PCjs Machines

Home of the original IBM PC emulator for browsers.

Logo

MS Windows Sample Code

The following document is from the Microsoft Programmer’s Library 1.3 CD-ROM.

Microsoft Windows S.D.K. v3.0 Sample `C' Source Code


BITMAP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\BITMAP\BITMAP.C

/****************************************************************************

    PROGRAM: Bitmap.c

    PURPOSE: Demonstrates how to use bitmap

    FUNCTIONS:

  WinMain() - calls initialization function, processes message loop
  InitApplication() - initializes window data and registers window
  InitInstance() - saves instance handle and creates main window
  MainWndProc() - processes messages
  About() - processes messages for "About" dialog box
        MakeColorBitmap(HWND) - creates a color bitmap

    COMMENTS:

        This application is linked with select.exe which is a library
        module.  For the source code, look in the \select\ directory, and
        in Appendix C of the Windows Programmer's Learning Guide.

****************************************************************************/

#include "windows.h"
#include "bitmap.h"
 "select.h"                /* used to link with select.exe */

HANDLE hInst;

/* Patterns used for the background */

short White[] =  { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
short Black[] =  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
short Zigzag[] = { 0xFF, 0xF7, 0xEB, 0xDD, 0xBE, 0x7F, 0xFF, 0xFF };
short CrossHatch[] = { 0xEF, 0xEF, 0xEF, 0xEF, 0x00, 0xEF, 0xEF, 0xEF };

/* handles used for the various bitmaps */

HBITMAP hPattern1;
HBITMAP hPattern2;
HBITMAP hPattern3;
HBITMAP hPattern4;
HBITMAP hBitmap1;
HBITMAP hBitmap2;
HBITMAP hBitmap3;
HBITMAP hMenuBitmap1;
HBITMAP hMenuBitmap2;
HBITMAP hMenuBitmap3;
HBITMAP hBitmap;
HBITMAP hOldBitmap;

HBRUSH hBrush;                         /* brush handle
int fStretchMode;                      /* type of stretch mode to use

HDC hDC;                               /* handle to device context
HDC hMemoryDC;                         /* handle to memory device context
BITMAP Bitmap;                         /* bitmap structure

BOOL bTrack = FALSE;                   /* TRUE if user is selecting a region
RECT Rect;

/* The following variables keep track of which menu item is checked */

WORD wPrevBitmap = IDM_BITMAP1;
WORD wPrevPattern = IDM_PATTERN1;
WORD wPrevMode = IDM_WHITEONBLACK;
WORD wPrevItem;

int Shape = SL_BLOCK;            /* shape to use for the selection rectangle

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
  if (!InitApplication(hInstance))
      return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = CS_VREDRAW | CS_HREDRAW;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "BitmapMenu";
    wc.lpszClassName = "BitmapWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    HWND            hwnd;

    hInst = hInstance;

    hwnd = CreateWindow(
        "BitmapWClass",
        "Bitmap Sample Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hwnd)
        return (FALSE);

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

  WM_COMMAND    - application menu (About dialog box)
        WM_CREATE      - create window and objects
        WM_LBUTTONDOWN - begin selection
        WM_MOUSEMOVE   - keep track of mouse movement during selection
        WM_LBUTTONUP   - end selection, draw bitmap
        WM_RBUTTONUP   - draw bitmap without resizing
        WM_ERASEBKGND  - erase background and redraw
        WM_DESTROY     - destroy window

    COMMENTS:

        User may select a "normal" size bitmap by pressing the right mouse
        button, or set the size of the bitmap to display by using the left
        button to define a region.  The routines to display the selection
        region are defined in the library module select.exe.
  WM_DESTROY    - destroy window

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout;

    HMENU hMenu;
    HBRUSH hOldBrush;
    HBITMAP hOurBitmap;

    switch (message) {
        case WM_CREATE:                            /* message: create window

            hPattern1 = CreateBitmap(8, 8, 1, 1, (LPSTR) White);
            hPattern2 = CreateBitmap(8, 8, 1, 1, (LPSTR) Black);
            hPattern3 = CreateBitmap(8, 8, 1, 1, (LPSTR) Zigzag);
            hPattern4 = CreateBitmap(8, 8, 1, 1, (LPSTR) CrossHatch);

            hBitmap1 = LoadBitmap(hInst, "dog");
            hBitmap2 = LoadBitmap(hInst, "cat");
            hBitmap3 = MakeColorBitmap(hWnd);

            hMenuBitmap1 = LoadBitmap(hInst, "dog");
            hMenuBitmap2 = LoadBitmap(hInst, "cat");
            hMenuBitmap3 = MakeColorBitmap(hWnd);

            hMenu = CreateMenu();
      AppendMenu(hMenu, MF_STRING | MF_CHECKED, IDM_PATTERN1, "&White");
      AppendMenu(hMenu, MF_STRING, IDM_PATTERN2, "&Black");
            AppendMenu(hMenu, MF_BITMAP, IDM_PATTERN3,
           (LPSTR)(LONG)hPattern3);
            AppendMenu(hMenu, MF_BITMAP, IDM_PATTERN4,
           (LPSTR)(LONG)hPattern4);

      ModifyMenu(GetMenu(hWnd), 1, MF_POPUP | MF_BYPOSITION,
           (WORD)hMenu, "&Pattern");

            hMenu = CreateMenu();

            /* Use bitmaps for menu items */
            AppendMenu(hMenu, MF_BITMAP | MF_CHECKED, IDM_BITMAP1,
           (LPSTR)(LONG) hMenuBitmap1);
            AppendMenu(hMenu, MF_BITMAP, IDM_BITMAP2,
           (LPSTR)(LONG) hMenuBitmap2);
            AppendMenu(hMenu, MF_BITMAP, IDM_BITMAP3,
           (LPSTR)(LONG) hMenuBitmap3);
            ModifyMenu(GetMenu(hWnd), 0, MF_POPUP | MF_BYPOSITION,
                       (WORD) hMenu, "&Bitmap");

            hBrush = CreatePatternBrush(hPattern1);
            fStretchMode = IDM_BLACKONWHITE;

            /* Select the first bitmap */

            hDC = GetDC(hWnd);
            hMemoryDC = CreateCompatibleDC(hDC);
            ReleaseDC(hWnd, hDC);
            hOldBitmap = SelectObject(hMemoryDC, hBitmap1);
            GetObject(hBitmap1, 16, (LPSTR) &Bitmap);

            break;

        case WM_LBUTTONDOWN:           /* message: left mouse button pressed

            /* Start selection of region */

            bTrack = TRUE;
            SetRectEmpty(&Rect);
            StartSelection(hWnd, MAKEPOINT(lParam), &Rect,
                (wParam & MK_SHIFT) ? (SL_EXTEND | Shape) : Shape);
            break;

        case WM_MOUSEMOVE:                        /* message: mouse movement

            /* Update the selection region */

            if (bTrack)
                UpdateSelection(hWnd, MAKEPOINT(lParam), &Rect, Shape);
            break;

        case WM_LBUTTONUP:            /* message: left mouse button released

            if (bTrack) {
               /* End the selection */

               EndSelection(MAKEPOINT(lParam), &Rect);
               ClearSelection(hWnd, &Rect, Shape);

               hDC = GetDC(hWnd);
               SetStretchBltMode(hDC, fStretchMode);
               StretchBlt(hDC, Rect.left, Rect.top,
                   Rect.right - Rect.left, Rect.bottom - Rect.top,
                  hMemoryDC, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight, SRCCOPY);
               ReleaseDC(hWnd, hDC);
            }

            bTrack = FALSE;
            break;

        case WM_RBUTTONUP:           /* message: right mouse button released

            /* Display a normal sized bitmap */

            hDC = GetDC(hWnd);
            BitBlt(hDC, LOWORD(lParam), HIWORD(lParam),
                Bitmap.bmWidth, Bitmap.bmHeight, hMemoryDC, 0, 0, SRCCOPY);
            ReleaseDC(hWnd, hDC);
            break;

        case WM_ERASEBKGND:                    /* messsage: erase background

            /* Repaint the background */

            UnrealizeObject(hBrush);
            hOldBrush = SelectObject(wParam, hBrush);
            GetClientRect(hWnd, &Rect);
            PatBlt(wParam, Rect.left, Rect.top,
                Rect.right-Rect.left, Rect.bottom-Rect.top, PATCOPY);
            SelectObject(wParam, hOldBrush);
            return TRUE;

  case WM_COMMAND:
            switch (wParam) {
                case IDM_ABOUT:
        lpProcAbout = MakeProcInstance(About, hInst);
        DialogBox(hInst,
            "AboutBox",
            hWnd,
            lpProcAbout);
        FreeProcInstance(lpProcAbout);
        break;

                case IDM_BITMAP1:
                    wPrevItem = wPrevBitmap;
                    wPrevBitmap = wParam;
                    GetObject(hBitmap1, 16, (LPSTR) &Bitmap);
                    SelectObject(hMemoryDC, hBitmap1);
                    break;

                case IDM_BITMAP2:
                    wPrevItem = wPrevBitmap;
                    wPrevBitmap = wParam;
                    GetObject(hBitmap2, 16, (LPSTR) &Bitmap);
                    SelectObject(hMemoryDC, hBitmap2);
                    break;

                case IDM_BITMAP3:
                    wPrevItem = wPrevBitmap;
                    wPrevBitmap = wParam;
                    GetObject(hBitmap3, 16, (LPSTR) &Bitmap);
                    hOurBitmap = SelectObject(hMemoryDC, hBitmap3);
                    break;

                /* Pattern menu: select the background brush to use */

                case IDM_PATTERN1:
                    wPrevItem = wPrevPattern;
                    wPrevPattern = wParam;
                    DeleteObject(hBrush);
                    hBrush = CreatePatternBrush(hPattern1);
                    InvalidateRect(hWnd, (LPRECT) NULL, TRUE);
                    UpdateWindow(hWnd);
                    break;

                case IDM_PATTERN2:
                    wPrevItem = wPrevPattern;
                    wPrevPattern = wParam;
                    DeleteObject(hBrush);
                    hBrush = CreatePatternBrush(hPattern2);
                    InvalidateRect(hWnd, (LPRECT) NULL, TRUE);
                    UpdateWindow(hWnd);
                    break;

                case IDM_PATTERN3:
                    wPrevItem = wPrevPattern;
                    wPrevPattern = wParam;
                    DeleteObject(hBrush);
                    hBrush = CreatePatternBrush(hPattern3);
                    InvalidateRect(hWnd, (LPRECT) NULL, TRUE);
                    UpdateWindow(hWnd);
                    break;

                case IDM_PATTERN4:
                    wPrevItem = wPrevPattern;
                    wPrevPattern = wParam;
                    DeleteObject(hBrush);
                    hBrush = CreatePatternBrush(hPattern4);
                    InvalidateRect(hWnd, (LPRECT) NULL, TRUE);
                    UpdateWindow(hWnd);
                    break;

                /* Mode menu: select the stretch mode to use */

                case IDM_BLACKONWHITE:
                    wPrevItem = wPrevMode;
                    wPrevMode = wParam;
                    fStretchMode = BLACKONWHITE;
                    break;

                case IDM_WHITEONBLACK:
                    wPrevItem = wPrevMode;
                    wPrevMode = wParam;
                    fStretchMode = WHITEONBLACK;
                    break;

                case IDM_COLORONCOLOR:
                    wPrevItem = wPrevMode;
                    wPrevMode = wParam;
                    fStretchMode = COLORONCOLOR;
                    break;
            }

            /* Uncheck the old item, check the new item */

            CheckMenuItem(GetMenu(hWnd), wPrevItem, MF_UNCHECKED);
            CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
            break;


  case WM_DESTROY:
            SelectObject(hMemoryDC, hOldBitmap);
            DeleteDC(hMemoryDC);
            DeleteObject(hBrush);
            DeleteObject(hPattern1);
            DeleteObject(hPattern2);
            DeleteObject(hPattern3);
            DeleteObject(hPattern4);
            DeleteObject(hBitmap1);
            DeleteObject(hBitmap2);
            DeleteObject(hBitmap3);
            DeleteObject(hMenuBitmap1);
            DeleteObject(hMenuBitmap2);
            DeleteObject(hMenuBitmap3);

      PostQuitMessage(0);
      break;

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


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}



/****************************************************************************

    FUNCTION: MakeColorBitmap(HWND)

    PURPOSE: Creates a color bitmap

    COMMENTS:

        This creates a plaid color bitmap by using overlappying colors.

****************************************************************************/

HBITMAP MakeColorBitmap(hWnd)
HWND hWnd;
{
    HDC hDC;
    HDC hMemoryDC;
    HBITMAP hBitmap;
    HBITMAP hOldBitmap;
    HBRUSH hRedBrush;
    HBRUSH hGreenBrush;
    HBRUSH hBlueBrush;
    HBRUSH hOldBrush;

    hDC = GetDC(hWnd);
    hMemoryDC = CreateCompatibleDC(hDC);
    hBitmap = CreateCompatibleBitmap(hDC, 64, 32);
    hOldBitmap = SelectObject(hMemoryDC, hBitmap);
    hRedBrush = CreateSolidBrush(RGB(255,0,0));
    hGreenBrush = CreateSolidBrush(RGB(0,255,0));
    hBlueBrush = CreateSolidBrush(RGB(0,0,255));

    PatBlt(hMemoryDC, 0, 0, 64, 32, BLACKNESS);
    hOldBrush = SelectObject(hMemoryDC, hRedBrush);
    PatBlt(hMemoryDC, 0, 0, 24, 11, PATORDEST);
    PatBlt(hMemoryDC, 40, 10, 24, 12, PATORDEST);
    PatBlt(hMemoryDC, 20, 21, 24, 11, PATORDEST);
    SelectObject(hMemoryDC, hGreenBrush);
    PatBlt(hMemoryDC, 20, 0, 24, 11, PATORDEST);
    PatBlt(hMemoryDC, 0, 10, 24, 12, PATORDEST);
    PatBlt(hMemoryDC, 40, 21, 24, 11, PATORDEST);
    SelectObject(hMemoryDC, hBlueBrush);
    PatBlt(hMemoryDC, 40, 0, 24, 11, PATORDEST);
    PatBlt(hMemoryDC, 20, 10, 24, 12, PATORDEST);
    PatBlt(hMemoryDC, 0, 21, 24, 11, PATORDEST);

    SelectObject(hMemoryDC, hOldBrush);
    DeleteObject(hRedBrush);
    DeleteObject(hGreenBrush);
    DeleteObject(hBlueBrush);
    SelectObject(hMemoryDC, hOldBitmap);
    DeleteDC(hMemoryDC);
    ReleaseDC(hWnd, hDC);
    return (hBitmap);
}


CFONT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SHOWFONT\CFONT.C

/****************************************************************************
    MODULE: cfont.c

    FUNCTION: CFontDlg(HWND, unsigned, WORD, LONG);

    PURPOSE: Processes dialog box messages for creating a font

****************************************************************************/

#include "windows.h"
#include "showfont.h"

BOOL FAR PASCAL CFontDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned  message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      SetDlgItemInt(hDlg, ID_HEIGHT, CLogFont.lfHeight, TRUE);
      SetDlgItemInt(hDlg, ID_WIDTH, CLogFont.lfWidth, TRUE);
      SetDlgItemInt(hDlg, ID_ESCAPEMENT,
    CLogFont.lfEscapement, TRUE);
      SetDlgItemInt(hDlg, ID_ORIENTATION,
    CLogFont.lfOrientation, TRUE);
      SetDlgItemText(hDlg, ID_FACE, CLogFont.lfFaceName);
      CheckDlgButton(hDlg, ID_ITALIC, CLogFont.lfItalic);
      CheckDlgButton(hDlg, ID_UNDERLINE, CLogFont.lfUnderline);
      CheckDlgButton(hDlg, ID_STRIKEOUT, CLogFont.lfStrikeOut);

      SetDlgItemInt(hDlg, ID_WEIGHT, CLogFont.lfWeight, TRUE);
      switch (CLogFont.lfWeight) {
    case FW_LIGHT:
        CheckRadioButton(hDlg, ID_LIGHT, ID_BOLD, ID_LIGHT);
        break;

    case FW_NORMAL:
        CheckRadioButton(hDlg, ID_LIGHT, ID_BOLD, ID_NORMAL);
        break;

    case FW_BOLD:
        CheckRadioButton(hDlg, ID_LIGHT, ID_BOLD, ID_BOLD);
        break;
      }

      SetDlgItemInt(hDlg, ID_CHARSET, CLogFont.lfCharSet, TRUE);
      switch (CLogFont.lfCharSet) {
    case ANSI_CHARSET:
        CheckRadioButton(hDlg, ID_ANSI, ID_OEM, ID_ANSI);
        break;

    case OEM_CHARSET:
        CheckRadioButton(hDlg, ID_ANSI, ID_OEM, ID_OEM);
        break;
      }

      switch (CLogFont.lfOutPrecision) {
    case OUT_STRING_PRECIS:
        CheckRadioButton(hDlg, ID_OUT_STRING, ID_OUT_DEFAULT,
      ID_OUT_STRING);
        break;

    case OUT_CHARACTER_PRECIS:
        CheckRadioButton(hDlg, ID_OUT_STRING, ID_OUT_DEFAULT,
      ID_OUT_CHAR);
        break;

    case OUT_STROKE_PRECIS:
        CheckRadioButton(hDlg, ID_OUT_STRING, ID_OUT_DEFAULT,
      ID_OUT_STROKE);
        break;

    case OUT_DEFAULT_PRECIS:
        CheckRadioButton(hDlg, ID_OUT_STRING, ID_OUT_DEFAULT,
      ID_OUT_DEFAULT);
        break;
      }

      switch (CLogFont.lfClipPrecision) {
    case CLIP_CHARACTER_PRECIS:
        CheckRadioButton(hDlg, ID_CLIP_CHAR, ID_CLIP_DEFAULT,
      ID_CLIP_CHAR);
        break;

    case CLIP_STROKE_PRECIS:
        CheckRadioButton(hDlg, ID_CLIP_CHAR, ID_CLIP_DEFAULT,
      ID_CLIP_STROKE);
        break;

    case CLIP_DEFAULT_PRECIS:
        CheckRadioButton(hDlg, ID_CLIP_CHAR, ID_CLIP_DEFAULT,
      ID_CLIP_DEFAULT);
        break;
      }

      switch (CLogFont.lfQuality) {
    case PROOF_QUALITY:
        CheckRadioButton(hDlg, ID_PROOF, ID_DEF_QUALITY, ID_PROOF);
        break;

    case DRAFT_QUALITY:
        CheckRadioButton(hDlg, ID_PROOF, ID_DEF_QUALITY, ID_DRAFT);
        break;

    case DEFAULT_QUALITY:
        CheckRadioButton(hDlg, ID_PROOF, ID_DEF_QUALITY,
      ID_DEF_QUALITY);
        break;
      }

      switch ((CLogFont.lfPitchAndFamily) & 3) {
    case FIXED_PITCH:
        CheckRadioButton(hDlg, ID_FIXED, ID_DEF_PITCH, ID_FIXED);
        break;

    case VARIABLE_PITCH:
        CheckRadioButton(hDlg, ID_FIXED, ID_DEF_PITCH, ID_VARIABLE);
        break;

    case DEFAULT_PITCH:
        CheckRadioButton(hDlg, ID_FIXED, ID_DEF_PITCH,
      ID_DEF_PITCH);
        break;
      }

      switch ((CLogFont.lfPitchAndFamily) & 240) {
    case FF_ROMAN:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY, ID_ROMAN);
        break;

    case FF_SWISS:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY, ID_SWISS);
        break;

    case FF_MODERN:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY, ID_MODERN);
        break;

    case FF_SCRIPT:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY, ID_SCRIPT);
        break;

    case FF_DECORATIVE:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY, ID_DECO);
        break;

    case FF_DONTCARE:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY,
      ID_DEF_FAMILY);
        break;
      }
      break;

  case WM_COMMAND:
      switch (wParam) {
    case IDOK:
        CLogFont.lfHeight = GetDlgItemInt(hDlg,
      ID_HEIGHT, NULL, TRUE);
        CLogFont.lfWidth = GetDlgItemInt(hDlg,
      ID_WIDTH, NULL, TRUE);
        CLogFont.lfEscapement = GetDlgItemInt(hDlg,
      ID_ESCAPEMENT, NULL, FALSE);
        CLogFont.lfOrientation = GetDlgItemInt(hDlg,
      ID_ORIENTATION, NULL, FALSE);
        GetDlgItemText(hDlg, ID_FACE, CLogFont.lfFaceName, 32);
        CLogFont.lfWeight = GetDlgItemInt(hDlg,
      ID_WEIGHT, NULL, FALSE);
        CLogFont.lfCharSet = GetDlgItemInt(hDlg,
      ID_CHARSET, NULL, FALSE);
        EndDialog(hDlg, 1);
        break;

    case IDCANCEL:
        EndDialog(hDlg, 0);
        break;

    case ID_ITALIC:
        CLogFont.lfItalic = IsDlgButtonChecked(hDlg, ID_ITALIC);
        break;

    case ID_UNDERLINE:
        CLogFont.lfUnderline = IsDlgButtonChecked(hDlg,
      ID_UNDERLINE);
        break;

    case ID_STRIKEOUT:
        CLogFont.lfStrikeOut = IsDlgButtonChecked(hDlg,
      ID_STRIKEOUT);
        break;

    case ID_LIGHT:
        SetDlgItemInt(hDlg, ID_WEIGHT, CLogFont.lfWeight, TRUE);
        CheckRadioButton(hDlg, ID_LIGHT, ID_BOLD, ID_LIGHT);
        CLogFont.lfWeight = FW_LIGHT;
        break;

    case ID_NORMAL:
        SetDlgItemInt(hDlg, ID_WEIGHT, CLogFont.lfWeight, TRUE);
        CheckRadioButton(hDlg, ID_LIGHT, ID_BOLD, ID_NORMAL);
        CLogFont.lfWeight = FW_NORMAL;
        break;

    case ID_BOLD:
        SetDlgItemInt(hDlg, ID_WEIGHT, CLogFont.lfWeight, TRUE);
        CheckRadioButton(hDlg, ID_LIGHT, ID_BOLD, ID_BOLD);
        CLogFont.lfWeight = FW_BOLD;
        break;

    case ID_WEIGHT:
        CheckDlgButton(hDlg, ID_LIGHT, FALSE);
        CheckDlgButton(hDlg, ID_NORMAL, FALSE);
        CheckDlgButton(hDlg, ID_BOLD, FALSE);
        break;

    case ID_ANSI:
        SetDlgItemInt(hDlg, ID_CHARSET, CLogFont.lfCharSet, TRUE);
        CheckRadioButton(hDlg, ID_ANSI, ID_OEM, ID_ANSI);
        break;

    case ID_OEM:
        SetDlgItemInt(hDlg, ID_CHARSET, CLogFont.lfCharSet, TRUE);
        CheckRadioButton(hDlg, ID_ANSI, ID_OEM, ID_OEM);
        break;

    case ID_CHARSET:
        CheckDlgButton(hDlg, ID_ANSI, FALSE);
        CheckDlgButton(hDlg, ID_OEM, FALSE);
        break;

    case ID_OUT_STRING:
        CheckRadioButton(hDlg, ID_OUT_STRING, ID_OUT_DEFAULT,
      ID_OUT_STRING);
        CLogFont.lfOutPrecision = OUT_STRING_PRECIS;
        break;

    case ID_OUT_CHAR:
        CheckRadioButton(hDlg, ID_OUT_STRING, ID_OUT_DEFAULT,
      ID_OUT_CHAR);
        CLogFont.lfOutPrecision = OUT_CHARACTER_PRECIS;
        break;

    case ID_OUT_STROKE:
        CheckRadioButton(hDlg, ID_OUT_STRING, ID_OUT_DEFAULT,
      ID_OUT_STROKE);
        CLogFont.lfOutPrecision = OUT_STROKE_PRECIS;
        break;

    case ID_OUT_DEFAULT:
        CheckRadioButton(hDlg, ID_OUT_STRING, ID_OUT_DEFAULT,
      ID_OUT_DEFAULT);
        CLogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
        break;

    case ID_CLIP_CHAR:
        CheckRadioButton(hDlg, ID_CLIP_CHAR, ID_CLIP_DEFAULT,
      ID_CLIP_CHAR);
        CLogFont.lfClipPrecision = CLIP_CHARACTER_PRECIS;
        break;

    case ID_CLIP_STROKE:
        CheckRadioButton(hDlg, ID_CLIP_CHAR, ID_CLIP_DEFAULT,
      ID_CLIP_STROKE);
        CLogFont.lfClipPrecision = CLIP_STROKE_PRECIS;
        break;

    case ID_CLIP_DEFAULT:
        CheckRadioButton(hDlg, ID_CLIP_CHAR, ID_CLIP_DEFAULT,
      ID_CLIP_DEFAULT);
        CLogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
        break;

    case ID_PROOF:
        CheckRadioButton(hDlg, ID_PROOF, ID_DEF_QUALITY, ID_PROOF);
        CLogFont.lfQuality = PROOF_QUALITY;
        break;

    case ID_DRAFT:
        CheckRadioButton(hDlg, ID_PROOF, ID_DEF_QUALITY, ID_DRAFT);
        CLogFont.lfQuality = DRAFT_QUALITY;
        break;

    case ID_DEF_QUALITY:
        CheckRadioButton(hDlg, ID_PROOF, ID_DEF_QUALITY,
      ID_DEF_QUALITY);
        CLogFont.lfQuality = DEFAULT_QUALITY;
        break;

    case ID_FIXED:
        CheckRadioButton(hDlg, ID_FIXED, ID_DEF_PITCH, ID_FIXED);
        CLogFont.lfPitchAndFamily =
      (~3 & CLogFont.lfPitchAndFamily) | FIXED_PITCH;
        break;

    case ID_VARIABLE:
        CheckRadioButton(hDlg, ID_FIXED, ID_DEF_PITCH, ID_VARIABLE);
        CLogFont.lfPitchAndFamily =
      (~3 & CLogFont.lfPitchAndFamily) | VARIABLE_PITCH;
        break;

    case ID_DEF_PITCH:
        CheckRadioButton(hDlg, ID_FIXED, ID_DEF_PITCH,
      ID_DEF_PITCH);
        CLogFont.lfPitchAndFamily =
      (~3 & CLogFont.lfPitchAndFamily) | DEFAULT_PITCH;
        break;

    case ID_ROMAN:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY, ID_ROMAN);
        CLogFont.lfPitchAndFamily =
      (~240 & CLogFont.lfPitchAndFamily) | FF_ROMAN;
        break;

    case ID_SWISS:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY, ID_SWISS);
        CLogFont.lfPitchAndFamily =
      (~240 & CLogFont.lfPitchAndFamily) | FF_SWISS;
        break;

    case ID_MODERN:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY, ID_MODERN);
        CLogFont.lfPitchAndFamily =
      (~240 & CLogFont.lfPitchAndFamily) | FF_MODERN;
        break;

    case ID_SCRIPT:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY, ID_SCRIPT);
        CLogFont.lfPitchAndFamily =
      (~240 & CLogFont.lfPitchAndFamily) | FF_SCRIPT;
        break;

    case ID_DECO:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY, ID_DECO);
        CLogFont.lfPitchAndFamily =
      (~240 & CLogFont.lfPitchAndFamily) | FF_DECORATIVE;
        break;

    case ID_DEF_FAMILY:
        CheckRadioButton(hDlg, ID_ROMAN, ID_DEF_FAMILY,
      ID_DEF_FAMILY);
        CLogFont.lfPitchAndFamily =
      (~240 & CLogFont.lfPitchAndFamily) | FF_DONTCARE;
        break;

      }
      break;
       }
       return (FALSE);
}


CLIDATA.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\DDE\CLIDATA.C

/****************************************************************************

    MODULE: CLIDATA.C

    PURPOSE: Maintains conversation data and paints data in the client
       application window.

****************************************************************************/

#include "windows.h"
#include "clires.h"
#include "client.h"
#include <string.h>
#include <stdlib.h>

typedef struct ITEM
{
    char szItem[ITEM_MAX_SIZE+1];
    char szValue[VALUE_MAX_SIZE+1];
};

typedef struct CONV
{
    BOOL  bInTerminate;
    enum PENDINGACK ePendingAck;
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
    char  szApplication[APP_MAX_SIZE+1];
    char  szTopic[TOPIC_MAX_SIZE+1];
    int   nItemCount;
    struct ITEM Item[ITEMS_PER_CONV_MAX_COUNT];
};

static struct CONV Conv[CONV_MAX_COUNT];
static int   nConvCount = 0;
static HWND  hwndNewClientDDE; /* used by SelectNewConvDlgProc */
static HWND  hwndNewServerDDE; /* new conversation selected by user */

static char  szSelectedApplication[APP_MAX_SIZE+1];
static char  szSelectedTopic[TOPIC_MAX_SIZE+1];
static char  szSelectedItem[ITEM_MAX_SIZE+1];
static char  szSelectedValue[VALUE_MAX_SIZE+1];

static struct CONV * NEAR FindConv(HWND);
static struct ITEM * NEAR FindItem(HWND, char *);

BOOL FAR PASCAL SelectNewConvDlgProc(HWND, unsigned, WORD, LONG);

/*****************************************************************

    FUNCTION: AddItemToConv

    PURPOSE:  Add a data item to an existing conversation.

*****************************************************************/
BOOL AddItemToConv(hwndClientDDE, szItem)
    HWND   hwndClientDDE;
    char * szItem;
{
    struct CONV * pConv;
    struct ITEM * pItem;

    if (!(pConv = FindConv(hwndClientDDE)))
        return (FALSE);
    if (pConv->nItemCount >= ITEMS_PER_CONV_MAX_COUNT)
        return (FALSE);
   pItem =  pConv->Item + pConv->nItemCount++;
   strcpy(pItem->szItem, szItem);
   pItem->szValue[0] = 0;
   return (TRUE);
}




/**********************************************************

    FUNCTION:  AtLeastOneConvActive

    PURPOSE:   Used during termination of application, to
         determine whether pending DDE terminations
         have completed.

***********************************************************/
BOOL AtLeastOneConvActive()
{
    return (nConvCount? TRUE: FALSE);
}



/*****************************************************************

    FUNCTION: AddConv

    PURPOSE:  Initialize items in CONV structure.

*****************************************************************/
BOOL AddConv(hwndClientDDE, hwndServerDDE, szApplication, szTopic)
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
    char * szApplication;
    char * szTopic;
{
    struct CONV * pConv;

    if (nConvCount >= CONV_MAX_COUNT)
        return (FALSE);
    pConv = Conv + nConvCount++;
    pConv->bInTerminate = FALSE;
    pConv->ePendingAck = NONE;
    pConv->hwndClientDDE = hwndClientDDE;
    pConv->hwndServerDDE = hwndServerDDE;
    strcpy(pConv->szApplication, szApplication);
    strcpy(pConv->szTopic, szTopic);
    pConv->nItemCount = 0;
    return (TRUE);
}



/*****************************************************************

    FUNCTION: DoesAdviseAlreadyExist

    PURPOSE:  Determines whether hot/warm link has already been
        established for specified conversation item.

*****************************************************************/
BOOL DoesAdviseAlreadyExist(hwndClientDDE, szItem)
    HWND hwndClientDDE;
    char * szItem;
{
    return (FindItem(hwndClientDDE,szItem)==NULL?FALSE:TRUE);
}



/*****************************************************************

    FUNCTION: FindItem

    PURPOSE:  Return pointer to item structure given conversation and item.

*****************************************************************/
struct ITEM * NEAR FindItem(hwndClientDDE, szItem)
    HWND hwndClientDDE;
    char * szItem;
{
    struct CONV * pConv;
    struct ITEM * pItem;
    int           nItemIndex;

    if (!(pConv = FindConv(hwndClientDDE)))
        return (NULL);
    for (pItem = pConv->Item, nItemIndex = 0;
   nItemIndex < pConv->nItemCount;
         pItem++, nItemIndex++)
    {
        if (!strcmpi(szItem, pItem->szItem))
        {
            return (pItem);
        }
    }
    return (NULL);
}


/*****************************************************************

    FUNCTION: FindConv

    PURPOSE:  Return pointer to conversation structure given handle
        to client DDE window.

*****************************************************************/
struct CONV * NEAR FindConv(hwndClientDDE)
    HWND  hwndClientDDE;
{
    struct CONV * pConv;
    int     nConvIndex;

    for (pConv = Conv, nConvIndex = 0;
   nConvIndex < nConvCount;
   pConv++, nConvIndex++)
    {
  if (pConv->hwndClientDDE == hwndClientDDE)
      return (pConv);
    }
    return (NULL);
}


/***************************************************************

    FUNCTION:  FindConvGivenAppTopic

    PURPOSE:   Find handle of client DDE window given
         application and topic for an active conversation.

***************************************************************/
HWND FindConvGivenAppTopic(szApp, szTopic)
    char * szApp;
    char * szTopic;
{
    struct CONV * pConv;
    int     nConvIndex;

    for (pConv = Conv, nConvIndex = 0;
   nConvIndex < nConvCount;
   pConv++, nConvIndex++)
    {
   if (!(stricmp(pConv->szApplication, szApp))
       && !(stricmp(pConv->szTopic, szTopic)))
   {
       return pConv->hwndClientDDE;
   }
    }
    return NULL;
}


/*****************************************************************

    FUNCTION: GetAppAndTopic

    PURPOSE:  Get conversation's application and topic strings.

*****************************************************************/
void GetAppAndTopic(hwndClientDDE, szApp, szTopic)
    HWND  hwndClientDDE;
    char * szApp;
    char * szTopic;
{
    struct CONV * pConv;

    if (!(pConv = FindConv(hwndClientDDE)))
        return;
    strcpy(szApp, pConv->szApplication);
    strcpy(szTopic, pConv->szTopic);
    return;
}



/****************************************************************

    FUNCTION: GetConvPendingAck

    PURPOSE:  Return state of acknowledgement for specified
        conversation.

****************************************************************/
enum PENDINGACK GetConvPendingAck(hwndClientDDE)
    HWND hwndClientDDE;
{
    struct CONV * pConv;

    if (pConv = FindConv(hwndClientDDE))
  return pConv->ePendingAck;
    else
        return NONE;
}



/*****************************************************************

    FUNCTION: GetHwndServerDDE

    PURPOSE:  Gets the hwnd of the server, given the handle of
        the client DDE window.

*****************************************************************/
HWND GetHwndServerDDE(hwndClientDDE)
    HWND  hwndClientDDE;
{
    struct CONV * pConv;
    int  nConvIndex;

    for (pConv = Conv, nConvIndex = 0;
   nConvIndex < nConvCount;
   pConv++, nConvIndex++)
    {
  if (pConv->hwndClientDDE == hwndClientDDE)
      return (pConv->hwndServerDDE);
    }
    return (NULL);
}



/*****************************************************************

    FUNCTION: GetNextConv

    PURPOSE:  Get next conversation in the list of current conversations.
        To get the first conversation, pass a NULL hwnd.

*****************************************************************/
HWND GetNextConv(hwndClientDDE)
    HWND hwndClientDDE;
{
    struct CONV * pConv;
    int     nConvIndex;

    if (hwndClientDDE)
    {
  for (nConvIndex = 0, pConv = Conv;
       nConvIndex < nConvCount;
       nConvIndex++, pConv++)
        {
      if (pConv->hwndClientDDE == hwndClientDDE)
            {
    if (++nConvIndex < nConvCount)
        return (++pConv)->hwndClientDDE;
                else
                    return (NULL);
            }
        }
        return (NULL);
    }
    if (nConvCount > 0)
  return (Conv[0].hwndClientDDE);
    else
        return (NULL);
}



/****************************************************************

    FUNCTION: HexToInt

    PURPOSE:  Convert from ascii to integer up to 4 chars
        representing a hexidecimal number.  The hex number
        is considered terminated by a null or any non-hex
        digit.

****************************************************************/
int HexToInt(szHex)
    char * szHex;
{
    unsigned int  nReturn;
    int     nDigit;
    int     nIndex;

    nReturn = 0;
    for (nIndex = 0; nIndex < 4; nIndex++)
    {
  if (*szHex >= '0' && *szHex <= '9')
      nDigit = *szHex - '0';
  else if (*szHex >= 'A' && *szHex <= 'F')
      nDigit = *szHex - 'A' + 10;
  else if (*szHex >= 'a' && *szHex <= 'f')
      nDigit = *szHex - 'a' + 10;
  else
      return ((int)nReturn);
  nReturn = (nReturn<<4) + nDigit;
  szHex++;
    }
    return ((int)nReturn);
}




/****************************************************************

    FUNCTION: IsConvInTerminateState

    PURPOSE:  Determine whether conversation is in process of
        being terminated.   In identifying the conversation,
        it is necessary to compare both the hwndClientDDE
        and hwndServerDDE, because during an initiate,
        there may be multiple unwanted conversations sharing
        the same hwndClientDDE.

****************************************************************/
BOOL IsConvInTerminateState(hwndClientDDE, hwndServerDDE)
    HWND hwndClientDDE;
    HWND hwndServerDDE;
{
    struct CONV * pConv;
    int  nConvIndex;

    for (nConvIndex = 0, pConv = Conv;
   nConvIndex < nConvCount;
   nConvIndex++, pConv++)
    {
  if (pConv->hwndClientDDE == hwndClientDDE
      && pConv->hwndServerDDE == hwndServerDDE)
      return pConv->bInTerminate;
    }
    return (TRUE);  /* If conversation not found, assume terminate state */
        /* to avoid possible endless terminate feedback loop */
}



/****************************************************************

    FUNCTION: IsHwndClientDDEUsed

    PURPOSE:  Determine whether hwndClientDDE is still being
        used in some second conversation after the
        first conversation has been terminated.  This
        determination is necessary during an initiate
        in which the same hwndClientDDE is used in
        multiple WM_DDE_INITIATE messages.
        being terminated.

****************************************************************/
BOOL IsHwndClientDDEUsed(hwndClientDDE)
    HWND  hwndClientDDE;
{
    struct CONV * pConv;
    int  nConvIndex;

    for (pConv = Conv, nConvIndex = 0;
   nConvIndex < nConvCount;
   pConv++, nConvIndex++)
    {
  if (pConv->hwndClientDDE == hwndClientDDE)
      return (TRUE);
    }
    return (FALSE);
}



/****************************************************************

    FUNCTION: LetUserPickConversation

    PURPOSE:  The client has initiated possibly multiple
        conversations (if a wild card application or topic
        was specified in the WM_DDE_INITIATE).  This function
        determines whether multiple servers established
        conversations with the specified hwndClientDDE.
        If so, this function asks the user to pick one of
        the conversations, and terminates the other
        conversations.

****************************************************************/
BOOL LetUserPickConversation(hwndClientDDE)
    HWND  hwndClientDDE;
{
    struct CONV * pConv;
    FARPROC  lpfnDlgProc;
    int  nCountSameWnd;
    int  nConvIndex;

    nCountSameWnd = 0;
    for (pConv = Conv, nConvIndex = 0;
   nConvIndex < nConvCount;
   pConv++, nConvIndex++)
    {
  if (pConv->hwndClientDDE == hwndClientDDE)
      nCountSameWnd++;
    }
    if (nCountSameWnd == 1)
  return (TRUE);
    if (nCountSameWnd == 0)
  return (FALSE);
    hwndNewServerDDE = NULL;
    hwndNewClientDDE = hwndClientDDE; /* make known to SelectNewConvDlgProc *
    /* Dialog proc SelectNewConvDlgProc is defined in this module */
    lpfnDlgProc = MakeProcInstance(SelectNewConvDlgProc, hInst);
    DialogBox(hInst,
        "SelectNewConversation",
        hwndMain,
        lpfnDlgProc);
    FreeProcInstance(lpfnDlgProc);

    /* Terminate unwanted conversations.  The only conversation  */
    /* wanted is the one (hwndNewServerDDE) selected by the user */
    /* in the SelectNewConv dialog box.        */

    for (pConv = Conv, nConvIndex = 0;
   nConvIndex < nConvCount;
   pConv++, nConvIndex++)
    {
  if (pConv->hwndClientDDE == hwndClientDDE
      && pConv->hwndServerDDE != hwndNewServerDDE)
  {
      SendTerminate(hwndClientDDE, pConv->hwndServerDDE);
  }
    }
    return (TRUE);

}


/****************************************************************

    FUNCTION: PaintConvData

    PURPOSE:  Paint the client application window, using all
        conversation/item information.

****************************************************************/
void PaintConvData(hwnd)
    HWND  hwnd;
{
    HDC  hDC;
    PAINTSTRUCT ps;
    int  x,y;
    int  nConvIndex, nItemIndex;
    struct CONV * pConv;
    struct ITEM * pItem;
    char          szNumber[10];

    BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
    hDC = ps.hdc;

    y = yDelta/2;  /* start 1/2 line down window */

    for (pConv = Conv, nConvIndex = 0;
   nConvIndex < nConvCount;
   pConv++, nConvIndex++)
    {
  x = xDelta/2;  /* start 1/2 char across window */
        TextOut(hDC, x, y,
      (LPSTR)pConv->szApplication,
      strlen(pConv->szApplication));
        x += ((3+APP_MAX_SIZE)*xDelta);
        TextOut(hDC, x, y,
      (LPSTR)pConv->szTopic,
      strlen(pConv->szTopic));
        x += ((3+TOPIC_MAX_SIZE) *xDelta);
  itoa(pConv->hwndClientDDE, szNumber, 16);
  strupr(szNumber);
        TextOut(hDC, x, y, (LPSTR)szNumber, strlen(szNumber));
        y += yDelta;

  for (pItem = pConv->Item, nItemIndex = 0;
       nItemIndex < pConv->nItemCount;
             pItem++, nItemIndex++)
        {
            x = 4 * xDelta;   /* Indent items 4 spaces */
            TextOut(hDC, x, y,
                (LPSTR)pItem->szItem,
                strlen(pItem->szItem));
            x += ((3+ITEM_MAX_SIZE)*xDelta);
            TextOut(hDC, x, y,
                (LPSTR)pItem->szValue,
                strlen(pItem->szValue));
            y += yDelta;
        }

    }

    ValidateRect(hwnd, (LPRECT)NULL);
    EndPaint(hwnd, (LPPAINTSTRUCT)&ps);

    return;
}



/*****************************************************************

    FUNCTION: RemoveItemFromConv

    PURPOSE:  Remove an item (advise) from an existing conversation.

*****************************************************************/
BOOL RemoveItemFromConv(hwndClientDDE, szItem)
    HWND   hwndClientDDE;
    char * szItem;
{
    struct CONV * pConv;
    int           nItemIndex;
    struct ITEM * pItem;

    if (!(pConv = FindConv(hwndClientDDE)))
        return (FALSE);
    pItem = pConv->Item;
    nItemIndex = 0;
    while (nItemIndex < pConv->nItemCount)
    {
        if (!(strcmpi(pItem->szItem, szItem)))
            break;
        pItem++;
        nItemIndex++;
    }
    pConv->nItemCount--;
    while (nItemIndex < pConv->nItemCount)
    {
        *pItem = *(pItem+1);
        pItem++;
        nItemIndex++;
    }
    return (TRUE);
}



/*****************************************************************

    FUNCTION: RemoveConv

    PURPOSE:  Remove active conversation.   It is necessary to
        specify both the client and server DDE windows,
        since during an initiate, only the server DDE
        window handles are distinguishable.

*****************************************************************/
BOOL RemoveConv(hwndClientDDE, hwndServerDDE)
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
{
    struct CONV * pRemoveConv;
    struct CONV * pConv;
    int     nConvIndex;

    for (pRemoveConv = Conv, nConvIndex = 0;
   nConvIndex < nConvCount;
   pRemoveConv++, nConvIndex++)
    {
  if (pRemoveConv->hwndClientDDE == hwndClientDDE
      && pRemoveConv->hwndServerDDE == hwndServerDDE)
      break;
    }
    if (nConvIndex >= nConvCount)
        return (FALSE);
    nConvIndex = 0;
    pConv = Conv;
    while (pConv != pRemoveConv)
    {
  if (++nConvIndex >= nConvCount)
            return (FALSE);
  pConv++;
    }
    while (++nConvIndex < nConvCount)
    {
  *pConv = *(pConv+1);
  pConv++;
    }
    nConvCount--;
    return (TRUE);
}




/****************************************************************

    FUNCTION: SelectNewConvDlgProc

    PURPOSE:  Ask the user to select one of multiple conversations
        that were established during a wild card initiate.

****************************************************************/
BOOL FAR PASCAL SelectNewConvDlgProc(hdlg, message, wParam, lParam)
    HWND      hdlg;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    HWND hctlConvBox;
    struct CONV * pConv;
    int  nConvIndex;
    char szConvInfo[CONVINFO_MAX_SIZE];
    char * pcBlank;
    int    nIndex;

    switch (message)
    {
  case WM_INITDIALOG:
      hctlConvBox = GetDlgItem(hdlg, IDC_CONVBOX);
      SendMessage(hctlConvBox, LB_RESETCONTENT, 0, 0L);
      for (pConv = Conv, nConvIndex = 0;
     nConvIndex < nConvCount;
     pConv++, nConvIndex++)
      {
    /* If this is one of the newly initiated conversations */
    /* then add it to the list box.            */
    if (pConv->hwndClientDDE == hwndNewClientDDE)
    {
        /* Display server's DDE window in the list box, */
        /* as that is the only way to distinguish      */
        /* conversations at this point.        */
        itoa((int)pConv->hwndServerDDE, szConvInfo, 16);
        strupr(szConvInfo);
        strcat(szConvInfo, " ");
        strcat(szConvInfo, pConv->szApplication);
        strcat(szConvInfo, " | ");
        strcat(szConvInfo, pConv->szTopic);

        SendMessage(hctlConvBox,
      LB_ADDSTRING,
      0,
      (LONG)(LPSTR)szConvInfo);
    }
      }
      return (TRUE);

  case WM_COMMAND:
      switch (wParam)
      {
    case IDC_CANCEL:
        /* Function LetUserPickConveresation will terminate */
        /* all newly initiated conversations.    */
        hwndNewServerDDE = NULL;
        EndDialog(hdlg, FALSE);
        return (TRUE);

    case IDC_OK:
        /* Function LetUserPickConversation will terminate */
        /* all newly initiated conversations, except the   */
        /* one selected by the user: hwndNewServerDDE.     */
        hwndNewServerDDE = NULL;
        hctlConvBox = GetDlgItem(hdlg, IDC_CONVBOX);
        if ((nIndex = SendMessage(hctlConvBox,
                LB_GETCURSEL, 0, 0L))
      != LB_ERR)
        {
      szConvInfo[0] = 0;
      SendMessage(hctlConvBox,
          LB_GETTEXT,
          nIndex,
          (LONG)(LPSTR)szConvInfo);
      if (pcBlank = strchr(szConvInfo, ' '))
      {
          *pcBlank = 0; /* terminate hwnd numeric value */
          hwndNewServerDDE = HexToInt(szConvInfo);
      }
        }
        EndDialog(hdlg, TRUE);
        return (TRUE);

    default:
        return (FALSE);
      }
    }
    return (FALSE);
}



/****************************************************************

    FUNCTION: SetConvInTerminateState

    PURPOSE:  Set conversation terminate state to TRUE.

****************************************************************/
void SetConvInTerminateState(hwndClientDDE, hwndServerDDE)
    HWND hwndClientDDE;
    HWND hwndServerDDE;
{
    struct CONV * pConv;
    int  nConvIndex;

    for (nConvIndex = 0, pConv = Conv;
   nConvIndex < nConvCount;
   nConvIndex++, pConv++)
    {
  if (pConv->hwndClientDDE == hwndClientDDE
      && pConv->hwndServerDDE == hwndServerDDE)
  {
      pConv->bInTerminate = TRUE;
      return;
  }
    }
    return;
}



/****************************************************************

    FUNCTION: SetConvItemValue

    PURPOSE:  Find server data item and set value.

****************************************************************/
BOOL SetConvItemValue(hwndClientDDE, szItem, lpszValue)
    HWND hwndClientDDE;
    char * szItem;
    LPSTR  lpszValue;
{
   struct ITEM * pItem;
   char        * pcValue;

    if (pItem = FindItem(hwndClientDDE, szItem))
    {
        pcValue = pItem->szValue;
        /* copy until <CR> in CF_TEXT data */
        while (*lpszValue != '\r' && *lpszValue)
        {
            *pcValue++ = *lpszValue++;
        }
        *pcValue++ = 0;
  /* Repaint client application window */
  InvalidateRect(hwndMain, NULL, TRUE);
        return (TRUE);
    }
    return (FALSE);
}



/****************************************************************

    FUNCTION: SetConvPendingAck

    PURPOSE:  Set the state of acknowledgement for a specified
        conversation.

****************************************************************/
void SetConvPendingAck(hwndClientDDE, ePendingAck)
    HWND hwndClientDDE;
    enum PENDINGACK ePendingAck;
{
    struct CONV * pConv;

    if (pConv = FindConv(hwndClientDDE))
    {
  pConv->ePendingAck = ePendingAck;
    }
    return;
}


CLIDDE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\DDE\CLIDDE.C

/****************************************************************************

    MODULE: CLIDDE.C

    PURPOSE: Processes incoming and outgoing DDE messages


****************************************************************************/

#include "windows.h"

#include "dde.h"
#include "clires.h"
#include "client.h"
#include <string.h>

#define DEFAULT_ACK_TIME_OUT_MILLISEC 10000
static int nAckTimeOut;

static BOOL   bInInitiate = FALSE;

BOOL NEAR AwaitingAck(HWND);


/****************************************************************************

    FUNCTION: AwaitingAck

    PURPOSE:  Inform user if acknowledgement is required before further
              action.

****************************************************************************/
BOOL NEAR AwaitingAck(hwndClientDDE)
    HWND hwndClientDDE;
{
    if (GetConvPendingAck(hwndClientDDE) == NONE)
    {
        return (FALSE);
    }
    MessageBox(hwndMain,
        "Previous DDE operation must be acknowledged first",
        "Client",
        MB_ICONEXCLAMATION | MB_OK);
    return (TRUE);
}



/****************************************************************************

    FUNCTION: ClientAcknowledge

    PURPOSE:  Called when client application receives WM_DDE_ACK message
        or WM_TIMER message (time out on wait for ACK).

****************************************************************************/
void ClientAcknowledge(hwndClientDDE, hwndServerDDE, lParam, bTimeOut)
    HWND hwndClientDDE;
    HWND hwndServerDDE;
    LONG lParam;    /* lParam of WM_DDE_ACK message */
    BOOL bTimeOut;  /* TRUE if NACK is due to time-out */
{
    enum PENDINGACK ePendingAck;
    char szApplication[APP_MAX_SIZE+1];
    char szTopic[TOPIC_MAX_SIZE+1];
    char szItem[ITEM_MAX_SIZE+1];
    char message[80];

    ePendingAck = GetConvPendingAck(hwndClientDDE);
    SetConvPendingAck(hwndClientDDE, NONE);
    KillTimer(hwndClientDDE, hwndServerDDE);

    if (bInInitiate)
    {
        GlobalGetAtomName(LOWORD(lParam),
            szApplication,
            APP_MAX_SIZE);
        GlobalGetAtomName(HIWORD(lParam),
            szTopic,
            TOPIC_MAX_SIZE);
  if (!AddConv(hwndClientDDE, hwndServerDDE, szApplication, szTopic))
        {
      MessageBox(hwndMain,
    "Maximum conversation count exceeded",
                "Client",
                MB_ICONEXCLAMATION | MB_OK);
        }
  /*
  GlobalDeleteAtom(LOWORD(lParam));
        GlobalDeleteAtom(HIWORD(lParam));
  */
        return;
    }
    if ((ePendingAck == ADVISE) && (LOWORD(lParam) & 0x8000))
    {  /* received positive ACK in response to ADVISE */
        GlobalGetAtomName(HIWORD(lParam), szItem, ITEM_MAX_SIZE);
  AddItemToConv(hwndClientDDE, szItem);

  /* Conversation item is established: now get current value */
  /* and update screen            */
  SendRequest(hwndClientDDE, hwndServerDDE, szItem);
  InvalidateRect(hwndMain, NULL, TRUE);
    }
    if ((ePendingAck == UNADVISE) && (LOWORD(lParam) & 0x8000))
    {  /* received positive ACK in response to UNADVISE */
        GlobalGetAtomName(HIWORD(lParam), szItem, ITEM_MAX_SIZE);
  RemoveItemFromConv(hwndClientDDE, szItem);
  InvalidateRect(hwndMain, NULL, TRUE);
    }
    if (!(LOWORD(lParam) & 0x8000))    /* NACK */
    {
        strcpy(message, "DDE ");
        strcat(message, ePendingAck == ADVISE?    "ADVISE "
                      : ePendingAck == UNADVISE?  "UNADVISE "
                      : ePendingAck == POKE?      "POKE "
                      : ePendingAck == REQUEST?   "REQUEST "
          : ePendingAck == EXECUTE?   "EXECUTE "
                      : " ");
        strcat(message, bTimeOut? "acknowledge time out"
                                : "operation failed");
  MessageBox(hwndMain,
            message,
            "Client",
            MB_ICONEXCLAMATION | MB_OK);
    }
    switch (ePendingAck)
    {
  case ADVISE:
  case UNADVISE:
  case POKE:
  case REQUEST:
      if (HIWORD(lParam))  /* will not be available for time-out */
    GlobalDeleteAtom(HIWORD(lParam));
      break;
  case EXECUTE:
      GlobalFree(HIWORD(lParam)); /* hCommand (execute string) */
      break;
    }
    return;
}



/****************************************************************************

    FUNCTION: ClientReceiveData

    PURPOSE:  Called when client application receives WM_DDE_DATA message.

****************************************************************************/
void ClientReceiveData(hwndClientDDE, hwndServerDDE, lParam)
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
    LONG  lParam;
{
    DDEDATA FAR * lpDDEData;
    char          szItem[ITEM_MAX_SIZE+1];
    BOOL          bRelease;
    BOOL          bAck;

    if (IsConvInTerminateState(hwndClientDDE, hwndServerDDE))
    { /* Terminate in progress: do not receive data */
        GlobalFree(LOWORD(lParam));
        GlobalDeleteAtom(HIWORD(lParam));
        return;
    }

    if (GetConvPendingAck(hwndClientDDE) == REQUEST)
    {
  SetConvPendingAck(hwndClientDDE, NONE);
  KillTimer(hwndClientDDE, hwndServerDDE);
    }

    if (!(lpDDEData = (DDEDATA FAR *)GlobalLock(LOWORD(lParam)))
        || (lpDDEData->cfFormat != CF_TEXT))
    {
  PostMessage(hwndServerDDE,
            WM_DDE_ACK,
      hwndClientDDE,
            MAKELONG(0, HIWORD(lParam)));  /* Negative ACK */
    }
    bAck = FALSE;
    if (IsInRequestDlg())
    {
  /* Update REQUEST dialog box value */
  RequestSatisfied(lpDDEData->Value);
        bAck = TRUE;
    }
    else
    {
        GlobalGetAtomName(HIWORD(lParam), szItem, ITEM_MAX_SIZE);
  bAck = SetConvItemValue(hwndClientDDE, szItem, lpDDEData->Value);
    }
    if (lpDDEData->fAckReq)
    {
  /* return ACK or NACK */
  PostMessage(hwndServerDDE,
            WM_DDE_ACK,
      hwndClientDDE,
      MAKELONG( (bAck? 0x8000:0), HIWORD(lParam)));
    }
    bRelease = lpDDEData->fRelease;
    GlobalUnlock(LOWORD(lParam));
    if (bRelease)
        GlobalFree(LOWORD(lParam));
    return;
}


/****************************************************************************

    FUNCTION: ClientTerminate

    PURPOSE:  Called when client application receives WM_DDE_TERMINATE
        message.

****************************************************************************/
void ClientTerminate(hwndClientDDE, hwndServerDDE)
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
{
    if (!IsConvInTerminateState(hwndClientDDE, hwndServerDDE))
    { /* Server has requested terminate: respond with terminate */
  PostMessage(hwndServerDDE, WM_DDE_TERMINATE, hwndClientDDE, 0L);
    }
    RemoveConv(hwndClientDDE, hwndServerDDE);
    if (!IsHwndClientDDEUsed(hwndClientDDE))
  DestroyWindow(hwndClientDDE);
    InvalidateRect(hwndMain, NULL, TRUE);
    return;
}



/****************************************************************************

    FUNCTION: DDEWndProc

    PURPOSE:  Handles all DDE messages received by the client application.

****************************************************************************/
long FAR PASCAL DDEWndProc(hwnd, message, wParam, lParam)
    HWND      hwnd;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    switch (message)
    {
  case WM_DDE_ACK:
      ClientAcknowledge(hwnd,(HWND)wParam, lParam, FALSE);
      return (0L);

  case WM_TIMER:
      /* Negative ACK because of time out */
      ClientAcknowledge(hwnd,(HWND)wParam, 0L, TRUE);
      return (0L);

   case WM_DDE_DATA:
       ClientReceiveData(hwnd,(HWND)wParam, lParam);
       return (0L);

   case WM_DDE_TERMINATE:
        ClientTerminate(hwnd,(HWND)wParam);
        return (0L);

   default:
        return (DefWindowProc(hwnd, message, wParam, lParam));
    }
}



/****************************************************************************

    FUNCTION: DoPasteLink

    PURPOSE:  Get conversation information (app/topic/item) from clipboard.
        Initiate conversation, if not already initiated.
        Then, request server to advise the specified item.

        Note, the standard clipboard format registered with the
        name "Link" is as follows:

        <app> <null> <topic> <null> <item> <null> <null>

****************************************************************************/
void DoPasteLink(void)
{

    HANDLE hData;
    LPSTR  lpData;
    HWND   hwndClientDDE;
    HWND   hwndServerDDE;
    char   szApplication[APP_MAX_SIZE+1];
    char   szTopic[TOPIC_MAX_SIZE+1];
    char   szItem[ITEM_MAX_SIZE+1];
    int    nBufLen;

    if (OpenClipboard(hwndMain))
    {
       if (!(hData = GetClipboardData(cfLink)) ||
    !(lpData = GlobalLock(hData)))
       {
          CloseClipboard();
    return;
       }


       /* Parse clipboard data */
       if ((nBufLen = lstrlen(lpData)) >= APP_MAX_SIZE)
       {
      CloseClipboard();
      GlobalUnlock(hData);
      return;
       }
       lstrcpy(szApplication, lpData);
       lpData += (nBufLen+1); /* skip over null */
       if ((nBufLen = lstrlen(lpData)) >= TOPIC_MAX_SIZE)
       {
      CloseClipboard();
      GlobalUnlock(hData);
      return;
       }
       lstrcpy(szTopic, lpData);
       lpData += (nBufLen+1); /* skip over null */
       if ((nBufLen = lstrlen(lpData)) >= ITEM_MAX_SIZE)
       {
      CloseClipboard();
      GlobalUnlock(hData);
      return;
       }
       lstrcpy(szItem, lpData);

       GlobalUnlock(hData);
       CloseClipboard();

       if (hwndClientDDE = FindConvGivenAppTopic(szApplication, szTopic))
       {   /* app/topic conversation already started */
     if (DoesAdviseAlreadyExist(hwndClientDDE, szItem))
         MessageBox(hwndMain,"Advisory already established",
                   "Client", MB_ICONEXCLAMATION | MB_OK);
           else
         hwndServerDDE = GetHwndServerDDE(hwndClientDDE);
         SendAdvise(hwndClientDDE, hwndServerDDE, szItem);
       }
       else
       {   /* must initiate new conversation first */
     SendInitiate(szApplication, szTopic);
     if (hwndClientDDE = FindConvGivenAppTopic(szApplication, szTopic))
     {
    hwndServerDDE = GetHwndServerDDE(hwndClientDDE);
    SendAdvise(hwndClientDDE, hwndServerDDE, szItem);
     }
       }
    }

    return;
}



/****************************************************************************

    FUNCTION: InitAckTimeOut

    PURPOSE:  Get DDE timeout value from win.ini.  Value is in milliseconds.

****************************************************************************/
void InitAckTimeOut(void)
{

   /* Finds value in win.ini section corresponding to application name */

   nAckTimeOut = GetPrivateProfileInt("Client",
             "DdeTimeOut",
             DEFAULT_ACK_TIME_OUT_MILLISEC,
                               "client.ini");
   return;
}

/****************************************************************************

    FUNCTION: SendAdvise

    PURPOSE:  Send advise message to server.


****************************************************************************/
void SendAdvise(hwndClientDDE, hwndServerDDE, szItem)
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
    char * szItem;
{
    ATOM            atomItem;
    HANDLE          hOptions;
    DDEADVISE FAR * lpOptions;

    /* don't send another message requiring an ACK until first message */
    /* is acknowledged                   */
    if (AwaitingAck(hwndClientDDE))
        return;

    if (!(hOptions
          = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (LONG)sizeof(DDEADVISE
        return;
    if (!(lpOptions
          = (DDEADVISE FAR *)GlobalLock(hOptions)))
    {
  GlobalFree(hOptions);
        return;
    }
    lpOptions->cfFormat = CF_TEXT;
    lpOptions->fAckReq = TRUE;
    lpOptions->fDeferUpd = FALSE;
    GlobalUnlock(hOptions);
    atomItem = GlobalAddAtom((LPSTR)szItem);
    SetConvPendingAck(hwndClientDDE, ADVISE);
    SetTimer(hwndClientDDE, hwndServerDDE, nAckTimeOut, NULL);
    if (!PostMessage(hwndServerDDE,
            WM_DDE_ADVISE,
      hwndClientDDE,
            MAKELONG(hOptions, atomItem)))
    {
        GlobalDeleteAtom(atomItem);
        GlobalFree(hOptions);
    }
    return;
}



/****************************************************************************

    FUNCTION: SendExecute

    PURPOSE:  Send execute string to server.


****************************************************************************/
void SendExecute(hwndClientDDE, hwndServerDDE, szExecuteString)
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
    char * szExecuteString;
{
    HANDLE  hExecuteString;
    LPSTR  lpExecuteString;

    /* don't send another message requiring an ACK until first message */
    /* is acknowledged                   */
    if (AwaitingAck(hwndClientDDE))
        return;

    if (!(hExecuteString
          = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
      (DWORD)lstrlen(szExecuteString) + 1)))
        return;
    if (!(lpExecuteString
    = GlobalLock(hExecuteString)))
    {
  GlobalFree(hExecuteString);
        return;
    }
    lstrcpy(lpExecuteString, szExecuteString);
    GlobalUnlock(hExecuteString);
    SetConvPendingAck(hwndClientDDE, EXECUTE);
    SetTimer(hwndClientDDE, hwndServerDDE, nAckTimeOut, NULL);
    if (!PostMessage(hwndServerDDE,
      WM_DDE_EXECUTE,
      hwndClientDDE,
      MAKELONG(0, hExecuteString)))
    {
  GlobalFree(hExecuteString);
    }
    return;
}



/****************************************************************************

    FUNCTION: SendInitiate

    PURPOSE:  Sends initiate message to all windows.  By the time this
        function returns, all servers matching the app/topic will
        have acknowledged, and this client applicaiton will have
        temporarily registered the new conversations.   If more
        than one server responded, then this client application
        asks the user which conversation to keep; all other
        conversations will then be terminated.   This function
        returns the handle of the hidden DDE window used to
        initiate the conversation with server(s).

****************************************************************************/
HWND SendInitiate(szApplication, szTopic)
    char * szApplication;
    char * szTopic;
{
    HWND  hwndClientDDE;
    ATOM  atomApplication;
    ATOM  atomTopic;

    if (!(hwndClientDDE = CreateWindow(
      "ClientDDEWndClass",
      "ClientDDE",
      WS_CHILD,  /* not visible */
      0, 0, 0, 0, /* no position or dimensions */
      hwndMain,  /* parent */
      NULL,  /* no menu */
      hInst,
      NULL)))
    {
  return (NULL);
    }

    atomApplication
        = *szApplication == 0 ? NULL : GlobalAddAtom((LPSTR)szApplication);
    atomTopic
        = *szTopic == 0 ? NULL : GlobalAddAtom((LPSTR)szTopic);

    /* flag bIniInitiate is queried when client processes the server's ACK */
    bInInitiate = TRUE;
    SendMessage(-1,
        WM_DDE_INITIATE,
  hwndClientDDE,
        MAKELONG(atomApplication, atomTopic));
    bInInitiate = FALSE;
    if (atomApplication != NULL)
        GlobalDeleteAtom(atomApplication);
    if (atomTopic != NULL)
        GlobalDeleteAtom(atomTopic);
    return (hwndClientDDE);
}

/****************************************************************************

    FUNCTION: SendPoke

    PURPOSE:  Send poke message to server.


****************************************************************************/
void SendPoke(hwndClientDDE, hwndServerDDE, szItem, szValue)
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
    char * szItem;
    char * szValue;
{
    ATOM        atomItem;
    HANDLE      hPokeData;
    DDEPOKE FAR * lpPokeData;

    /* don't send another message requiring an ACK until first message */
    /* is acknowledged                   */
    if (AwaitingAck(hwndClientDDE))
        return;

    /* Allocate size of DDE data header, plus the data:  a string   */
    /* terminated by <CR> <LF> <NULL>.  The <NULL> is counted by    */
    /* by DDEPOKE.Value[1].                                         */

    if (!(hPokeData
          = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
                        (LONG)sizeof(DDEPOKE) + lstrlen(szValue) + 2)))
        return;
    if (!(lpPokeData
          = (DDEPOKE FAR*)GlobalLock(hPokeData)))
    {
  GlobalFree(hPokeData);
        return;
    }
    lpPokeData->fRelease = TRUE;
    lpPokeData->cfFormat = CF_TEXT;
    lstrcpy((LPSTR)lpPokeData->Value, (LPSTR)szValue);
    /* each line of CF_TEXT data is terminated by CR/LF */
    lstrcat((LPSTR)lpPokeData->Value, (LPSTR)"\r\n");
    GlobalUnlock(hPokeData);
    atomItem = GlobalAddAtom((LPSTR)szItem);
    SetConvPendingAck(hwndClientDDE, POKE);
    SetTimer(hwndClientDDE, hwndServerDDE, nAckTimeOut, NULL);
    if (!PostMessage(hwndServerDDE,
            WM_DDE_POKE,
      hwndClientDDE,
            MAKELONG(hPokeData, atomItem)))
    {
        GlobalDeleteAtom(atomItem);
        GlobalFree(hPokeData);
    }
    return;
}



/****************************************************************************

    FUNCTION: SendRequest

    PURPOSE:  Send request message to server.


****************************************************************************/
void SendRequest(hwndClientDDE, hwndServerDDE, szItem)
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
    char * szItem;
{
    ATOM  atomItem;

    /* don't send another message requiring an ACK until first message */
    /* is acknowledged                   */
    if (AwaitingAck(hwndClientDDE))
        return;

    atomItem = GlobalAddAtom((LPSTR)szItem);
    SetConvPendingAck(hwndClientDDE, REQUEST);
    SetTimer(hwndClientDDE, hwndServerDDE, nAckTimeOut, NULL);
    if (!PostMessage(hwndServerDDE,
            WM_DDE_REQUEST,
      hwndClientDDE,
            MAKELONG(CF_TEXT,atomItem)))
    {
        GlobalDeleteAtom(atomItem);
    }
    return;
}


/****************************************************************************

    FUNCTION: SendTerminate

    PURPOSE:  Send terminate message to server.

****************************************************************************/
void SendTerminate(hwndClientDDE, hwndServerDDE)
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
{
    MSG msg;
    LONG lTimeOut;

    SetConvInTerminateState(hwndClientDDE, hwndServerDDE);
    PostMessage(hwndServerDDE, WM_DDE_TERMINATE, hwndClientDDE, 0L);
    return;
}




/****************************************************************************

    FUNCTION: SendUnadvise

    PURPOSE:  Send unadvise message to server.


****************************************************************************/
void SendUnadvise(hwndClientDDE, hwndServerDDE, szItem)
    HWND  hwndClientDDE;
    HWND  hwndServerDDE;
    char * szItem;
{
    ATOM  atomItem;

    /* don't send another message requiring an ACK until first message */
    /* is acknowledged                   */
    if (AwaitingAck(hwndClientDDE))
        return;

    atomItem = GlobalAddAtom((LPSTR)szItem);
    SetConvPendingAck(hwndClientDDE, UNADVISE);
    SetTimer(hwndClientDDE, hwndServerDDE, nAckTimeOut, NULL);
    if (!PostMessage(hwndServerDDE,
            WM_DDE_UNADVISE,
      hwndClientDDE,
            MAKELONG(0,atomItem)))
    {
        GlobalDeleteAtom(atomItem);
    }
    return;
}


/****************************************************************************

    FUNCTION: TerminateConversations

    PURPOSE:  Processes WM_DESTROY message, terminates all conversations.

****************************************************************************/
void TerminateConversations(void)
{
   HWND  hwndClientDDE;
   HWND  hwndServerDDE;
   LONG  lTimeOut;
   MSG   msg;


   /* Terminate each active conversation */
   hwndClientDDE = NULL;
   while (hwndClientDDE = GetNextConv(hwndClientDDE))
   {
  hwndServerDDE = GetHwndServerDDE(hwndClientDDE);
  if (IsWindow(hwndServerDDE)) /* if server window still alive */
      SendTerminate(hwndClientDDE, hwndServerDDE);
   }

   /* Wait for all conversations to terminate or for time out */
   lTimeOut = GetTickCount() + (LONG)nAckTimeOut;
   while (PeekMessage(&msg, NULL, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE))
   {
         DispatchMessage (&msg);
   if (msg.message == WM_DDE_TERMINATE)
   {
       if (!AtLeastOneConvActive())
     break;
   }
         if (GetTickCount() > lTimeOut)
             break;
   }

   return;
}


CLIENT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\DDE\CLIENT.C

/****************************************************************************

    PROGRAM: CLIENT

    PURPOSE: Illustrates client side of DDE conversation

    MODULES:

        CLIENT.C   Window and dialog procedures.
  CLIDATA.C  Maintains conversation data.
        CLIDDE.C   Processes incoming and outgoing DDE messages.

****************************************************************************/

#include "windows.h"

#include "dde.h"
#include "clires.h"
#include "client.h"
#include <string.h>
#include <stdlib.h>

static int    nInstCount;
static HWND   hwndRequestDlg;

static BOOL   bInInitiate = FALSE;
static BOOL   bInRequestDlg = FALSE;
static BOOL   bTerminating = FALSE;

static char  szSelectedApplication[APP_MAX_SIZE+1];
static char  szSelectedTopic[TOPIC_MAX_SIZE+1];
static char  szSelectedItem[ITEM_MAX_SIZE+1];
static char  szSelectedValue[VALUE_MAX_SIZE+1];
static HWND  hwndSelectedClientDDE;
static int   cfSelectedFormat;

long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
BOOL            InitApplication(HANDLE);
void            InitAddedInstance(HANDLE, HANDLE);
BOOL            InitInstance(HANDLE, int);
int  NEAR  DoDialog(char *, FARPROC);
BOOL FAR PASCAL AboutDlgProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL AdviseDlgProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL ClearDlgProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL ExecuteDlgProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL InitiateDlgProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL PokeDlgProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL RequestDlgProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL TerminateDlgProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL UnadviseDlgProc(HWND, unsigned, WORD, LONG);
void    AddConversationsToBox(HWND, unsigned);
void NEAR  GetSelectedConversation(HWND, unsigned, unsigned);


/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: Calls initialization functions and processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
    {
        if (!InitApplication(hInstance))
         return (FALSE);
    }
    else
    {
        InitAddedInstance(hInstance, hPrevInstance);
    }

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL))
    {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window classes

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    nInstCount = 1;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "ClientMenu";
    wc.lpszClassName = "ClientWClass";

    if (!RegisterClass(&wc))
  return (FALSE);

    wc.style = NULL;
    wc.lpfnWndProc = DDEWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = NULL;
    wc.hCursor = NULL;
    wc.hbrBackground = NULL;
    wc.lpszMenuName =  NULL;
    wc.lpszClassName = "ClientDDEWndClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION: InitAddedInstance

    PURPOSE:  Increment instance counter.

****************************************************************************/
void InitAddedInstance(hInstance, hPrevInstance)
    HANDLE  hInstance;
    HANDLE  hPrevInstance;
{
    GetInstanceData(hPrevInstance, (NPSTR)&nInstCount, sizeof(int));
    nInstCount++;
    return;
}



/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    HDC         hDC;
    TEXTMETRIC  tm;

    hInst = hInstance;

    hwndMain = CreateWindow(
        "ClientWClass",
        "Client",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hwndMain)
        return (FALSE);

    InitDataTextMetrics();
    InitAckTimeOut();      /* in module CLIDDE */

    MoveWindow(hwndMain,
        xDelta*(5+nInstCount),
        ((nInstCount-1)&1)*nVertRes/2 + yDelta*nInstCount,
        xDelta*30,
        yDelta*12,
        FALSE);

    if (!(cfLink = RegisterClipboardFormat("Link")))
  return (FALSE);

    ShowWindow(hwndMain, nCmdShow);
    UpdateWindow(hwndMain);

    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for client application.
        DDE messages are handled by DDEWndProc in CLIDDE.C.

****************************************************************************/

long FAR PASCAL MainWndProc(hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    char  szApplication[APP_MAX_SIZE+1];
    char  szTopic[TOPIC_MAX_SIZE+1];

    switch (message)
    {
        case WM_PAINT:
      PaintConvData(hwnd);
            return (0L);

        case WM_INITMENU:
            if (wParam == GetMenu(hwnd))
            {
    if (IsClipboardFormatAvailable(cfLink))
        EnableMenuItem(wParam, IDM_PASTELINK, MF_ENABLED);
    else
        EnableMenuItem(wParam, IDM_PASTELINK, MF_GRAYED);
            }
            return (0L);

        case WM_COMMAND:
            switch (wParam)
            {
    case IDM_INITIATE:
                    /* If we are in the process of terminating, no new
                       conversations are allowed */
                    if (!bTerminating)
                    {
      DoDialog("Initiate", InitiateDlgProc);
                    }
                    return 0L;

                case IDM_TERMINATE:
        DoDialog("Terminate", TerminateDlgProc);
                    return 0L;

                case IDM_ADVISE:
        DoDialog("Advise", AdviseDlgProc);
                    return 0L;

                case IDM_UNADVISE:
        DoDialog("Unadvise", UnadviseDlgProc);
                    return 0L;

                case IDM_REQUEST:
        DoDialog("Request", RequestDlgProc);
                    return 0L;

                case IDM_POKE:
        DoDialog("Poke", PokeDlgProc);
                    return 0L;

                case IDM_PASTELINK:
        DoPasteLink();
                    return 0L;

                case IDM_CLEAR:
        DoDialog("Clear", ClearDlgProc);
                    return 0L;

    case IDM_EXECUTE:
        DoDialog("Execute", ExecuteDlgProc);
        return 0L;

    case IDM_ABOUT:
        DoDialog("About", AboutDlgProc);
        break;

                default:
                    return (DefWindowProc(hwnd, message, wParam, lParam));
            }
            break;

        case WM_DESTROY:
            /* Terminate all DDE conversations before destroying
               client window */
      bTerminating = TRUE;
      TerminateConversations();
            PostQuitMessage(0);
            break;

  default:
      return (DefWindowProc(hwnd, message, wParam, lParam));
    }
    return (0L);
}


/****************************************************************************

    FUNCTION: DoDialog

    PURPOSE:  Creates dialog given dialog i.d.

****************************************************************************/
int NEAR DoDialog(szDialog, lpfnDlgProc)
    char   * szDialog;
    FARPROC  lpfnDlgProc;
{
    int      nReturn;

    lpfnDlgProc = MakeProcInstance(lpfnDlgProc, hInst);
    nReturn = DialogBox(hInst,
  szDialog,
  hwndMain,
        lpfnDlgProc);
    FreeProcInstance(lpfnDlgProc);
    return  (nReturn);
}



/****************************************************************************

    FUNCTION: AboutDlgProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

****************************************************************************/

BOOL FAR PASCAL AboutDlgProc(hDlg, message, wParam, lParam)
    HWND hDlg;
    unsigned message;
    WORD wParam;
    LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}



/****************************************************************************

    FUNCTION: AdviseDlgProc

    PURPOSE:  Processes messages for the Advise dialog.

****************************************************************************/
BOOL FAR PASCAL AdviseDlgProc(hdlg, message, wParam, lParam)
    HWND      hdlg;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    HWND  hwndServerDDE;

    switch (message)
    {
        case WM_INITDIALOG:
      AddConversationsToBox(hdlg, CB_ADDSTRING);
            return (TRUE);

        case WM_COMMAND:
            switch (wParam)
            {
                case IDC_OK:
        GetSelectedConversation(hdlg, CB_GETCURSEL, CB_GETLBTEXT);
                    GetDlgItemText(hdlg,
                        IDC_ITEM,
                        (LPSTR)szSelectedItem,
                        ITEM_MAX_SIZE);
        if (DoesAdviseAlreadyExist(hwndSelectedClientDDE,
                                               szSelectedItem))
                        MessageBox(hdlg, "Advisory already established",
                            "Client", MB_ICONEXCLAMATION | MB_OK);
                    else
      hwndServerDDE
          = GetHwndServerDDE(hwndSelectedClientDDE);
      SendAdvise(hwndSelectedClientDDE,
          hwndServerDDE,
          szSelectedItem);
        return (TRUE);

                case IDC_CANCEL:
                    EndDialog(hdlg, FALSE);
        return (FALSE);
            }

        default:
            return (FALSE);
    }
    return (FALSE);
}



/****************************************************************************

    FUNCTION: ClearDlgProc

    PURPOSE:  Processes messages for the Clear dialog.

****************************************************************************/
BOOL FAR PASCAL ClearDlgProc(hdlg, message, wParam, lParam)
    HWND      hdlg;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    HWND  hwndServerDDE;
    HWND  hctlItemBox;
    int   nIndex;

    switch (message)
    {
        case WM_INITDIALOG:
      AddConversationsToBox(hdlg, CB_ADDSTRING);
            return (TRUE);

        case WM_COMMAND:
            switch (wParam)
            {
                case IDC_OK:
        GetSelectedConversation(hdlg, CB_GETCURSEL, CB_GETLBTEXT);
                    GetDlgItemText(hdlg,
                        IDC_ITEM,
                        (LPSTR)szSelectedItem,
                        ITEM_MAX_SIZE);
        hwndServerDDE = GetHwndServerDDE(hwndSelectedClientDDE);
        SendUnadvise(hwndSelectedClientDDE,
      hwndServerDDE,
      szSelectedItem);
                    EndDialog(hdlg, TRUE);
        return (TRUE);

                case IDC_CANCEL:
                    EndDialog(hdlg, FALSE);
                    return (TRUE);
            }
        default:
            return (FALSE);
    }
    return (FALSE);
}



/****************************************************************************

    FUNCTION: ExecuteDlgProc

    PURPOSE:  Processes messages for the Execute dialog.

****************************************************************************/
BOOL FAR PASCAL ExecuteDlgProc(hdlg, message, wParam, lParam)
    HWND      hdlg;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    HWND  hwndServerDDE;
    char  szExecuteString[EXECUTE_STRING_MAX_SIZE+1];

    switch (message)
    {
        case WM_INITDIALOG:
      AddConversationsToBox(hdlg, CB_ADDSTRING);
            return (TRUE);

        case WM_COMMAND:
            switch (wParam)
            {
                case IDC_OK:
        GetSelectedConversation(hdlg, CB_GETCURSEL, CB_GETLBTEXT);
                    GetDlgItemText(hdlg,
      IDC_EXECUTE_STRING,
      (LPSTR)szExecuteString,
      EXECUTE_STRING_MAX_SIZE);
        hwndServerDDE = GetHwndServerDDE(hwndSelectedClientDDE);
        SendExecute(hwndSelectedClientDDE,
      hwndServerDDE,
      szExecuteString);
        return (TRUE);

                case IDC_CANCEL:
                    EndDialog(hdlg, FALSE);
        return (TRUE);
            }

        default:
            return (FALSE);
    }
    return (FALSE);
}




/****************************************************************************

    FUNCTION: InitiateDlgProc

    PURPOSE:  Processes messages for the Initiate dialog.

****************************************************************************/
BOOL FAR PASCAL InitiateDlgProc(hdlg, message, wParam, lParam)
    HWND      hdlg;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    HWND      hwndClientDDE;

    switch (message)
    {
        case WM_INITDIALOG:
            return (TRUE);

        case WM_COMMAND:
            switch (wParam)
            {
                case IDC_OK:
                    GetDlgItemText(hdlg,
                        IDC_APPLICATION,
                        (LPSTR)szSelectedApplication,
                        APP_MAX_SIZE);
                    GetDlgItemText(hdlg,
                        IDC_TOPIC,
                        (LPSTR)szSelectedTopic,
                        TOPIC_MAX_SIZE);
                    EndDialog(hdlg, TRUE);
        if (hwndClientDDE
      = SendInitiate(szSelectedApplication, szSelectedTopic))
        {
      LetUserPickConversation(hwndClientDDE);
      InvalidateRect(hwndMain, NULL, TRUE);
        }
        return (TRUE);

                case IDC_CANCEL:
                    EndDialog(hdlg, FALSE);
                    return (TRUE);
            }
        default:
            return (FALSE);
    }
    return (FALSE);
}




/****************************************************************************

    FUNCTION: PokeDlgProc

    PURPOSE:  Processes messages for the Poke dialog.

****************************************************************************/
BOOL FAR PASCAL PokeDlgProc(hdlg, message, wParam, lParam)
    HWND      hdlg;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    HWND  hwndServerDDE;

    switch (message)
    {
        case WM_INITDIALOG:
      AddConversationsToBox(hdlg, CB_ADDSTRING);
            return (TRUE);

        case WM_COMMAND:
            switch (wParam)
            {
                case IDC_OK:
        GetSelectedConversation(hdlg, CB_GETCURSEL, CB_GETLBTEXT);
                    GetDlgItemText(hdlg,
                        IDC_ITEM,
                        (LPSTR)szSelectedItem,
                        ITEM_MAX_SIZE);
                    GetDlgItemText(hdlg,
                        IDC_VALUE,
                        (LPSTR)szSelectedValue,
                        VALUE_MAX_SIZE);
        hwndServerDDE = GetHwndServerDDE(hwndSelectedClientDDE);
        SendPoke(hwndSelectedClientDDE,
      hwndServerDDE,
                        szSelectedItem,
                        szSelectedValue);
        return (TRUE);

                case IDC_CANCEL:
                    EndDialog(hdlg, FALSE);
        return (TRUE);
            }

        default:
            return (FALSE);
    }
    return (FALSE);
}


/****************************************************************************

    FUNCTION: RequestDlgProc

    PURPOSE:  Processes messages for the Request dialog.

****************************************************************************/
BOOL FAR PASCAL RequestDlgProc(hdlg, message, wParam, lParam)
    HWND      hdlg;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    HWND  hwndServerDDE;

    switch (message)
    {
        case WM_INITDIALOG:
            hwndRequestDlg = hdlg;
            bInRequestDlg = TRUE;
      AddConversationsToBox(hdlg, CB_ADDSTRING);
            return (TRUE);

        case WM_COMMAND:
            switch (wParam)
            {
                case IDC_OK:
        GetSelectedConversation(hdlg, CB_GETCURSEL, CB_GETLBTEXT);
                    GetDlgItemText(hdlg,
                        IDC_ITEM,
                        (LPSTR)szSelectedItem,
                        ITEM_MAX_SIZE);
        hwndServerDDE = GetHwndServerDDE(hwndSelectedClientDDE);
        SendRequest(hwndSelectedClientDDE,
      hwndServerDDE,
      szSelectedItem);
        return (TRUE);

                case IDC_CANCEL:
                    bInRequestDlg = FALSE;
                    EndDialog(hdlg, FALSE);
                    return (TRUE);
            }
            break;

        case WM_DESTROY:
            bInRequestDlg = FALSE;
            return (FALSE);

        default:
            return (FALSE);
    }
    return (FALSE);
}



/****************************************************************************

    FUNCTION: TerminateDlgProc

    PURPOSE:  Processes messages for the Terminate dialog.

****************************************************************************/
BOOL FAR PASCAL TerminateDlgProc(hdlg, message, wParam, lParam)
    HWND      hdlg;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    HWND hwndServerDDE;

    switch (message)
    {
        case WM_INITDIALOG:
      AddConversationsToBox(hdlg, LB_ADDSTRING);
            return (TRUE);

        case WM_COMMAND:
            switch (wParam)
            {
                case IDC_OK:
        GetSelectedConversation(hdlg, LB_GETCURSEL, LB_GETTEXT);
                    EndDialog(hdlg, TRUE);
        hwndServerDDE = GetHwndServerDDE(hwndSelectedClientDDE);
        SendTerminate(hwndSelectedClientDDE, hwndServerDDE);
        return (TRUE);

                case IDC_CANCEL:
                    EndDialog(hdlg, FALSE);
        return (TRUE);
            }
        default:
            return (FALSE);
    }
    return (FALSE);
}




/****************************************************************************

    FUNCTION: UnadviseDlgProc

    PURPOSE:  Processes messages for the Unadvise dialog.

****************************************************************************/
BOOL FAR PASCAL UnadviseDlgProc(hdlg, message, wParam, lParam)
    HWND      hdlg;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    HWND  hctlItemBox;
    int   nIndex;
    HWND  hwndServerDDE;

    switch (message)
    {
        case WM_INITDIALOG:
      AddConversationsToBox(hdlg, CB_ADDSTRING);
            return (TRUE);

        case WM_COMMAND:
            switch (wParam)
            {
                case IDC_OK:
        GetSelectedConversation(hdlg, CB_GETCURSEL, CB_GETLBTEXT);
                    GetDlgItemText(hdlg,
                        IDC_ITEM,
                        (LPSTR)szSelectedItem,
                        ITEM_MAX_SIZE);
        hwndServerDDE = GetHwndServerDDE(hwndSelectedClientDDE);
        SendUnadvise(hwndSelectedClientDDE,
      hwndServerDDE,
                        szSelectedItem);
        return (TRUE);

                case IDC_CANCEL:
                    EndDialog(hdlg, FALSE);
                    return (TRUE);
            }
        default:
            return (FALSE);
    }
    return (FALSE);
}



/****************************************************************

    FUNCTION: AddConversationsToBox

    PURPOSE:  Add server, app, topic info to client list box


****************************************************************/
void AddConversationsToBox(hdlg, nAddMessage)
    HWND      hdlg;
    unsigned  nAddMessage;  /* LB_ADDSTRING or CB_ADDSTRING */
{
    HWND  hwndClientDDE;
    HWND  hctlServerList;
    char  szConvInfo[CONVINFO_MAX_SIZE+1];
    char  szApp[APP_MAX_SIZE+1];
    char  szTopic[TOPIC_MAX_SIZE+1];

    hctlServerList = GetDlgItem(hdlg, IDC_CONVBOX);
    SendMessage(hctlServerList,
        nAddMessage == LB_ADDSTRING ? LB_RESETCONTENT : CB_RESETCONTENT,
        0,
        0L);
    hwndClientDDE = NULL;
    while (1)
    {
  if (!(hwndClientDDE = GetNextConv(hwndClientDDE)))
      break;
  itoa((int)hwndClientDDE, szConvInfo, 16);
  strupr(szConvInfo);
  strcat(szConvInfo,"->");
  itoa((int)GetHwndServerDDE(hwndClientDDE),
      szConvInfo+strlen(szConvInfo),
      16);
  strcat(szConvInfo," ");
  GetAppAndTopic(hwndClientDDE, szApp, szTopic);
  strcat(szConvInfo, szApp);
  strcat(szConvInfo, " | ");
  strcat(szConvInfo, szTopic);

        SendMessage(hctlServerList,
            nAddMessage,
            0,
      (LONG)(LPSTR)szConvInfo);
    }
    if (nAddMessage == CB_ADDSTRING)
    {
  SendMessage(hctlServerList, CB_SETCURSEL, 0, 0L);
    }
    return;
}


/*********************************************************************

    FUNCTION: IsInRequestDlg

    PURPOSE:  Returns whether the user is in the Request dialog or not.

*********************************************************************/
BOOL IsInRequestDlg()
{
    return (bInRequestDlg);
}



/*********************************************************************

    FUNCTION: GetSelectedConversation

    PURPOSE:  Gets the user's selection from the conversation list
        box, and returns result in hwndSelectedClientDDE.

*********************************************************************/
void NEAR GetSelectedConversation(hdlg, nCurSelMessage, nGetTextMessage)
    HWND      hdlg;
    unsigned  nCurSelMessage;
    unsigned  nGetTextMessage;
{
    HWND hctlConvBox;
    int  nIndex;
    char szConvInfo[CONVINFO_MAX_SIZE+1];
    char * pcBlank;


    hctlConvBox = GetDlgItem(hdlg, IDC_CONVBOX);
    if ((nIndex = SendMessage(hctlConvBox, nCurSelMessage, 0, 0L))
        != LB_ERR)
    {
  szConvInfo[0] = 0;
  SendMessage(hctlConvBox,
            nGetTextMessage,
            nIndex,
      (LONG)(LPSTR)szConvInfo);
  /* find '-' in 'hwnd->hwnd' list box entry */
  if (!(pcBlank = strchr(szConvInfo, '-')))
            return;
        *pcBlank = 0;  /* terminate hwnd numeric value */
  hwndSelectedClientDDE = HexToInt(szConvInfo);
     }
     return;
}



/****************************************************************

    FUNCTION: InitDataTextMetrics

    PURPOSE:  Get font information

****************************************************************/
void InitDataTextMetrics()
{
    HDC hDC;
    TEXTMETRIC tm;

    hDC = GetDC(hwndMain);
    GetTextMetrics(hDC, (LPTEXTMETRIC)&tm);
    nHorzRes = GetDeviceCaps(hDC, HORZRES);
    nVertRes = GetDeviceCaps(hDC, VERTRES);
    ReleaseDC(hwndMain, hDC);
    yDelta = tm.tmHeight + tm.tmExternalLeading;
    xDelta = tm.tmAveCharWidth;
    return;
}


/*********************************************************************

    FUNCTION: RequestSatisfied

    PURPOSE:  Updates Request dialog box with value requested from
        server.

*********************************************************************/
void RequestSatisfied(lpszValue)
    LPSTR lpszValue;
{
    HWND hctlValue;

    hctlValue = GetDlgItem(hwndRequestDlg, IDC_VALUE);
    SetWindowText(hctlValue, lpszValue);
    return;
}


/*********************************************************************

    FUNCTION: SetSelectedValue

    PURPOSE:  Set specified value.

*********************************************************************/
void SetSelectedValue(lpszSelectedValue)
    LPSTR lpszSelectedValue;
{
    lstrcpy((LPSTR)szSelectedValue, lpszSelectedValue);
    return;
}


CLIPTEXT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\CLIPTEXT\CLIPTEXT.C

/****************************************************************************

    PROGRAM: Cliptext.c

    PURPOSE: Demonstrates copying text to and from the clipboard

    FUNCTIONS:

  WinMain() - calls initialization function, processes message loop
  InitApplication() - initializes window data and registers window
  InitInstance() - saves instance handle and creates main window
  MainWndProc() - processes messages
  About() - processes messages for "About" dialog box
        OutOfMemory() - displays warning message

****************************************************************************/

#include "windows.h"
#include "cliptext.h"

HANDLE hInst;
HANDLE hAccTable;
HWND   hwnd;

HANDLE hText = NULL;

char szInitialClientAreaText[] =
    "This program demonstrates the use of the Edit menu to copy and "
    "paste text to and from the clipboard.  Try using the Copy command "
    "to move this text to the clipboard, and the Paste command to replace "
    "this text with data from another application.  \r\n\r\n"
    "You might want to try running Notepad and Clipbrd alongside this "
    "application so that you can watch the data exchanges take place.  ";

HANDLE hData, hClipData;                            /* handles to clip data
LPSTR lpData, lpClipData;                           /* pointers to clip data

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;
    LPSTR lpszText;

    if (!hPrevInstance)
  if (!InitApplication(hInstance))
      return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {

    /* Only translate message if it is not an accelerator message */

        if (!TranslateAccelerator(hwnd, hAccTable, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "CliptextMenu";
    wc.lpszClassName = "CliptextWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    LPSTR           lpszText;

    hInst = hInstance;

    hAccTable = LoadAccelerators(hInst, "ClipTextAcc");

    if (!(hText
          = GlobalAlloc(GMEM_MOVEABLE,(DWORD)sizeof(szInitialClientAreaText))
        OutOfMemory();
        return (FALSE);
    }

    if (!(lpszText = GlobalLock(hText))) {
        OutOfMemory();
        return (FALSE);
    }

    lstrcpy(lpszText, szInitialClientAreaText);
    GlobalUnlock(hText);

    hwnd = CreateWindow(
        "CliptextWClass",
        "Cliptext Sample Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hwnd)
        return (FALSE);

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

        WM_COMMAND    - message from menu
        WM_INITMENU   - initialize menu
  WM_PAINT      - update window
        WM_DESTROY    - destroy window

    COMMENTS:

        WM_INITMENU - when this message is received, the application checks
        to see if there is any text data in the clipboard, and enables or
        disables the Paste menu item accordingly.

        Seclecting the Copy menu item will send the text "Hello Windows" to
        the clipboard.

        Seclecting the Paste menu item will copy whatever text is in the
        clipboard to the application window.

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout;
    HDC hDC;
    HMENU hMenu;
    PAINTSTRUCT ps;
    RECT rectClient;
    LPSTR lpszText;

    switch (message) {

        case WM_INITMENU:
            if (wParam == GetMenu(hWnd)) {
                if (OpenClipboard(hWnd)) {
                    if (IsClipboardFormatAvailable(CF_TEXT)
                        || IsClipboardFormatAvailable(CF_OEMTEXT))
                        EnableMenuItem(wParam, IDM_PASTE, MF_ENABLED);
                    else
                        EnableMenuItem(wParam, IDM_PASTE, MF_GRAYED);
                    CloseClipboard();
                    return (TRUE);
                }
                else                           /* Clipboard is not available
                    return (FALSE);

            }
            return (TRUE);

        case WM_COMMAND:
            switch(wParam) {
                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
                    FreeProcInstance(lpProcAbout);
                    break;

                /* file menu commands */

                case IDM_NEW:
                case IDM_OPEN:
                case IDM_SAVE:
                case IDM_SAVEAS:
                case IDM_PRINT:
                    MessageBox (
                          GetFocus ()
                        , "Command not implemented."
                        , "ClipText Sample Application"
                        , MB_ICONASTERISK | MB_OK
                    );
                    break;

                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;

                /* edit menu commands */

                case IDM_UNDO:
                case IDM_CLEAR:
                    MessageBox (
                          GetFocus ()
                        , "Command not implemented."
                        , "ClipText Sample Application"
                        , MB_ICONASTERISK | MB_OK
                    );
                    break;

                case IDM_CUT:
                case IDM_COPY:

                    if (hText != NULL) {

                        /* Allocate memory and copy the string to it */

                        if (!(hData
                             = GlobalAlloc(GMEM_MOVEABLE, GlobalSize (hText))
                            OutOfMemory();
                            return (TRUE);
                        }
                        if (!(lpData = GlobalLock(hData))) {
                            OutOfMemory();
                            return (TRUE);
                        }
                        if (!(lpszText = GlobalLock (hText))) {
                            OutOfMemory();
                            return (TRUE);
                        }
                        lstrcpy(lpData, lpszText);
                        GlobalUnlock(hData);
                        GlobalUnlock (hText);

                        /* Clear the current contents of the clipboard, and s
                         * the data handle to the new string.
                         */

                        if (OpenClipboard(hWnd)) {
                            EmptyClipboard();
                            SetClipboardData(CF_TEXT, hData);
                            CloseClipboard();
                        }
                        hData = NULL;

                        if (wParam == IDM_CUT) {
                            GlobalFree (hText);
                            hText = NULL;
                            EnableMenuItem(GetMenu (hWnd), IDM_CUT, MF_GRAYED
                            EnableMenuItem(GetMenu(hWnd), IDM_COPY, MF_GRAYED
                            InvalidateRect (hWnd, NULL, TRUE);
                            UpdateWindow (hWnd);
                        }
                    }

                    return (TRUE);

                case IDM_PASTE:
                    if (OpenClipboard(hWnd)) {

                        /* get text from the clipboard */

                        if (!(hClipData = GetClipboardData(CF_TEXT))) {
                            CloseClipboard();
                            break;
                        }
                        if (hText != NULL) {
                            GlobalFree(hText);
                        }
                        if (!(hText = GlobalAlloc(GMEM_MOVEABLE
                                                    , GlobalSize(hClipData)))
                            OutOfMemory();
                            CloseClipboard();
                            break;
                        }
                        if (!(lpClipData = GlobalLock(hClipData))) {
                            OutOfMemory();
                            CloseClipboard();
                            break;
                        }
                        if (!(lpszText = GlobalLock(hText))) {
                            OutOfMemory();
                            CloseClipboard();
                            break;
                        }
                        lstrcpy(lpszText, lpClipData);
                        GlobalUnlock(hClipData);
                        CloseClipboard();
                        GlobalUnlock(hText);
                        EnableMenuItem(GetMenu(hWnd), IDM_CUT, MF_ENABLED);
                        EnableMenuItem(GetMenu(hWnd), IDM_COPY, MF_ENABLED);

                        /* copy text to the application window */

                        InvalidateRect(hWnd, NULL, TRUE);
                        UpdateWindow(hWnd);
                        return (TRUE);
                    }
                    else
                        return (FALSE);
            }
            break;

  case WM_SIZE:
      InvalidateRect(hWnd, NULL, TRUE);
      break;

  case WM_PAINT:
            hDC = BeginPaint (hWnd, &ps);
            if (hText != NULL) {
                if (!(lpszText = GlobalLock (hText))) {
                    OutOfMemory();
                } else {
        GetClientRect (hWnd, &rectClient);
                    DrawText (hDC, lpszText, -1, &rectClient
                                , DT_EXTERNALLEADING | DT_NOPREFIX | DT_WORDB
                    GlobalUnlock (hText);
                }
            }
      EndPaint (hWnd, &ps);
            break;

  case WM_DESTROY:
      PostQuitMessage(0);
      break;

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


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}


/****************************************************************************

    FUNCTION: OutOfMemory(void)

    PURPOSE:  Displays warning message

****************************************************************************/
void OutOfMemory(void)
{
    MessageBox(
        GetFocus(),
        "Out of Memory",
        NULL,
        MB_ICONHAND | MB_SYSTEMMODAL);
    return;
}


CLOCK.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\CLOCK\CLOCK.C

/***************************************************************************
 *                                                                         *
 *  PROGRAM   : Clock.c                                                    *
 *                                                                         *
 *  PURPOSE   : To give a demonstration on the use of a timer in a windows *
 *              application.                                               *
 *                                                                         *
 *  MACROS    : HourHandPos  - Computes the hour hand position based on    *
 *                             both the hour and minute values.            *
 *                                                                         *
 *              VertEquiv    - Computes the raster line equivalent to the  *
 *                             given pixel value.                          *
 *                                                                         *
 *              HorzEquiv    - Computes the pixel equivalent to the given  *
 *                             raster line value.                          *
 *                                                                         *
 *  FUNCTIONS : About        - Dialog function for the About Dialog.       *
 *                                                                         *
 *              ClockWndProc - Window function for the application.        *
 *                                                                         *
 *              CreateTools  - Creates brushes and pens to coincide with   *
 *                             the current system colors.                  *
 *                                                                         *
 *              DeleteTools  - Destroys the brushes and pens created by    *
 *                             CreateTools.                                *
 *                                                                         *
 *              ClockCreate  - Performs the necessary initialization for   *
 *                             drawing the clock correctly and gets the    *
 *                             initial time to be displayed by the clock.  *
 *                                                                         *
 *              ClockSize    - Resize the clock to the largest possible    *
 *                             circle that will fit in the client area.    *
 *                                                                         *
 *              ClockTimer   - Update the clock to reflect the most recent *
 *                             time.                                       *
 *                                                                         *
 *              ClockPaint   - Paint the clock to display the most recent  *
 *                             time.                                       *
 *                                                                         *
 *              DrawFace     - Draws the clock face.                       *
 *                                                                         *
 *              DrawHand     - Draws a thin hand with the specified brush  *
 *                             in the specified hand position.             *
 *                                                                         *
 *              DrawFatHand  - Draws a fat hand with the specified brush   *
 *                             in the specified hand position.             *
 *                                                                         *
 *              CircleClock  - Resizes clock rectangle to keep clock       *
 *                             circular.                                   *
 *                                                                         *
 *              WinMain      - Calls the initialization function, creates  *
 *                             the main application window, and enters the *
 *                             message loop.                               *
 *                                                                         *
 *              ClockInit    - Registers the application window class and  *
 *                             initializes the circle values for the clock *
 *                             face.                                       *
 *                                                                         *
 ***************************************************************************/

#include "windows.h"
#include "clock.h"

/* Structure for holding time (in hours, minutes, and seconds) */
typedef struct
{
  int hour;
  int minute;
  int second;
} TIME;

extern void GetTime(TIME *); /* asm function to get current time */

TIME oTime;             /* the time currently displayed on the clock

HBRUSH hbrForegnd;      /* foreground brush -- system window text color
HBRUSH hbrBackgnd;      /* background brush -- system window backbround color
HPEN   hpenForegnd;     /* foreground pen   -- system window text color
HPEN   hpenBackgnd;     /* background pen   -- system window background color

HANDLE hInst;           /* instance of the CLOCK program being executed
BOOL   bFirst = TRUE;   /* TRUE if this is the 1st instance; FALSE otherwise

HANDLE    hCirTab;      /* Circle table for the circular clock face positions
POINT FAR *lpCirTab;    /* Pointer to the circle table

int   TimerID = 1;      /* number used for timer-id
char  szBuffer[BUFLEN]; /* buffer for stringtable data
RECT  ClockRect;        /* rectangle that EXACTLY bounds the clock face
long  ClockRadius;      /* clock face radius
POINT ClockCenter;      /* clock face center
BOOL  bIconic = FALSE;  /* TRUE if clock is currently iconic; FALSE otherwise

int   HorzRes;          /* width of the display (in pixels)
int   VertRes;          /* height of the display (in raster lines)
long  AspectH;          /* number of pixels per decimeter on the display
long  AspectV;          /* number of raster lines per decimeter on the displa


/***************************************************************************
 *                                                                         *
 *  MACRO    : HourHandPos (TIME)                                          *
 *                                                                         *
 *  PURPOSE  : Computes the hour hand position based on both the hour and  *
 *             minute values in the given time record.                     *
 *                                                                         *
 ***************************************************************************/

#define HourHandPos(time)  (time.hour * 5) + (time.minute /12)


/***************************************************************************
 *                                                                         *
 *  MACRO    : VertEquiv (int)                                             *
 *                                                                         *
 *  PURPOSE  : Computes the raster line (vertical) equivalent to the given *
 *             pixel (horizontal) value.                                   *
 *                                                                         *
 ***************************************************************************/

#define VertEquiv(lengthH) ((lengthH * AspectV) / AspectH)


/***************************************************************************
 *                                                                         *
 *  MACRO    : HorzEquiv (int)                                             *
 *                                                                         *
 *  PURPOSE  : Computes the pixel (horizontal) equivalent to the given     *
 *             raster line (vertical) value.                               *
 *                                                                         *
 ***************************************************************************/

#define HorzEquiv(lengthV) ((lengthV * AspectH) / AspectV)


/***************************************************************************
 *                                                                         *
 *  FUNCTION : About (HWND, unsigned, WORD, LONG)                          *
 *                                                                         *
 *  PURPOSE  : Dialog function for the "About..." menu item dialog.        *
 *                                                                         *
 ***************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
  HWND     hDlg;
  unsigned message;
  WORD     wParam;
  LONG     lParam;
{
  switch (message)
  {
    case WM_COMMAND:
      EndDialog(hDlg, TRUE);
      /* fall through */

    case WM_INITDIALOG:
      return(TRUE);

    default:
      return(FALSE);
  }
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : ClockWndProc (HWND, unsigned, WORD, LONG)                   *
 *                                                                         *
 *  PURPOSE  : Window function for the application.                        *
 *                                                                         *
 ***************************************************************************/

long FAR PASCAL ClockWndProc(hWnd, message, wParam, lParam)
  HWND     hWnd;
  unsigned message;
  WORD     wParam;
  LONG     lParam;
{
  switch (message)
  {
    case WM_SYSCOMMAND:
      if (wParam == IDM_ABOUT)
      {
        /* Draw and handle messages for the "About..." Dialog */
        DialogBox(hInst,
            MAKEINTRESOURCE(1),
            hWnd,
            MakeProcInstance((FARPROC) About, hInst));
      }
      else
      {
        /* Perform the default window processing */
        return(DefWindowProc(hWnd, message, wParam, lParam));
      }
      break;

    case WM_SIZE:
      /* Resize clock based on window size and redraw */
      ClockSize(hWnd, LOWORD(lParam), HIWORD(lParam), wParam);
      UpdateWindow(hWnd);
      break;

    case WM_DESTROY:
      /* Destroy clock's timer and tools before exiting */
      KillTimer(hWnd, TimerID);
      DeleteTools();
      PostQuitMessage(0);
      break;

    case WM_PAINT:
      {
        PAINTSTRUCT ps;

        /* Paint clock displaying current time */
        InvalidateRect(hWnd, (LPRECT) NULL, TRUE);
        BeginPaint(hWnd, (LPPAINTSTRUCT) &ps);
        ClockPaint(hWnd, ps.hdc, PAINTALL);
        EndPaint(hWnd, (LPPAINTSTRUCT) &ps);
      }
      break;

    case WM_TIMECHANGE:
    case WM_TIMER:
      /* Update clock to display new time */
      ClockTimer(hWnd);
      break;

    case WM_SYSCOLORCHANGE:
      /* Change tools to coincide with system window colors */
      DeleteTools();
      CreateTools();
      break;

    case WM_ERASEBKGND:
      {
        RECT rc;

        /* Paint over the entire client area */
        GetClientRect(hWnd, (LPRECT) &rc);
        FillRect((HDC) wParam, (LPRECT) &rc, hbrBackgnd);
      }
      break;

    default:
      /* Perform the default window processing */
      return(DefWindowProc(hWnd, message, wParam, lParam));
  }
  return(0L);
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : CreateTools ()                                              *
 *                                                                         *
 *  PURPOSE  : Creates brushes and pens to coincide with the current       *
 *             system colors.                                              *
 *                                                                         *
 ***************************************************************************/

int CreateTools()
{
    hbrForegnd  = CreateSolidBrush(GetSysColor(COLOR_WINDOWTEXT));
    hbrBackgnd  = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
    hpenForegnd = CreatePen(0, 1, GetSysColor(COLOR_WINDOWTEXT));
    hpenBackgnd = CreatePen(0, 1, GetSysColor(COLOR_WINDOW));
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : DeleteTools ()                                              *
 *                                                                         *
 *  PURPOSE  : Destroys the brushes and pens created by CreateTools.       *
 *                                                                         *
 ***************************************************************************/

int DeleteTools()
{
    DeleteObject(hbrForegnd);
    DeleteObject(hbrBackgnd);
    DeleteObject(hpenForegnd);
    DeleteObject(hpenBackgnd);
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : ClockCreate ()                                              *
 *                                                                         *
 *  PURPOSE  : First, for drawing the clock, ClockCreate computes the      *
 *             aspect ratio and creates the necessary pens and brushes.    *
 *             Then, if this is the first instance of the app running,     *
 *             ClockCreate scales the circle table values according to the *
 *             aspect ratio. Finally, ClockCreate gets the initial time.   *
 *                                                                         *
 ***************************************************************************/

int ClockCreate()
{
  int  pos;      /* hand position index into the circle table */
  int  vertSize; /* height of the display in millimeters      */
  int  horzSize; /* width of the display in millimeters       */
  HDC  hDC;
  RECT rc;

  /* Get display size in (pixels X raster lines) */
  /* and in (millimeters X millimeters)          */
  hDC = GetDC(NULL);
  VertRes = GetDeviceCaps(hDC, VERTRES);
  HorzRes = GetDeviceCaps(hDC, HORZRES);
  vertSize= GetDeviceCaps(hDC, VERTSIZE);
  horzSize= GetDeviceCaps(hDC, HORZSIZE);
  ReleaseDC(NULL, hDC);

  /* Compute (raster lines / decimeter) and (pixels / decimeter) */
  AspectV = ((long) VertRes * MMPERDM) / (long) vertSize;
  AspectH = ((long) HorzRes * MMPERDM) / (long) horzSize;

  CreateTools();

  /* Scale cosines for aspect ratio if this is the first instance */
  if (bFirst)
  {
    lpCirTab = (POINT far *) GlobalLock(hCirTab);
    for (pos = 0; pos < HANDPOSITIONS; pos++)
    {
      lpCirTab[pos].y = VertEquiv(lpCirTab[pos].y);
    }
    GlobalUnlock(hCirTab);
        }

  GetTime(&oTime);
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : ClockSize (HWND, int, int, WORD)                            *
 *                                                                         *
 *  PURPOSE  : Resize the clock to the largest possible circle that will   *
 *             fit in the client area. If switching from not iconic to     *
 *             iconic, alter the timer to update every minute.  And if     *
 *             switching back to non iconic, restore the timer to update   *
 *             every second.                                               *
 *                                                                         *
 ***************************************************************************/

int ClockSize(hWnd, newWidth, newHeight, sizeType)
  HWND hWnd;
  int  newWidth;
  int  newHeight;
  WORD sizeType;
{
  /* Set ClockRect to bound the largest possible circle in the window */
  SetRect((LPRECT) &(ClockRect), 0, 0, newWidth, newHeight);
  CircleClock(newWidth, newHeight);

  if(sizeType == SIZEICONIC)
  {
    /* Update once every minute in the iconic state */
    KillTimer(hWnd, TimerID);
    SetTimer(hWnd, TimerID, (unsigned) ICON_TLEN, 0L);
    bIconic = TRUE;
  }
  else if (bIconic)
  {
    /* Update every second in the opened state (ignore tiling) */
    KillTimer(hWnd, TimerID);
    SetTimer(hWnd, TimerID, OPEN_TLEN, 0L);
    bIconic = FALSE;
  }
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : ClockTimer (HWND)                                           *
 *                                                                         *
 *  PURPOSE  : Update the clock to reflect the most recent time.           *
 *                                                                         *
 ***************************************************************************/

int ClockTimer(hWnd)
  HWND hWnd;
{
  TIME nTime;
  HDC  hDC;

  GetTime(&nTime);

  /* It's possible to change any part of the system at any time through */
  /* the Control Panel. Check for any change in second, minute, or hour */
  if ((nTime.second != oTime.second) ||
      (nTime.minute != oTime.minute) ||
      (nTime.hour   != oTime.hour))
  {
    /* The time has changed -- update the clock */
    hDC = GetDC(hWnd);
    ClockPaint(hWnd, hDC, HANDPAINT);
    ReleaseDC(hWnd, hDC);
  }
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : ClockPaint (HWND, HDC, int)                                 *
 *                                                                         *
 *  PURPOSE  : Paint the clock to display the most recent time.            *
 *                                                                         *
 ***************************************************************************/

int ClockPaint(hWnd, hDC, paintType)
  HWND hWnd;
  HDC  hDC;
  int  paintType;
{
  TIME nTime;

  SetBkMode(hDC, TRANSPARENT);

  lpCirTab = (POINT far *) GlobalLock(hCirTab);

  if (paintType == PAINTALL)
  {
    /* Paint entire clock -- face and hands */
    FillRect(hDC, (LPRECT) &ClockRect, hbrBackgnd);
    DrawFace(hDC);
    DrawFatHand(hDC, HourHandPos(oTime), hpenForegnd, HHAND);
    DrawFatHand(hDC, oTime.minute, hpenForegnd, MHAND);
    if (!bIconic)
    {
      /* Erase old second hand */
      DrawHand(hDC, oTime.second, hpenBackgnd, SECONDTIP, R2_NOT);
    }
        }
  else if (paintType == HANDPAINT)
  {
    GetTime(&nTime);

    if ((!bIconic) && (nTime.second != oTime.second))
    {
      /* Second has changed -- erase old second hand */
      DrawHand(hDC, oTime.second, hpenBackgnd, SECONDTIP, R2_NOT);
    }

    if ((nTime.minute != oTime.minute) || (nTime.hour != oTime.hour))
    {
      /* Hour and/or minute have changed -- update hands */
      if (bIconic)
      {
        /* Erase old minute and hour hands */
        DrawHand(hDC, oTime.minute,
                 hpenBackgnd, MINUTETIP, R2_COPYPEN);
        DrawHand(hDC, HourHandPos(oTime),
                 hpenBackgnd, HOURTIP, R2_COPYPEN);

        /* Draw new minute and hour hands */
        DrawHand(hDC, nTime.minute,
                 hpenForegnd, MINUTETIP, R2_COPYPEN);
        DrawHand(hDC, HourHandPos(nTime),
                 hpenForegnd, HOURTIP, R2_COPYPEN);

      }
      else
      {
        /* Erase old minute and hour fat hands */
        DrawFatHand(hDC, oTime.minute,
              hpenBackgnd, MHAND);
        DrawFatHand(hDC, HourHandPos(oTime),
              hpenBackgnd, HHAND);

        /* Draw new minute and hour fat hands */
        DrawFatHand(hDC, nTime.minute,
              hpenForegnd, MHAND);
        DrawFatHand(hDC, HourHandPos(nTime),
                    hpenForegnd, HHAND);
      }
    }

    if ((!bIconic) && (nTime.second != oTime.second))
    {
      /* second has changed -- draw new second hand */
      DrawHand(hDC, nTime.second,
               hpenBackgnd, SECONDTIP, R2_NOT);
    }

    /* Store most recent time */
    oTime.minute = nTime.minute;
    oTime.hour   = nTime.hour;
    oTime.second = nTime.second;
  }
  GlobalUnlock(hCirTab);
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : DrawFace (HDC)                                              *
 *                                                                         *
 *  PURPOSE  : Draws the clock face.                                       *
 *                                                                         *
 ***************************************************************************/

DrawFace(hDC)
  HDC hDC; /* device context to be used when drawing face */
{
  int    pos;       /* hand position index into the circle table */
  int    dotHeight; /* height of the hour-marking dot            */
  int    dotWidth;  /* width of the hour-marking dot             */
  POINT  dotCenter; /* center point of the hour-marking dot      */
  RECT   rc;

  /* Compute hour-marking dot width, height, and center point */
  dotWidth = (MAXDOTWIDTH * (long) (ClockRect.right - ClockRect.left)) / Horz
  dotHeight = VertEquiv(dotWidth);

  if (dotHeight < MINDOTHEIGHT)
  {
    dotHeight = MINDOTHEIGHT;
  }

  if (dotWidth < MINDOTWIDTH)
  {
    dotWidth = MINDOTWIDTH;
  }

  dotCenter.x = dotWidth >> 1;
  dotCenter.y = dotHeight >> 1;

  /* Compute the clock center and radius */
  InflateRect((LPRECT) &ClockRect, -dotCenter.y, -dotCenter.x);
  ClockRadius = (long) ((ClockRect.right - ClockRect.left) >> 1);
  ClockCenter.x = ClockRect.left + ClockRadius;
  ClockCenter.y = ClockRect.top + ((ClockRect.bottom - ClockRect.top) >> 1);
  InflateRect((LPRECT) &ClockRect, dotCenter.y, dotCenter.x);

  /* Draw the large hour-marking dots and small minute-marking dots */
  for(pos = 0; pos < HANDPOSITIONS; pos++)
  {
    rc.top = (lpCirTab[pos].y * ClockRadius) / CIRTABSCALE + ClockCenter.y;
    rc.left = (lpCirTab[pos].x * ClockRadius) / CIRTABSCALE + ClockCenter.x;
    if (pos % 5)
    {
      if ((dotWidth > MINDOTWIDTH) && (dotHeight > MINDOTHEIGHT))
      {
        /* Draw small minute-marking dot */
        rc.right = rc.left + 1;
        rc.bottom = rc.top + 1;
        FillRect(hDC, (LPRECT) &rc, hbrForegnd);
      }
    }
    else
    {
      /* Draw large hour-marking dot */
      rc.right = rc.left + dotWidth;
      rc.bottom = rc.top + dotHeight;
      OffsetRect((LPRECT) &rc, -dotCenter.x, -dotCenter.y);
      FillRect(hDC, (LPRECT) &rc, hbrForegnd);
      }
  }
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : DrawHand (HDC, int, HPEN, int, int)                         *
 *                                                                         *
 *  PURPOSE  : Draws a thin hand with the specified pen in the specified   *
 *             hand position.                                              *
 *                                                                         *
 ***************************************************************************/

DrawHand(hDC, pos, hPen, scale, patMode)
  HDC  hDC;     /* device context to be used when drawing hand */
  int  pos;     /* hand position index into the circle table   */
  HPEN hPen;    /* pen to be used when drawing hand            */
  int  scale;   /* ClockRadius percentage to scale drawing to  */
  int  patMode; /* pattern mode to be used when drawing hand   */
{
  long radius;

  /* scale length of hand */
  radius = (ClockRadius * scale) / 100;

  /* set pattern mode for hand */
  SetROP2(hDC, patMode);

  /* select pen for hand */
  SelectObject(hDC, hPen);

  /* Draw thin hand */
  MoveTo(hDC, ClockCenter.x, ClockCenter.y);
  LineTo(hDC, ClockCenter.x + (int)((lpCirTab[pos].x * radius) / CIRTABSCALE)
        ClockCenter.y + (int)((lpCirTab[pos].y * radius) / CIRTABSCALE));
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : DrawFatHand (HDC, int, HPEN, BOOL)                          *
 *                                                                         *
 *  PURPOSE  : Draws a fat hand with the specified pen in the specified    *
 *             hand position.                                              *
 *                                                                         *
 ***************************************************************************/

DrawFatHand(hDC, pos, hPen, hHand)
  HDC  hDC;     /* device context to be used when drawing hand */
  int  pos;     /* hand position index into the circle table   */
  HPEN hPen;    /* pen to be used when drawing hand            */
  BOOL hHand;   /* TRUE if drawing hour hand; FALSE otherwise  */
{
  POINT ptTip;  /* coordinates for the tip of the hand        */
  POINT ptTail; /* coordinates for the tail of the hand       */
  POINT ptSide; /* coordinates for the side of the hand       */
  int   index;  /* position index into the circle table       */
  long  scale;  /* ClockRadius percentage to scale drawing to */

  /* set pattern mode for hand */
  SetROP2(hDC, 13);

  /* select pen for hand */
  SelectObject(hDC, hPen);

  /* compute coordinates for the side of the hand */
  scale = (ClockRadius * (hHand ? HOURSIDE : MINUTESIDE)) / 100;
  index = (pos + SIDESHIFT) % HANDPOSITIONS;
  ptSide.y = (lpCirTab[index].y * scale) / CIRTABSCALE;
  ptSide.x = (lpCirTab[index].x * scale) / CIRTABSCALE;

  /* compute coordinates for the tip of the hand */
  scale = (ClockRadius * (hHand ? HOURTIP : MINUTETIP)) / 100;
  ptTip.y = (lpCirTab[pos].y * scale) / CIRTABSCALE;
  ptTip.x = (lpCirTab[pos].x * scale) / CIRTABSCALE;

  /* compute coordinates for the tail of the hand */
  scale = (ClockRadius * (hHand ? HOURTAIL : MINUTETAIL)) / 100;
  index = (pos + TAILSHIFT) % HANDPOSITIONS;
  ptTail.y = (lpCirTab[index].y * scale) / CIRTABSCALE;
  ptTail.x = (lpCirTab[index].x * scale) / CIRTABSCALE;

  /* Draw tip of hand */
  MoveTo(hDC, ClockCenter.x + ptSide.x, ClockCenter.y + ptSide.y);
  LineTo(hDC, ClockCenter.x +  ptTip.x, ClockCenter.y +  ptTip.y);
  MoveTo(hDC, ClockCenter.x - ptSide.x, ClockCenter.y - ptSide.y);
  LineTo(hDC, ClockCenter.x +  ptTip.x, ClockCenter.y +  ptTip.y);

  /* Draw tail of hand */
  MoveTo(hDC, ClockCenter.x + ptSide.x, ClockCenter.y + ptSide.y);
  LineTo(hDC, ClockCenter.x + ptTail.x, ClockCenter.y + ptTail.y);
  MoveTo(hDC, ClockCenter.x - ptSide.x, ClockCenter.y - ptSide.y);
  LineTo(hDC, ClockCenter.x + ptTail.x, ClockCenter.y + ptTail.y);
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : CircleClock (int, int)                                      *
 *                                                                         *
 *  PURPOSE  : Resizes the clock rectangle to keep the face circular.      *
 *                                                                         *
 ***************************************************************************/

CircleClock(maxWidth, maxHeight)
  int maxWidth;    /* the maximum width of the clock face         */
  int maxHeight;   /* the maximum height of the clock face        */
{
  int clockHeight; /* tallest height that will keep face circular */
  int clockWidth;  /* widest width that will keep face circular   */

  if (maxWidth > HorzEquiv(maxHeight))
  {
    /* too wide -- decrease width to keep face circular */
    clockWidth = HorzEquiv(maxHeight);
    ClockRect.left += (maxWidth - clockWidth) >> 1;
    ClockRect.right = ClockRect.left + clockWidth;
  }
  else
  {
    /* too tall -- decrease height to keep face circular */
    clockHeight = VertEquiv(maxWidth);
    ClockRect.top += (maxHeight - clockHeight) >> 1;
    ClockRect.bottom = ClockRect.top + clockHeight;
  }
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : WinMain (HANDLE, HANDLE, LPSTR, int)                        *
 *                                                                         *
 *  PURPOSE  : Calls the initialization function, creates the main appli-  *
 *             cation window, and enters the message loop.                 *
 *                                                                         *
 ***************************************************************************/

int PASCAL WinMain(hInstance, hPrev, lpszCmdLine, cmdShow)
  HANDLE hInstance;
  HANDLE hPrev;
  LPSTR  lpszCmdLine;
  int    cmdShow;
{
  HWND  hWnd;
  MSG   msg;
  HMENU hMenu;
  TIME  nTime;
  int   sysWidth;  /* width of left and right frames                  */
  int   sysHeight; /* height of caption bar and top and bottom frames */
  int   width;     /* width of entire clock window                    */
  int   height;    /* height of entire clock window                   */

  hInst = hInstance;

  LoadString(hInst, IDS_APPNAME, (LPSTR) szBuffer, BUFLEN);

  if (!hPrev)
  {
    /* First instance -- register window class */
    if (!ClockInit())
      return(FALSE);
        }
  else
  {
    /* Not first instance -- get circle table and reset bFirst flag */
    GetInstanceData(hPrev, (PSTR) &hCirTab, sizeof(HANDLE));
    bFirst = FALSE;
        }

  ClockCreate();

  /* compute window height and width */
  sysWidth  = GetSystemMetrics(SM_CXFRAME) * 2;
  sysHeight = GetSystemMetrics(SM_CYCAPTION) + (GetSystemMetrics(SM_CYFRAME)
  width = (HorzRes / 3) + sysWidth;
  height = VertEquiv(width) + sysHeight;

  hWnd = CreateWindow( (LPSTR) szBuffer, /* class name              */
                             (LPSTR) szBuffer, /* The window name         */
                             WS_TILEDWINDOW,   /* window style            */
                             CW_USEDEFAULT,    /* use default positioning */
                             0,                /* y not used              */
                             width,            /* window width            */
           height,           /* window height           */
                             NULL,             /* NULL parent handle      */
                             NULL,             /* NULL menu/child handle  */
                             hInst,            /* program instance        */
                             NULL              /* NULL data structure ref.*/
         );

  GetTime(&nTime);
  GetTime(&oTime);
  while ((nTime.second == oTime.second) &&
               (nTime.minute == oTime.minute) &&
               (nTime.hour   == oTime.hour)     )
  {
    GetTime(&oTime);
  }

  if (!SetTimer(hWnd, TimerID, OPEN_TLEN, 0L))
  {
    LPSTR szTooMany;

    /* 16 public timers already in use -- post error and exit */
    szTooMany = (LPSTR)(unsigned long) LocalAlloc(LPTR, 40);
    LoadString(hInst, IDS_TOOMANY, szTooMany, 40);
    MessageBox((HWND) NULL, szTooMany, (LPSTR) szBuffer,
         MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
    DeleteTools();
    return(FALSE);
  }

  /* Add the "About..." menu item to the bottom of the system menu */
  LoadString(hInst, IDS_ABOUTMENU, (LPSTR) szBuffer, BUFLEN);
  hMenu = GetSystemMenu(hWnd, FALSE);
  ChangeMenu(hMenu, 0, (LPSTR) szBuffer, IDM_ABOUT, MF_APPEND | MF_STRING);

  ShowWindow(hWnd, cmdShow);

  /* Process messages until program termination */
  while (GetMessage((LPMSG) &msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) &msg);
    DispatchMessage((LPMSG) &msg);
  }
  return(msg.wParam);
}


/***************************************************************************
 *                                                                         *
 *  FUNCTION : ClockInit ()                                                *
 *                                                                         *
 *  PURPOSE  : Registers the applicatoin windwo class and initializes the  *
 *             circle values for the clock face.                           *
 *                                                                         *
 ***************************************************************************/

ClockInit()
{
  PWNDCLASS pClockClass;
  HANDLE    hRes;
  char      szData[5];

  pClockClass = (PWNDCLASS) LocalAlloc(LPTR, sizeof(WNDCLASS));

  pClockClass->lpszClassName = (LPSTR) szBuffer;
  pClockClass->hbrBackground = (HBRUSH) NULL;
  pClockClass->style         = CS_VREDRAW | CS_HREDRAW | CS_BYTEALIGNCLIENT;
  pClockClass->hInstance     = hInst;
  pClockClass->lpfnWndProc   = ClockWndProc;
  pClockClass->hCursor       = LoadCursor(NULL, IDC_ARROW);
  pClockClass->hIcon         = NULL;

  if (!RegisterClass((LPWNDCLASS) pClockClass))
  {
    /* Error registering class -- return */
    return(FALSE);
  }

  LocalFree((HANDLE) pClockClass);

  /* Load in pre-computed circle table cosine values from resource file */
  LoadString(hInst, IDS_DATA, (LPSTR) szData, 5);
  hRes = FindResource(hInst, (LPSTR) szBuffer, (LPSTR) szData);
  if (!hRes)
  {
    /* Could not find circle table resource data -- return */
    return(FALSE);
  }

  hCirTab = LoadResource(hInst, hRes);
  LockResource(hCirTab);

  return(TRUE);
}


CURSOR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\CURSOR\CURSOR.C

/****************************************************************************

    PROGRAM: Cursor.c

    PURPOSE: Demonstrates how to manipulate a cursor and select a region

    FUNCTIONS:

  WinMain() - calls initialization function, processes message loop
  InitApplication() - initializes window data and registers window
  InitInstance() - saves instance handle and creates main window
  MainWndProc() - processes messages
  About() - processes messages for "About" dialog box
        sieve() - time consuming function, generates primes

****************************************************************************/

#include "windows.h"
#include "cursor.h"

HANDLE hInst;

char str[255];                              /* general-purpose string buffer

HCURSOR hSaveCursor;                        /* handle to current cursor
HCURSOR hHourGlass;                         /* handle to hourglass cursor

BOOL bTrack = FALSE;                        /* TRUE if left button clicked
int OrgX = 0, OrgY = 0;                     /* original cursor position
int PrevX = 0, PrevY = 0;                   /* current cursor position
int X = 0, Y = 0;                           /* last cursor position
RECT Rect;                                  /* selection rectangle

POINT ptCursor;                             /* x and y coordinates of cursor
int repeat = 1;                             /* repeat count of keystroke

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
  if (!InitApplication(hInstance))
      return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    MessageBox (
          GetFocus ()
        , "Use the mouse button in this program for an example of graphics "
                        "selection, or the <Enter> key for an example of "
                        "using a special cursor to reflect a program state."
        , "Cursor Sample Application"
        , MB_ICONASTERISK | MB_OK
    );

    while (GetMessage(&msg, NULL, NULL, NULL)) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(hInstance, "bullseye");
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "CursorMenu";
    wc.lpszClassName = "CursorWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    HWND            hWnd;

    hInst = hInstance;

    strcpy(str,"");

    hHourGlass = LoadCursor(NULL, IDC_WAIT);

    hWnd = CreateWindow(
        "CursorWClass",
        "Cursor Sample Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
        return (FALSE);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

  WM_COMMAND     - application menu (About dialog box)
        WM_CHAR        - ASCII key value received
        WM_LBUTTONDOWN - left mouse button
        WM_MOUSEMOVE   - mouse movement
        WM_LBUTTONUP   - left button released
        WM_KEYDOWN     - key pressed
        WM_KEYUPS      - key released
        WM_PAINT       - update window
  WM_DESTROY     - destroy window

    COMMENTS:

        When the left mouse button is pressed, btrack is set to TRUE so that
        the code for WM_MOUSEMOVE will keep track of the mouse and update
        the box accordingly.  Once the button is released, btrack is set to
        FALSE, and the current position is saved.  Holding the SHIFT key
        while pressing the left button will extend the current box rather
        then erasing it and starting a new one.

        When an arrow key is pressed, the cursor is repositioned in the
        direction of the arrow key.  A repeat count is kept so that the
        longer the user holds down the arrow key, the faster it will move.
        As soon as the key is released, the repeat count is set to 1 for
        normal cursor movement.

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout;
    HDC hDC;

    switch (message) {
  case WM_COMMAND:
      if (wParam == IDM_ABOUT) {
    lpProcAbout = MakeProcInstance(About, hInst);

    DialogBox(hInst,
        "AboutBox",
        hWnd,
        lpProcAbout);

    FreeProcInstance(lpProcAbout);
    break;
      }
      else
    return (DefWindowProc(hWnd, message, wParam, lParam));

        case WM_CHAR:
            if (wParam == '\r') {
                SetCapture(hWnd);

                /* Set the cursor to an hourglass */

                hSaveCursor = SetCursor(hHourGlass);

                strcpy (str, "Calculating prime numbers...");
                InvalidateRect (hWnd, NULL, TRUE);
                UpdateWindow (hWnd);
                wsprintf(str, "Calculated %d primes.       ", sieve());
                InvalidateRect (hWnd, NULL, TRUE);
                UpdateWindow (hWnd);

                SetCursor(hSaveCursor);          /* Restores previous cursor
                ReleaseCapture();
            }
            break;

        case WM_LBUTTONDOWN:
            bTrack = TRUE;
            strcpy (str, "");
            PrevX = LOWORD(lParam);
            PrevY = HIWORD(lParam);
            if (!(wParam & MK_SHIFT)) {       /* If shift key is not pressed
                OrgX = LOWORD(lParam);
                OrgY = HIWORD(lParam);
            }
            InvalidateRect (hWnd, NULL, TRUE);
            UpdateWindow (hWnd);

            /* Capture all input even if the mouse goes outside of window */

            SetCapture(hWnd);
            break;

        case WM_MOUSEMOVE:
            {
                RECT        rectClient;
                int         NextX;
                int         NextY;

                if (bTrack) {
                    NextX = LOWORD(lParam);
                    NextY = HIWORD(lParam);

                    /* Do not draw outside the window's client area */

                    GetClientRect (hWnd, &rectClient);
                    if (NextX < rectClient.left) {
                        NextX = rectClient.left;
                    } else if (NextX >= rectClient.right) {
                        NextX = rectClient.right - 1;
                    }
                    if (NextY < rectClient.top) {
                        NextY = rectClient.top;
                    } else if (NextY >= rectClient.bottom) {
                        NextY = rectClient.bottom - 1;
                    }

                    /* If the mouse position has changed, then clear the */
                    /* previous rectangle and draw the new one.          */

                    if ((NextX != PrevX) || (NextY != PrevY)) {
                        hDC = GetDC(hWnd);
                        SetROP2(hDC, R2_NOT);          /* Erases the previous
                        MoveTo(hDC, OrgX, OrgY);
                        LineTo(hDC, OrgX, PrevY);
                        LineTo(hDC, PrevX, PrevY);
                        LineTo(hDC, PrevX, OrgY);
                        LineTo(hDC, OrgX, OrgY);

                        /* Get the current mouse position */

                        PrevX = NextX;
                        PrevY = NextY;
                        MoveTo(hDC, OrgX, OrgY);        /* Draws the new box
                        LineTo(hDC, OrgX, PrevY);
                        LineTo(hDC, PrevX, PrevY);
                        LineTo(hDC, PrevX, OrgY);
                        LineTo(hDC, OrgX, OrgY);
                        ReleaseDC(hWnd, hDC);
                    }
                }
            }
            break;

        case WM_LBUTTONUP:
      bTrack = FALSE;        /* No longer creating a selection */
      ReleaseCapture();        /* Releases hold on mouse input */

      X = LOWORD(lParam);       /* Saves the current value      */
            Y = HIWORD(lParam);
            break;

        case WM_KEYDOWN:
            if (wParam != VK_LEFT && wParam != VK_RIGHT
                    && wParam != VK_UP && wParam != VK_DOWN)
                break;

            GetCursorPos(&ptCursor);

            /* Convert screen coordinates to client coordinates */

            ScreenToClient(hWnd, &ptCursor);
            repeat++;                           /* Increases the repeat rate

            switch (wParam) {

            /* Adjust cursor position according to which key was pressed. */

                case VK_LEFT:
                    ptCursor.x -= repeat;
                    break;

                case VK_RIGHT:
                    ptCursor.x += repeat;
                    break;

                case VK_UP:
                    ptCursor.y -= repeat;
                    break;

                case VK_DOWN:
                    ptCursor.y += repeat;
                    break;

            }

            /* Get the client boundaries */

            GetClientRect(hWnd, &Rect);

            /* Do not draw outside the window's client area */

            if (ptCursor.x >= Rect.right)
                ptCursor.x = Rect.right - 1;
            else if (ptCursor.x < Rect.left)
                ptCursor.x = Rect.left;
            if (ptCursor.y >= Rect.bottom)
                ptCursor.y = Rect.bottom - 1;
            else if (ptCursor.y < Rect.top)
                ptCursor.y = Rect.top;

            /* Convert the coordinates to screen coordinates */

            ClientToScreen(hWnd, &ptCursor);
            SetCursorPos(ptCursor.x, ptCursor.y);
            break;

        case WM_KEYUP:
            repeat = 1;                          /* Clears the repeat count.
            break;

        case WM_ACTIVATE:
            if (!GetSystemMetrics(SM_MOUSEPRESENT)) {
                if (!HIWORD(lParam)) {
                    if (wParam) {
                        SetCursor(LoadCursor(hInst, "bullseye"));
                        ptCursor.x = X;
                        ptCursor.y = Y;
                        ClientToScreen(hWnd, &ptCursor);
                        SetCursorPos(ptCursor.x, ptCursor.y);
                    }
                    ShowCursor(wParam);
                }
            }
            break;

        case WM_PAINT:
            {
                PAINTSTRUCT     ps;

                hDC = BeginPaint (hWnd, &ps);
                if (OrgX != PrevX || OrgY != PrevY) {
                    MoveTo(hDC, OrgX, OrgY);
                    LineTo(hDC, OrgX, PrevY);
                    LineTo(hDC, PrevX, PrevY);
                    LineTo(hDC, PrevX, OrgY);
                    LineTo(hDC, OrgX, OrgY);
                }
                TextOut (hDC, 1, 1, str, strlen (str));
                EndPaint (hWnd, &ps);
            }
            break;

  case WM_DESTROY:
      PostQuitMessage(0);
      break;

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


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}


/****************************************************************************

    FUNCTION: Sieve()

    PURPOSE:  Example of time consuming process

    COMMENTS:

  Sieve of Eratosthenes, BYTE, Volume 8, Number 1, by Jim Gilbreath
  and Gary Gilbreath.  Code changed to give correct results.

  One could return the count, and after restoring the cursor, use
  sprintf() to copy the information to a string which could then be
  put up in a MessageBox().

****************************************************************************/

 NITER  20           /* number of iterations */
#define SIZE  8190

char flags[SIZE+1]={ 0};

sieve() {
    int i,k;
    int iter, count;

    for (iter = 1; iter <= NITER; iter++) {   /* Does sieve NITER times */
  count = 0;
  for (i = 0; i <= SIZE; i++)     /* Sets all flags TRUE     */
      flags[i] = TRUE;

  for (i = 2; i <= SIZE; i++) {
      if (flags[i] ) {          /* Found a prime?      */
    for (k = i + i; k <= SIZE; k += i)
        flags[k] = FALSE;       /* Cancelsits multiples */
    count++;
      }
  }
    }
    return (count);
}


DEFDLG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\DEFPROCS\DEFDLG.C


/*--------------------------------------------------------------------------*
/*                      */
/*  DefDlgProc() -                  */
/*                      */
/*--------------------------------------------------------------------------*

LONG FAR PASCAL DefDlgProc(hwnd, message, wParam, lParam)

register HWND hwnd;
register WORD message;
WORD        wParam;
LONG        lParam;

{
  HWND        hwndT1;
  HWND        hwndT2;
  int        result;

  if (!CheckHwnd(hwnd))
      return(NULL);

  ((PDLG)hwnd)->resultWP = 0L;

  if (((PDLG)hwnd)->lpfnDlg == NULL ||
      !(result = (*((PDLG)hwnd)->lpfnDlg)(hwnd, message, wParam, lParam)))
    {
      switch (message)
  {
    case WM_ERASEBKGND:
        FillWindow(hwnd, hwnd, (HDC)wParam, (HBRUSH)CTLCOLOR_DLG);
        return((LONG)TRUE);

    case WM_SHOWWINDOW:
        /* If hiding the window, save the focus. If showing the window
         * by means of a SW_* command and the fEnd bit is set, do not
         * pass to DWP so it won't get shown.
         */
        if (!wParam && ((PDLG)hwnd)->hwndFocusSave == NULL)
      ((PDLG)hwnd)->hwndFocusSave = hwndFocus;
        else if (LOWORD(lParam) != 0 && ((PDLG)hwnd)->fEnd)
      break;
        goto CallDWP;

    case WM_ACTIVATE:
        fDialog = FALSE;
        if (wParam)
    {
      fDialog = TRUE;
      if (((PDLG)hwnd)->hwndFocusSave)
        {
          SetFocus(((PDLG)hwnd)->hwndFocusSave);

          /* Set to NULL so we don't reset if we get more than
       one activate message. */
          ((PDLG)hwnd)->hwndFocusSave = NULL;
        }
    }
        else if (hwndFocus && IsChild(hwnd, hwndFocus) &&
           ((PDLG)hwnd)->hwndFocusSave == NULL)
    {
      /* Must remember focus if deactivated */
      ((PDLG)hwnd)->hwndFocusSave = hwndFocus;
    }
        break;

    case WM_SETFOCUS:
              if (!((PDLG)hwnd)->fEnd)
                  /* Don't set the focus if we are ending this dialog box
       */
              DlgSetFocus(GetFirstTab(hwnd));
        break;

    case WM_CLOSE:
        /* Make sure cancel button is not disabled before sending the
         * IDCANCEL.  Note that we need to do this as a message instead
         * of directly calling the dlg proc so that any dialog box
         * filters get this.
         */
        hwndT1 = GetDlgItem(hwnd, IDCANCEL);
        if (hwndT1 && TestWF(hwndT1, WFDISABLED))
      MessageBeep(0);
        else
      PostMessage(hwnd, WM_COMMAND, IDCANCEL, 0L);
        break;

    case WM_NCDESTROY:
              fDialog = FALSE;      /* clear this flag */
        if (!(hwnd->style & DS_LOCALEDIT))
    {
      if (((PDLG)hwnd)->hData)
        {
          GlobalUnWire(((PDLG)hwnd)->hData);
          ReleaseEditDS(((PDLG)hwnd)->hData);
        }
    }
        /* Delete the user defined font if any */
        if (((PDLG)hwnd)->hUserFont)
      DeleteObject(((PDLG)hwnd)->hUserFont);

        /* Gotta let DefWindowProc do its thing here or we won't
         * get all of the little chunks of memory freed for this
         * window (szName and rgwScroll).
         */
        DefWindowProc(hwnd, message, wParam, lParam);
        break;

    case DM_SETDEFID:
              if (!(((PDLG)hwnd)->fEnd) && (((PDLG)hwnd)->result != wParam))
                {
                  /* Make sure that the new default button has the highlight.
       * We need to blow this off if we are ending the dialog box
       * because hwnd->result is no longer a default window id but
       * rather the return value of the dialog box.
       */
                  /* Catch the case of setting the defid to null or setting
       * the defid to something else when it was initially null.
       */
                  CheckDefPushButton(hwnd,
                       (((PDLG)hwnd)->result ?
                                     GetDlgItem(hwnd, ((PDLG)hwnd)->result) :
                                     NULL),
                       (wParam ? GetDlgItem(hwnd, wParam) : NULL));
               ((PDLG)hwnd)->result = wParam;
                }
        return(TRUE);

    case DM_GETDEFID:
        return(MAKELONG(((PDLG)hwnd)->result, DC_HASDEFID));

    /* This message was added so that user defined controls that want
     * tab keys can pass the tab off to the next/previous control in the
     * dialog box.  Without this, all they could do was set the focus
     * which didn't do the default button stuff.
     */
    case WM_NEXTDLGCTL:
        hwndT2 = hwndFocus;
        if (LOWORD(lParam))
    {
      if (hwndT2 == NULL)
          hwndT2 = hwnd;

      /* wParam contains the hwnd of the ctl to set focus to. */
      hwndT1 = (HWND)wParam;
    }
        else
    {
      if (hwndT2 == NULL)
        {
          /* Set focus to the first tab item. */
          hwndT1 = GetFirstTab(hwnd);
          hwndT2 = hwnd;
        }
      else
        {
          /* If window with focus not a dlg ctl, ignore message. */
          if (!IsChild(hwnd, hwndT2))
        return(TRUE);

          /* wParam = TRUE for previous, FALSE for next */
          hwndT1 = GetNextDlgTabItem(hwnd, hwndT2, wParam);
        }
    }

        DlgSetFocus(hwndT1);
        CheckDefPushButton(hwnd, hwndT2, hwndT1);
        return(TRUE);

    case WM_LBUTTONDOWN:
    case WM_NCLBUTTONDOWN:
        hwndT1 = hwndFocus;
        if (hwndT1->pcls->lpfnWndProc == ComboBoxCtlWndProc)
      /* If user clicks anywhere in dialog box and a combo box (or
       * the editcontrol of a combo box) has the focus, then hide
       * it's listbox.
       */
      SendMessage(hwndT1,CB_SHOWDROPDOWN, FALSE, 0L);
        else
        if (hwndT1->pcls->lpfnWndProc == EditWndProc &&
      hwndT1->hwndParent->pcls->lpfnWndProc==ComboBoxCtlWndProc)
    {
      SendMessage(hwndT1->hwndParent,CB_SHOWDROPDOWN, FALSE, 0L);
    }
        /* Always send the message off to DefWndProc */
        goto CallDWP;

    case WM_GETFONT:
        return(((PDLG)hwnd)->hUserFont);

    case WM_VKEYTOITEM:
    case WM_COMPAREITEM:
    case WM_CHARTOITEM:
        /* We need to return the 0 the app may have returned for these
         * items instead of calling defwindow proc.
         */
        return(result);

    default:
CallDWP:
        return(DefWindowProc(hwnd, message, wParam, lParam));
  }
    }

  /* Must return brush which apps dlgfn returns. */
  if (message == WM_CTLCOLOR ||
      message == WM_COMPAREITEM ||
      message == WM_VKEYTOITEM ||
      message == WM_CHARTOITEM)
      return(result);

  return(((PDLG)hwnd)->resultWP);
}


DEFWND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\DEFPROCS\DEFWND.C

/*--------------------------------------------------------------------------*
/*                      */
/*  DefWindowProc() -                  */
/*                      */
/*--------------------------------------------------------------------------*

LONG FAR PASCAL DefWindowProc(hwnd, message, wParam, lParam)

register HWND hwnd;
WORD        message;
register WORD wParam;
LONG        lParam;

{
  int        i;
  HDC        hdc;
  PAINTSTRUCT ps;
  HICON        hIcon;
  RECT        rc;
  HANDLE      hCurs;
  HBRUSH      hbr;
  HWND        hwndT;

  if (!CheckHwnd(hwnd))
      return((DWORD)FALSE);

  switch (message)
    {
      case WM_NCACTIVATE:
    if (wParam != 0)
        SetWF(hwnd, WFFRAMEON);
    else
        ClrWF(hwnd, WFFRAMEON);

    if (TestWF(hwnd, WFVISIBLE) && !TestWF(hwnd, WFNONCPAINT))
      {
        hdc = GetWindowDC(hwnd);
        DrawCaption(hwnd, hdc, TRUE, TestWF(hwnd, WFFRAMEON));
        InternalReleaseDC(hdc);
        if (TestWF(hwnd,WFMINIMIZED))
      RedrawIconTitle(hwnd);
      }
    return(TRUE);

      case WM_NCHITTEST:
    return(FindNCHit(hwnd, lParam));

      case WM_NCCALCSIZE:
    CalcClientRect(hwnd, (LPRECT)lParam);
    break;

      case WM_NCLBUTTONDOWN:
  {
    WORD       cmd;
    RECT       rcWindow;
    RECT       rcCapt;
    RECT       rcInvert;
    RECT       rcWindowSave;

    cmd = 0;

    switch(wParam)
      {
        case HTZOOM:
        case HTREDUCE:
      GetWindowRect(hwnd, (LPRECT)&rcWindow);
      CopyRect((LPRECT)&rcWindowSave, (LPRECT)&rcWindow);

      if (TestWF(hwnd, WFSIZEBOX))
          InflateRect((LPRECT)&rcWindow,
                -cxSzBorderPlus1, -cySzBorderPlus1);
      else
          InflateRect((LPRECT)&rcWindow, -cxBorder, -cyBorder);

      rcCapt.right = rcWindow.right + cxBorder;
                  rcCapt.left = rcWindow.right - oemInfo.bmReduce.cx-cxBorder

      if (wParam == HTREDUCE)
          cmd = SC_MINIMIZE;
      else if (TestWF(hwnd, WFMAXIMIZED))
          cmd = SC_RESTORE;
      else
          cmd = SC_MAXIMIZE;

      if (wParam == HTREDUCE && TestWF(hwnd, WFMAXBOX))
                      OffsetRect((LPRECT)&rcCapt, -oemInfo.bmReduce.cx, 0);

      rcCapt.top = rcWindow.top;
      rcCapt.bottom = rcCapt.top + cyCaption;

      CopyRect((LPRECT)&rcInvert, (LPRECT)&rcCapt);
                  InflateRect((LPRECT)&rcInvert, -cxBorder, -cyBorder);

                  rcInvert.right += cxBorder;
      rcInvert.left += cxBorder;

      /* Converting to window coordinates. */
      OffsetRect((LPRECT)&rcInvert,
           -(rcWindowSave.left + cxBorder),
           -(rcWindowSave.top + cyBorder));
      /* Wait for the BUTTONUP message and see if cursor is still
       * in the Minimize or Maximize box.
       *
       * NOTE: rcInvert is in window coords, rcCapt is in screen
       * coords
       */
                  if (!DepressTitleButton(hwnd, rcCapt, rcInvert, wParam))
          cmd = 0;

      break;

        default:
      if (wParam >= HTSIZEFIRST && wParam <= HTSIZELAST)
          /* Change HT into a MV command. */
          cmd = SC_SIZE + (wParam - HTSIZEFIRST + MVSIZEFIRST);
      }

    if (cmd != 0)
      {
        /* For SysCommands on system menu, don't do if
         * menu item is disabled.
         */
        if (TestWF(hwnd, WFSYSMENU))
    {
                  /* don't check old app child windows
       */
      if (LOWORD(GetExpWinVer(hwnd->hInstance)) >= VER ||
          !TestwndChild(hwnd))
        {
          SetSysMenu(hwnd);
          if (GetMenuState(GetSysMenuHandle(hwnd), cmd & 0xFFF0,
        MF_BYCOMMAND) & (MF_DISABLED | MF_GRAYED))
        break;
        }
    }
        SendMessage(hwnd, WM_SYSCOMMAND, cmd, lParam);
        break;
      }
    /*** FALL THRU ***/
  }

      case WM_NCMOUSEMOVE:
      case WM_NCLBUTTONUP:
      case WM_NCLBUTTONDBLCLK:
    HandleNCMouseGuys(hwnd, message, wParam, lParam);
    break;

      case WM_CANCELMODE:
    if (hwndCapture == hwnd && pfnSB != NULL)
        EndScroll(hwnd, TRUE);

          if (fMenu && hwndMenu == hwnd)
              EndMenu();

    /* If the capture is still set, just release at this point.
     * Can put other End* functions in later.
     */
    if (hwnd == hwndCapture)
        ReleaseCapture();
    break;

      case WM_NCCREATE:
    if (TestWF(hwnd, (WFHSCROLL | WFVSCROLL)))
        if (InitPwSB(hwnd) == NULL)
      return((LONG)FALSE);

    return((LONG)DefSetText(hwnd, ((LPCREATESTRUCT)lParam)->lpszName));

      case WM_NCDESTROY:
    if (hwnd->hName)
        hwnd->hName = TextFree(hwnd->hName);
    break;

      case WM_NCPAINT:
    /* Force the drawing of the menu. */
    SetWF(hwnd, WFMENUDRAW);
    DrawWindowFrame(hwnd, (HRGN)wParam);
    ClrWF(hwnd, WFMENUDRAW);
    break;

      case WM_SETTEXT:
    DefSetText(hwnd, (LPSTR)lParam);
    if (TestWF(hwnd, WFVISIBLE))
            {
        if (TestWF(hwnd,WFMINIMIZED))
    {
      ShowIconTitle(hwnd,FALSE);
      ShowIconTitle(hwnd,TRUE);
    }
        else if (TestWF(hwnd, WFBORDERMASK) == (BYTE)LOBYTE(WFCAPTION))
    {
      hdc = GetWindowDC(hwnd);
      DrawCaption(hwnd, hdc, FALSE, TestWF(hwnd, WFFRAMEON));
      InternalReleaseDC(hdc);
    }
            }
    break;

      case WM_GETTEXT:
    if (wParam)
            {
              if (hwnd->hName)
            return (DWORD)TextCopy(hwnd->hName,(LPSTR)lParam,wParam);

              /* else Null terminate the text buffer since there is no text.
         */
        ((LPSTR)lParam)[0] = NULL;
            }
    return (0L);


      case WM_GETTEXTLENGTH:
    if (hwnd->hName)
        return(lstrlen(TextPointer(hwnd->hName)));

          /* else */
          return(0L);

      case WM_CLOSE:
    DestroyWindow(hwnd);
    break;

      case WM_PAINT:
    BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
    EndPaint(hwnd, (LPPAINTSTRUCT)&ps);
    break;

      case WM_PAINTICON:
          /* Draw the icon through the window DC if app used own DC. If own D
     * is used the mapping mode may not be MM_TEXT.
     */
          BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
          if (TestCF(hwnd, CFOWNDC) || TestCF(hwnd, CFCLASSDC))
            {
              /* If owndc, do the end paint now so that the
         * erasebackgrounds/validate regions go through properly. Then
         * we get a clean window dc to draw the icon into.
         */
              InternalEndPaint(hwnd, (LPPAINTSTRUCT)&ps, TRUE);
              hdc = GetWindowDC(hwnd);
            }
          else
            {
              hdc = ps.hdc;
            }

    /* wParam is TRUE to draw icon, FALSE to ignore paint. */
    if (wParam)
      {
              hIcon = (HICON)(PCLS)(hwnd->pcls)->hIcon;
              GetClientRect(hwnd, (LPRECT)&rc);

              rc.left = (rc.right - rgwSysMet[SM_CXICON]) >> 1;
        rc.top = (rc.bottom - rgwSysMet[SM_CYICON]) >> 1;

        DrawIcon(hdc, rc.left, rc.top, hIcon);
      }

    /* Delete the update region. */
          if (TestCF(hwnd, CFOWNDC) || TestCF(hwnd, CFCLASSDC))
            {
              InternalReleaseDC(hdc);
              /* ValidateRect(hwnd, NULL); */
            }
          else
              InternalEndPaint(hwnd, (LPPAINTSTRUCT)&ps, TRUE);
    break;

      case WM_ICONERASEBKGND:
          /* Erase the icon through the window DC if app used own DC. If own
     * DC is used the mapping mode may not be MM_TEXT.
     */
          if (TestCF(hwnd, CFOWNDC) || TestCF(hwnd, CFCLASSDC))
          hdc = GetWindowDC(hwnd);
          else
           hdc = (HDC)wParam;

          if (TestWF(hwnd, WFCHILD))    /* for MDI child icons */
            {
              if ((hbr = GetBackBrush(hwnd->hwndParent)) == NULL)
    {
                  /* No brush, punt. */
                  goto AbortIconEraseBkGnd;
                }
              else
                  goto ICantBelieveIUsedAGoToStatement;
      }

    if (hbmWallpaper)
            {
              /* Since desktop bitmaps are done on a wm_paint message (and no
         * erasebkgnd), we need to call the paint proc with our dc
         */
              PaintDesktop(hdc);
              /* SendMessage(hwndDesktop, WM_ERASEBKGND, hdc, 0L);*/
            }
    else
      {
        hbr = sysClrObjects.hbrDesktop;
ICantBelieveIUsedAGoToStatement:
        FillWindow(hwnd->hwndParent,hwnd,hdc,hbr);
      }

AbortIconEraseBkGnd:
          if (TestCF(hwnd, CFOWNDC) || TestCF(hwnd, CFCLASSDC))
          InternalReleaseDC(hdc);

    return((LONG)TRUE);

      case WM_ERASEBKGND:
    if ((hbr = GetBackBrush(hwnd)) != NULL)
      {
        FillWindow(hwnd, hwnd, (HDC)wParam, hbr);
        return((LONG)TRUE);
      }
    break;

      case WM_QUERYOPEN:
      case WM_QUERYENDSESSION:
    return((LONG)TRUE);

      case WM_SYSCOMMAND:
    SysCommand(hwnd, wParam, lParam);
    break;

      case WM_KEYDOWN:
    if (wParam == VK_F10)
        fF10Status = TRUE;
    break;

      case WM_SYSKEYDOWN:
    /* Is the ALT key down? */
    if (HIWORD(lParam) & SYS_ALTERNATE)
      {
        /* Toggle the fMenuStatus iff this is NOT a repeat KEYDOWN
         * message; Only if the prev key state was 0, then this is the
         * first KEYDOWN message and then we consider toggling menu
               * status;
         */
        if((HIWORD(lParam) & SYS_PREVKEYSTATE) == 0)
          {
            /* Don't have to lock hwndActive because it's processing this
         key. */
            if ((wParam == VK_MENU) && (!fMenuStatus))
          fMenuStatus = TRUE;
            else
          fMenuStatus = FALSE;
    }

        fF10Status = FALSE;

        DWP_ProcessVirtKey(wParam);
      }
    else
      {
        if (wParam == VK_F10)
      fF10Status = TRUE;
        else
    {
      if (wParam == VK_ESCAPE)
        {
          if(GetKeyState(VK_SHIFT) < 0)
               SendMessage(hwnd, WM_SYSCOMMAND,
               SC_KEYMENU, (DWORD)MENUSYSMENU);
        }
    }
      }
    break;

      case WM_KEYUP:
      case WM_SYSKEYUP:
    /* press and release F10 or ALT.Send this only to top-level windows,
     * otherwise MDI gets confused.  The fix in which DefMDIChildProc()
     * passed up the message was insufficient in the case a child window
     * of the MDI child had the focus.
     */
    if ((wParam == VK_MENU && (fMenuStatus == TRUE)) ||
        (wParam == VK_F10 && fF10Status) )
        SendMessage(GetTopLevelWindow(hwnd), WM_SYSCOMMAND, SC_KEYMENU,
      (DWORD)0);

    fF10Status = fMenuStatus = FALSE;
    break;

      case WM_SYSCHAR:
    /* If syskey is down and we have a char... */
    fMenuStatus = FALSE;
    if ((HIWORD(lParam) & SYS_ALTERNATE) && wParam)
      {
        if (wParam == VK_TAB || wParam == VK_ESCAPE)
      break;

        /* Send ALT-SPACE only to top-level windows. */
        if ((wParam == MENUSYSMENU) && (TestwndChild(hwnd)))
      SendMessage(hwnd->hwndParent, message, wParam, lParam);
        else
      SendMessage(hwnd, WM_SYSCOMMAND, SC_KEYMENU, (DWORD)wParam);
      }
    else
        /* Ctrl-Esc produces a WM_SYSCHAR, But should not beep; */
        if(wParam != VK_ESCAPE)
            MessageBeep(0);
    break;

      case WM_CHARTOITEM:
      case WM_VKEYTOITEM:
          /* Do default processing for keystrokes into owner draw
             listboxes. */
          return(-1);


      case WM_ACTIVATE:
    if (wParam)
        SetFocus(hwnd);
    break;

      case WM_SETREDRAW:
    DWP_SetRedraw(hwnd, wParam);
    break;

      case WM_SHOWWINDOW:
    /* Non null descriptor implies popup hide or show. */
    /* We should check whether it is a popup window or Owned window */
    if (LOWORD(lParam) != 0 && (TestwndPopup(hwnd) || hwnd -> hwndOwner))
      {
        /* IF NOT(showing, invisible, and not set as hidden) AND
         *   NOT(hiding and not visible)
         */
        if (!(wParam != 0 && !TestWF(hwnd, WFVISIBLE) &&
      !TestWF(hwnd, WFHIDDENPOPUP)) &&
      !(wParam == 0 && !TestWF(hwnd, WFVISIBLE)))
    {
      /* Are we showing? */
      if (wParam)
          /* Yes, clear the hidden popup flag. */
          ClrWF(hwnd, WFHIDDENPOPUP);
      else
          /* No, Set the hidden popup flag. */
          SetWF(hwnd, WFHIDDENPOPUP);

      ShowWindow(hwnd,
           (wParam ? SHOW_OPENNOACTIVATE : HIDE_WINDOW));
    }
      }
    break;

      case WM_CTLCOLOR:
    if (HIWORD(lParam) != CTLCOLOR_SCROLLBAR)
      {
        SetBkColor((HDC)wParam, sysColors.clrWindow);
        SetTextColor((HDC)wParam, sysColors.clrWindowText);
        hbr = sysClrObjects.hbrWindow;
      }
    else
      {
              SetBkColor((HDC)wParam, 0x00ffffff);
              SetTextColor((HDC)wParam, (LONG)0x00000000);
        hbr = sysClrObjects.hbrScrollbar;
        UnrealizeObject(hbr);
      }

    return((DWORD)hbr);

      case WM_SETCURSOR:
    /* wParam  == hwnd that cursor is over
     * lParamL == Hit test area code (result of WM_NCHITTEST)
     * lParamH == Mouse message number
     */
    if (HIWORD(lParam) != 0 &&
        LOWORD(lParam) >= HTSIZEFIRST &&
        LOWORD(lParam) <= HTSIZELAST)
      {
        SetCursor(rghCursor[LOWORD(lParam) - HTSIZEFIRST + MVSIZEFIRST]);
        break;
      }

    if ((hwndT = GetChildParent(hwnd)) != NULL &&
           (BOOL)SendMessage(hwndT, WM_SETCURSOR, wParam, lParam))
        return((LONG)TRUE);

    if (HIWORD(lParam) == 0)
      {
        hCurs = hCursNormal;
        SetCursor(hCurs);
      }
    else
      {
        switch (LOWORD(lParam))
    {
      case HTCLIENT:
          if (((HWND)wParam)->pcls->hCursor != NULL)
        SetCursor(((HWND)wParam)->pcls->hCursor);
          break;

      case HTERROR:
          switch (HIWORD(lParam))
      {
        case WM_LBUTTONDOWN:
            if ((hwndT = DWP_GetEnabledPopup(hwnd)) != NULL)
        {
          if (hwndT != hwndDesktop->hwndChild)
            {
              SetWindowPos(hwnd, NULL,
               0, 0, 0, 0,
               SWP_NOMOVE | SWP_NOSIZE |
               SWP_NOACTIVATE);
              SetActiveWindow(hwndT);
              break;
            }
        }

            /*** FALL THRU ***/

        case WM_RBUTTONDOWN:
        case WM_MBUTTONDOWN:
                              MessageBeep(0);
            break;
      }
          /*** FALL THRU ***/

      default:
          SetCursor(hCursNormal);
    }
      }

    return((LONG)FALSE);

      case WM_MOUSEACTIVATE:
    if ((hwndT = GetChildParent(hwnd)) != NULL &&
        (i = (int)SendMessage(hwndT, WM_MOUSEACTIVATE, wParam, lParam))
          != 0)
        return((LONG)i);

    /* Moving, sizing or minimizing? Activate AFTER we take action. */
    if (LOWORD(lParam) == HTCAPTION)
        return((LONG)MA_NOACTIVATE);
    else
        return((LONG)MA_ACTIVATE);

      case WM_DRAWITEM:
          if (((LPDRAWITEMSTRUCT)lParam)->CtlType == ODT_LISTBOX)
              LBDefaultListboxDrawItem((LPDRAWITEMSTRUCT)lParam);
          break;

    }

  return(0L);
}


DEMO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SELECT\DEMO.C

/****************************************************************************

    PROGRAM: Demo.c

    PURPOSE: Demonstrates how to manipulate a cursor and select a region

    FUNCTIONS:

  WinMain() - calls initialization function, processes message loop
  DemoInit() - initializes window data and registers window
  DemoWndProc() - processes messages
  About() - processes messages for "About" dialog box

    COMMENTS:
  This code is a modified version of the CURSOR.C program.  Instead of
  using inline code for drawing the shape, the routines from the Select
  library are called.

****************************************************************************/

#include "windows.h"
#include "demo.h"
#include "select.h"

HANDLE hInst;
BOOL bTrack = FALSE;
int OrgX = 0, OrgY = 0;
int PrevX = 0, PrevY = 0;
int X = 0, Y = 0;

RECT Rect;

int Shape = SL_BLOCK;             /* Shape to use for rectangle */
BOOL RetainShape = FALSE;           /* Retain or destroy shape    */

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{

    HWND hWnd;
    MSG msg;

    if (!hPrevInstance)
  if (!DemoInit(hInstance))
      return (NULL);

    hInst = hInstance;

    hWnd = CreateWindow("Demo",
  "Demo Sample Application",
  WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  CW_USEDEFAULT,
  NULL,
  NULL,
  hInstance,
  NULL);

    if (!hWnd)
  return (NULL);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    while (GetMessage(&msg, NULL, NULL, NULL)) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
    }
    return (msg.wParam);
}

/****************************************************************************

    FUNCTION: DemoInit(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL DemoInit(hInstance)
HANDLE hInstance;
{
    HANDLE hMemory;
    PWNDCLASS pWndClass;
    BOOL bSuccess;

    hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
    pWndClass = (PWNDCLASS) LocalLock(hMemory);
    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
    pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION);
    pWndClass->lpszMenuName = (LPSTR) "Menu";
    pWndClass->lpszClassName = (LPSTR) "Demo";
    pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
    pWndClass->hInstance = hInstance;
    pWndClass->style = NULL;
    pWndClass->lpfnWndProc = DemoWndProc;

    bSuccess = RegisterClass(pWndClass);

    LocalUnlock(hMemory);
    LocalFree(hMemory);
    return (bSuccess);
}

/****************************************************************************

    FUNCTION: DemoWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

  WM_SYSCOMMAND - system menu (About dialog box)
  WM_CREATE     - create window
  WM_DESTROY    - destroy window
  WM_LBUTTONDOWN - left mouse button
  WM_MOUSEMOVE   - mouse movement
  WM_LBUTTONUP   - left button released

  WM_COMMAND messages:
      IDM_BOX    - use inverted box for selecting a region
      IDM_BLOCK  - use empty box for selecting a region
      IDM_RETAIN - retain/delete selection on button release

    COMMENTS:

  When the left mouse button is pressed, btrack is set to TRUE so that
  the code for WM_MOUSEMOVE will keep track of the mouse and update the
  box accordingly.  Once the button is released, btrack is set to
  FALSE, and the current position is saved.  Holding the SHIFT key
  while pressing the left button will extend the current box rather
  then erasing it and starting a new one.   The exception is when the
  retain shape option is enabled.   With this option, the rectangle is
  zeroed whenever the mouse is released so that it can not be erased or
  extended.

****************************************************************************/

long FAR PASCAL DemoWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout;
    HMENU hMenu;

    switch (message) {

  case WM_COMMAND:
      switch (wParam) {
    case IDM_BOX:
        Shape = SL_BOX;
        hMenu = GetMenu(hWnd);
        CheckMenuItem(hMenu, IDM_BOX, MF_CHECKED);
        CheckMenuItem(hMenu, IDM_BLOCK, MF_UNCHECKED);
        break;

    case IDM_BLOCK:
        Shape = SL_BLOCK;
        hMenu = GetMenu(hWnd);
        CheckMenuItem(hMenu, IDM_BOX, MF_UNCHECKED);
        CheckMenuItem(hMenu, IDM_BLOCK, MF_CHECKED);
        break;

    case IDM_RETAIN:
        if (RetainShape) {
      hMenu = GetMenu(hWnd);
      CheckMenuItem(hMenu, IDM_RETAIN, MF_UNCHECKED);
      RetainShape = FALSE;
        }
        else {
      hMenu = GetMenu(hWnd);
      CheckMenuItem(hMenu, IDM_RETAIN, MF_CHECKED);
      RetainShape = TRUE;
        }
        break;

    case IDM_ABOUT:
        lpProcAbout = MakeProcInstance(About, hInst);
        DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
        FreeProcInstance(lpProcAbout);
        break;

      }
      break;

  case WM_LBUTTONDOWN:

      bTrack = TRUE;     /* user has pressed the left button */

      /* If you don't want the shape cleared, you must clear the Rect
       * coordinates before calling StartSelection
       */

      if (RetainShape)
    SetRectEmpty(&Rect);

      StartSelection(hWnd, MAKEPOINT(lParam), &Rect,
    (wParam & MK_SHIFT) ? SL_EXTEND | Shape : Shape);
      break;

  case WM_MOUSEMOVE:
      if (bTrack)
    UpdateSelection(hWnd, MAKEPOINT(lParam), &Rect, Shape);
      break;

  case WM_LBUTTONUP:
       if (bTrack)
         EndSelection(MAKEPOINT(lParam), &Rect);
      bTrack = FALSE;
      break;

   case WM_SIZE:
      switch (wParam) {
         case SIZEICONIC:

            /* If we aren't in retain mode we want to clear the
             * current rectangle now!
             */
            if (!RetainShape)
               SetRectEmpty(&Rect);
      }
      break;

  case WM_DESTROY:
      PostQuitMessage(NULL);
      break;

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

/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      return (TRUE);
    }
    return (FALSE);
}


DIB.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SHOWDIB\DIB.C

/****************************************************************************
 *                         *
 *  MODULE  : DIB.C                    *
 *                         *
 *  DESCRIPTION : Routines for dealing with Device Independent Bitmaps.
 *                         *
 *  FUNCTIONS  : OpenDIB()        - Opens DIB file and creates a memory DIB*
 *                         *
 *      WriteDIB()        - Writes a global handle in CF_DIB format*
 *          to a file.             *
 *                         *
 *      DibInfo()        - Retrieves the info. block associated   *
 *          with a CF_DIB format memory block.     *
 *                         *
 *      CreateBIPalette()   - Creates a GDI palette given a pointer  *
 *          to a BITMAPINFO structure.         *
 *                         *
 *      CreateDibPalette()  - Creates a GDI palette given a HANDLE   *
 *          to a BITMAPINFO structure.         *
 *                         *
 *      ReadDibBitmapInfo() - Reads a file in DIB format and returns *
 *          a global handle to it's BITMAPINFO     *
 *                         *
 *      PaletteSize()       - Calculates the palette size in bytes   *
 *          of given DIB             *
 *                         *
 *      DibNumColors()      - Determines the number of colors in DIB *
 *                         *
 *      BitmapFromDib()     - Creates a DDB given a global handle to *
 *          a block in CF_DIB format.         *
 *                         *
 *      DibFromBitmap()     - Creates a DIB repr. the DDB passed in. *
 *                         *
 *      DrawBitmap()        - Draws a bitmap at specified position   *
 *          in the DC.             *
 *                         *
 *      DibBlt()        - Draws a bitmap in CIF_DIB format using *
 *          SetDIBitsToDevice()           *
 *                         *
 *      StretchDibBlt()     - Draws a bitmap in CIF_DIB format using *
 *          StretchDIBits()            *
 *                         *
 *      lread()        - Private routine to read more than 64k  *
 *                         *
 *      lwrite()        - Private routine to write more than 64k *
 *                         *
 ****************************************************************************

#include <windows.h>
#include "showdib.h"
static   HCURSOR hcurSave;

/****************************************************************************
 *                      *
 *  FUNCTION   :OpenDIB(LPSTR szFile)              *
 *                      *
 *  PURPOSE    :Open a DIB file and create a MEMORY DIB, a memory handle    *
 *    containing BITMAPINFO, palette data and the bits.      *
 *                      *
 *  RETURNS    :A handle to the DIB.              *
 *                      *
 ****************************************************************************
HANDLE OpenDIB (szFile)
LPSTR szFile;
{
    unsigned    fh;
    BITMAPINFOHEADER  bi;
    LPBITMAPINFOHEADER  lpbi;
    DWORD    dwLen = 0;
    DWORD    dwBits;
    HANDLE    hdib;
    HANDLE              h;
    OFSTRUCT    of;

    /* Open the file and read the DIB information */
    fh = OpenFile(szFile, &of, OF_READ);
    if (fh == -1)
  return NULL;

    hdib = ReadDibBitmapInfo(fh);
    if (!hdib)
  return NULL;
    DibInfo(hdib,&bi);

    /* Calculate the memory needed to hold the DIB */
    dwBits = bi.biSizeImage;
    dwLen  = bi.biSize + (DWORD)PaletteSize (&bi) + dwBits;

    /* Try to increase the size of the bitmap info. buffer to hold the DIB */
    h = GlobalReAlloc(hdib, dwLen, GHND);
    if (!h){
  GlobalFree(hdib);
  hdib = NULL;
    }
    else
  hdib = h;

    /* Read in the bits */
    if (hdib){

        lpbi = (VOID FAR *)GlobalLock(hdib);
  lread(fh, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi), dwBits);
  GlobalUnlock(hdib);
    }
    _lclose(fh);

    return hdib;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : WriteDIB(LPSTR szFile,HANDLE hdib)          *
 *                      *
 *  PURPOSE    : Write a global handle in CF_DIB format to a file.      *
 *                      *
 *  RETURNS    : TRUE  - if successful.             *
 *     FALSE - otherwise              *
 *                      *
 ****************************************************************************
BOOL WriteDIB (szFile, hdib)
LPSTR szFile;
HANDLE hdib;
{
    BITMAPFILEHEADER  hdr;
    LPBITMAPINFOHEADER  lpbi;
    int                 fh;
    OFSTRUCT            of;

    if (!hdib)
  return FALSE;

    fh = OpenFile (szFile, &of, OF_CREATE|OF_READWRITE);
    if (fh == -1)
  return FALSE;

    lpbi = (VOID FAR *)GlobalLock (hdib);

    /* Fill in the fields of the file header */
    hdr.bfType    = BFT_BITMAP;
    hdr.bfSize    = GlobalSize (hdib) + sizeof (BITMAPFILEHEADER);
    hdr.bfReserved1     = 0;
    hdr.bfReserved2     = 0;
    hdr.bfOffBits       = (DWORD)sizeof(BITMAPFILEHEADER) + lpbi->biSize +
                          PaletteSize(lpbi);

    /* Write the file header */
    _lwrite (fh, (LPSTR)&hdr, sizeof (BITMAPFILEHEADER));

    /* Write the DIB header and the bits */
    lwrite (fh, (LPSTR)lpbi, GlobalSize (hdib));

    GlobalUnlock (hdib);
    _lclose (fh);
    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : DibInfo(HANDLE hbi,LPBITMAPINFOHEADER lpbi)        *
 *                      *
 *  PURPOSE    : Retrieves the DIB info associated with a CF_DIB      *
 *     format memory block.              *
 *                      *
 *  RETURNS    : TRUE  - if successful.             *
 *     FALSE - otherwise              *
 *                      *
 ****************************************************************************
BOOL DibInfo (hbi, lpbi)
HANDLE hbi;
LPBITMAPINFOHEADER lpbi;
{
    if (hbi){
  *lpbi = *(LPBITMAPINFOHEADER)GlobalLock (hbi);

  /* fill in the default fields */
  if (lpbi->biSize != sizeof (BITMAPCOREHEADER)){
            if (lpbi->biSizeImage == 0L)
    lpbi->biSizeImage =
        WIDTHBYTES(lpbi->biWidth*lpbi->biBitCount) * lpbi->biHeight;

            if (lpbi->biClrUsed == 0L)
    lpbi->biClrUsed = DibNumColors (lpbi);
        }
  GlobalUnlock (hbi);
  return TRUE;
    }
    return FALSE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : CreateBIPalette(LPBITMAPINFOHEADER lpbi)        *
 *                      *
 *  PURPOSE    : Given a Pointer to a BITMAPINFO struct will create a      *
 *     a GDI palette object from the color table.        *
 *                      *
 *  RETURNS    : A handle to the palette.            *
 *                      *
 ****************************************************************************
HPALETTE CreateBIPalette (lpbi)
LPBITMAPINFOHEADER lpbi;
{
    LOGPALETTE          *pPal;
    HPALETTE            hpal = NULL;
    WORD                nNumColors;
    BYTE                red;
    BYTE                green;
    BYTE                blue;
    int                 i;
    RGBQUAD        FAR *pRgb;

    if (!lpbi)
  return NULL;

    if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
  return NULL;

    /* Get a pointer to the color table and the number of colors in it */
    pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
    nNumColors = DibNumColors(lpbi);

    if (nNumColors){
  /* Allocate for the logical palette structure */
        pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors *
  if (!pPal)
      return NULL;

        pPal->palNumEntries = nNumColors;
  pPal->palVersion    = PALVERSION;

  /* Fill in the palette entries from the DIB color table and
   * create a logical color palette.
   */
  for (i = 0; i < nNumColors; i++){
            pPal->palPalEntry[i].peRed   = pRgb[i].rgbRed;
            pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
            pPal->palPalEntry[i].peBlue  = pRgb[i].rgbBlue;
            pPal->palPalEntry[i].peFlags = (BYTE)0;
        }
        hpal = CreatePalette(pPal);
        LocalFree((HANDLE)pPal);
    }
    else if (lpbi->biBitCount == 24){
  /* A 24 bitcount DIB has no color table entries so, set the number of
   * to the maximum value (256).
   */
  nNumColors = MAXPALETTE;
        pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors *
        if (!pPal)
      return NULL;

  pPal->palNumEntries = nNumColors;
  pPal->palVersion    = PALVERSION;

  red = green = blue = 0;

  /* Generate 256 (= 8*8*4) RGB combinations to fill the palette
   * entries.
   */
  for (i = 0; i < pPal->palNumEntries; i++){
            pPal->palPalEntry[i].peRed   = red;
            pPal->palPalEntry[i].peGreen = green;
            pPal->palPalEntry[i].peBlue  = blue;
            pPal->palPalEntry[i].peFlags = (BYTE)0;

      if (!(red += 32))
    if (!(green += 32))
        blue += 64;
        }
        hpal = CreatePalette(pPal);
        LocalFree((HANDLE)pPal);
    }
    return hpal;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : CreateDibPalette(HANDLE hbi)            *
 *                      *
 *  PURPOSE    : Given a Global HANDLE to a BITMAPINFO Struct        *
 *     will create a GDI palette object from the color table.     *
 *     (BITMAPINFOHEADER format DIBs only)           *
 *                      *
 *  RETURNS    : A handle to the palette.            *
 *                      *
 ****************************************************************************
HPALETTE CreateDibPalette (hbi)
HANDLE hbi;
{
    HPALETTE hpal;

    if (!hbi)
  return NULL;
    hpal = CreateBIPalette((LPBITMAPINFOHEADER)GlobalLock(hbi));
    GlobalUnlock(hbi);
    return hpal;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : ReadDibBitmapInfo(int fh)            *
 *                      *
 *  PURPOSE    : Will read a file in DIB format and return a global HANDLE  *
 *     to it's BITMAPINFO.  This function will work with both     *
 *     "old" (BITMAPCOREHEADER) and "new" (BITMAPINFOHEADER)      *
 *     bitmap formats, but will always return a "new" BITMAPINFO  *
 *                      *
 *  RETURNS    : A handle to the BITMAPINFO of the DIB in the file.      *
 *                      *
 ****************************************************************************
HANDLE ReadDibBitmapInfo (fh)
int fh;
{
    DWORD     off;
    HANDLE    hbi = NULL;
    int       size;
    int       i;
    WORD      nNumColors;

    RGBQUAD FAR       *pRgb;
    BITMAPINFOHEADER   bi;
    BITMAPCOREHEADER   bc;
    LPBITMAPINFOHEADER lpbi;
    BITMAPFILEHEADER   bf;
    DWORD         dwWidth = 0;
    DWORD         dwHeight = 0;
    WORD         wPlanes, wBitCount;

    if (fh == -1)
        return NULL;

    /* Reset file pointer and read file header */
    off = _llseek(fh, 0L, SEEK_CUR);
    if (sizeof (bf) != _lread (fh, (LPSTR)&bf, sizeof (bf)))
        return FALSE;

    /* Do we have a RC HEADER? */
    if (!ISDIB (bf.bfType)) {
        bf.bfOffBits = 0L;
  _llseek (fh, off, SEEK_SET);
    }
    if (sizeof (bi) != _lread (fh, (LPSTR)&bi, sizeof(bi)))
        return FALSE;

    nNumColors = DibNumColors (&bi);

    /* Check the nature (BITMAPINFO or BITMAPCORE) of the info. block
     * and extract the field information accordingly. If a BITMAPCOREHEADER,
     * transfer it's field information to a BITMAPINFOHEADER-style block
     */
    switch (size = (int)bi.biSize){
  case sizeof (BITMAPINFOHEADER):
            break;

  case sizeof (BITMAPCOREHEADER):

      bc = *(BITMAPCOREHEADER*)&bi;

      dwWidth   = (DWORD)bc.bcWidth;
      dwHeight  = (DWORD)bc.bcHeight;
      wPlanes   = bc.bcPlanes;
      wBitCount = bc.bcBitCount;

            bi.biSize               = sizeof(BITMAPINFOHEADER);
      bi.biWidth        = dwWidth;
      bi.biHeight       = dwHeight;
      bi.biPlanes       = wPlanes;
      bi.biBitCount      = wBitCount;

            bi.biCompression        = BI_RGB;
            bi.biSizeImage          = 0;
            bi.biXPelsPerMeter      = 0;
            bi.biYPelsPerMeter      = 0;
            bi.biClrUsed            = nNumColors;
            bi.biClrImportant       = nNumColors;

      _llseek (fh, (LONG)sizeof (BITMAPCOREHEADER) - sizeof (BITMAPINFOHEADER
            break;

  default:
      /* Not a DIB! */
      return NULL;
    }

    /*  Fill in some default values if they are zero */
    if (bi.biSizeImage == 0){
  bi.biSizeImage = WIDTHBYTES ((DWORD)bi.biWidth * bi.biBitCount)
       * bi.biHeight;
    }
    if (bi.biClrUsed == 0)
  bi.biClrUsed = DibNumColors(&bi);

    /* Allocate for the BITMAPINFO structure and the color table. */
    hbi = GlobalAlloc (GHND, (LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
    if (!hbi)
        return NULL;
    lpbi = (VOID FAR *)GlobalLock (hbi);
    *lpbi = bi;

    /* Get a pointer to the color table */
    pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + bi.biSize);
    if (nNumColors){
  if (size == sizeof(BITMAPCOREHEADER)){
      /* Convert a old color table (3 byte RGBTRIPLEs) to a new
       * color table (4 byte RGBQUADs)
             */
      _lread (fh, (LPSTR)pRgb, nNumColors * sizeof(RGBTRIPLE));

      for (i = nNumColors - 1; i >= 0; i--){
                RGBQUAD rgb;

                rgb.rgbRed      = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
                rgb.rgbBlue     = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
                rgb.rgbGreen    = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
                rgb.rgbReserved = (BYTE)0;

                pRgb[i] = rgb;
            }
        }
  else
            _lread(fh,(LPSTR)pRgb,nNumColors * sizeof(RGBQUAD));
    }

    if (bf.bfOffBits != 0L)
        _llseek(fh,off + bf.bfOffBits,SEEK_SET);

    GlobalUnlock(hbi);
    return hbi;
}

/****************************************************************************
 *                      *
 *  FUNCTION   :  PaletteSize(VOID FAR * pv)            *
 *                      *
 *  PURPOSE    :  Calculates the palette size in bytes. If the info. block  *
 *      is of the BITMAPCOREHEADER type, the number of colors is  *
 *      multiplied by 3 to give the palette size, otherwise the   *
 *      number of colors is multiplied by 4.                *
 *                      *
 *  RETURNS    :  Palette size in number of bytes.          *
 *                      *
 ****************************************************************************
WORD PaletteSize (pv)
VOID FAR * pv;
{
    LPBITMAPINFOHEADER lpbi;
    WORD         NumColors;

    lpbi      = (LPBITMAPINFOHEADER)pv;
    NumColors = DibNumColors(lpbi);

    if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
        return NumColors * sizeof(RGBTRIPLE);
    else
        return NumColors * sizeof(RGBQUAD);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : DibNumColors(VOID FAR * pv)            *
 *                      *
 *  PURPOSE    : Determines the number of colors in the DIB by looking at   *
 *     the BitCount filed in the info block.          *
 *                      *
 *  RETURNS    : The number of colors in the DIB.          *
 *                      *
 ****************************************************************************
WORD DibNumColors (pv)
VOID FAR * pv;
{
    int     bits;
    LPBITMAPINFOHEADER  lpbi;
    LPBITMAPCOREHEADER  lpbc;

    lpbi = ((LPBITMAPINFOHEADER)pv);
    lpbc = ((LPBITMAPCOREHEADER)pv);

    /*  With the BITMAPINFO format headers, the size of the palette
     *  is in biClrUsed, whereas in the BITMAPCORE - style headers, it
     *  is dependent on the bits per pixel ( = 2 raised to the power of
     *  bits/pixel).
     */
    if (lpbi->biSize != sizeof(BITMAPCOREHEADER)){
        if (lpbi->biClrUsed != 0)
            return (WORD)lpbi->biClrUsed;
        bits = lpbi->biBitCount;
    }
    else
        bits = lpbc->bcBitCount;

    switch (bits){
  case 1:
    return 2;
  case 4:
    return 16;
  case 8:
    return 256;
  default:
    /* A 24 bitcount DIB has no color table */
    return 0;
    }
}
/****************************************************************************
 *                      *
 *  FUNCTION   : DibFromBitmap()              *
 *                      *
 *  PURPOSE    : Will create a global memory block in DIB format that      *
 *     represents the Device-dependent bitmap (DDB) passed in.    *
 *                      *
 *  RETURNS    : A handle to the DIB              *
 *                      *
 ****************************************************************************
HANDLE DibFromBitmap (hbm, biStyle, biBits, hpal)
HBITMAP      hbm;
DWORD       biStyle;
WORD       biBits;
HPALETTE     hpal;
{
    BITMAP               bm;
    BITMAPINFOHEADER     bi;
    BITMAPINFOHEADER FAR *lpbi;
    DWORD                dwLen;
    HANDLE               hdib;
    HANDLE               h;
    HDC                  hdc;

    if (!hbm)
  return NULL;

    if (hpal == NULL)
        hpal = GetStockObject(DEFAULT_PALETTE);

    GetObject(hbm,sizeof(bm),(LPSTR)&bm);

    if (biBits == 0)
  biBits =  bm.bmPlanes * bm.bmBitsPixel;

    bi.biSize               = sizeof(BITMAPINFOHEADER);
    bi.biWidth              = bm.bmWidth;
    bi.biHeight             = bm.bmHeight;
    bi.biPlanes             = 1;
    bi.biBitCount           = biBits;
    bi.biCompression        = biStyle;
    bi.biSizeImage          = 0;
    bi.biXPelsPerMeter      = 0;
    bi.biYPelsPerMeter      = 0;
    bi.biClrUsed            = 0;
    bi.biClrImportant       = 0;

    dwLen  = bi.biSize + PaletteSize(&bi);

    hdc = GetDC(NULL);
    hpal = SelectPalette(hdc,hpal,FALSE);
   RealizePalette(hdc);

    hdib = GlobalAlloc(GHND,dwLen);

    if (!hdib){
  SelectPalette(hdc,hpal,FALSE);
  ReleaseDC(NULL,hdc);
  return NULL;
    }

    lpbi = (VOID FAR *)GlobalLock(hdib);

    *lpbi = bi;

    /*  call GetDIBits with a NULL lpBits param, so it will calculate the
     *  biSizeImage field for us
     */
    GetDIBits(hdc, hbm, 0, (WORD)bi.biHeight,
        NULL, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS);

    bi = *lpbi;
    GlobalUnlock(hdib);

    /* If the driver did not fill in the biSizeImage field, make one up */
    if (bi.biSizeImage == 0){
        bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight

        if (biStyle != BI_RGB)
            bi.biSizeImage = (bi.biSizeImage * 3) / 2;
    }

    /*  realloc the buffer big enough to hold all the bits */
    dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage;
    if (h = GlobalReAlloc(hdib,dwLen,0))
        hdib = h;
    else{
        GlobalFree(hdib);
  hdib = NULL;

  SelectPalette(hdc,hpal,FALSE);
  ReleaseDC(NULL,hdc);
  return hdib;
    }

    /*  call GetDIBits with a NON-NULL lpBits param, and actualy get the
     *  bits this time
     */
    lpbi = (VOID FAR *)GlobalLock(hdib);

    if (GetDIBits( hdc,
       hbm,
       0,
       (WORD)bi.biHeight,
       (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),
       (LPBITMAPINFO)lpbi, DIB_RGB_COLORS) == 0){
   GlobalUnlock(hdib);
   hdib = NULL;
   SelectPalette(hdc,hpal,FALSE);
   ReleaseDC(NULL,hdc);
   return NULL;
    }

    bi = *lpbi;
    GlobalUnlock(hdib);

    SelectPalette(hdc,hpal,FALSE);
    ReleaseDC(NULL,hdc);
    return hdib;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : BitmapFromDib(HANDLE hdib, HPALETTE hpal)        *
 *                      *
 *  PURPOSE    : Will create a DDB (Device Dependent Bitmap) given a global *
 *     handle to a memory block in CF_DIB format        *
 *                      *
 *  RETURNS    : A handle to the DDB.              *
 *                      *
 ****************************************************************************
HBITMAP BitmapFromDib (hdib, hpal)
HANDLE     hdib;
HPALETTE   hpal;
{
    LPBITMAPINFOHEADER  lpbi;
    HPALETTE    hpalT;
    HDC     hdc;
    HBITMAP    hbm;

    StartWait();

    if (!hdib)
  return NULL;

    lpbi = (VOID FAR *)GlobalLock(hdib);

    if (!lpbi)
  return NULL;

    hdc = GetDC(NULL);

    if (hpal){
        hpalT = SelectPalette(hdc,hpal,FALSE);
        RealizePalette(hdc);     // GDI Bug...????
    }

    hbm = CreateDIBitmap(hdc,
                (LPBITMAPINFOHEADER)lpbi,
                (LONG)CBM_INIT,
                (LPSTR)lpbi + lpbi->biSize + PaletteSize(lpbi),
                (LPBITMAPINFO)lpbi,
                DIB_RGB_COLORS );

    if (hpal)
        SelectPalette(hdc,hpalT,FALSE);

    ReleaseDC(NULL,hdc);
    GlobalUnlock(hdib);

    EndWait();

    return hbm;
}
/****************************************************************************
 *                      *
 *  FUNCTION   : DrawBitmap(HDC hdc, int x, int y, HBITMAP hbm, DWORD rop)  *
 *                      *
 *  PURPOSE    : Draws bitmap <hbm> at the specifed position in DC <hdc>    *
 *                      *
 *  RETURNS    : Return value of BitBlt()            *
 *                      *
 ****************************************************************************
BOOL DrawBitmap (hdc, x, y, hbm, rop)
HDC     hdc;
int     x, y;
HBITMAP    hbm;
DWORD     rop;
{
    HDC       hdcBits;
    BITMAP    bm;
    HPALETTE  hpalT;
    BOOL      f;

    if (!hdc || !hbm)
        return FALSE;

    hdcBits = CreateCompatibleDC(hdc);
    GetObject(hbm,sizeof(BITMAP),(LPSTR)&bm);
    SelectObject(hdcBits,hbm);
    f = BitBlt(hdc,0,0,bm.bmWidth,bm.bmHeight,hdcBits,0,0,rop);
    DeleteDC(hdcBits);

    return f;
}
/****************************************************************************
 *                      *
 *  FUNCTION   : DibBlt( HDC hdc,              *
 *       int x0, int y0,            *
 *       int dx, int dy,            *
 *       HANDLE hdib,              *
 *       int x1, int y1,            *
 *       LONG rop)              *
 *                      *
 *  PURPOSE    : Draws a bitmap in CF_DIB format, using SetDIBits to device.*
 *     taking the same parameters as BitBlt().        *
 *                      *
 *  RETURNS    : TRUE  - if function succeeds.            *
 *     FALSE - otherwise.              *
 *                      *
 ****************************************************************************
BOOL DibBlt (hdc, x0, y0, dx, dy, hdib, x1, y1, rop)
HDC     hdc;
int     x0, y0, dx, dy;
HANDLE     hdib;
int     x1, y1;
LONG     rop;
{
    LPBITMAPINFOHEADER   lpbi;
    HPALETTE     hpal,hpalT;
    LPSTR     pBuf;
    HDC      hdcMem;
    HBITMAP     hbm,hbmT;

    if (!hdib)
  return PatBlt(hdc,x0,y0,dx,dy,rop);

    lpbi = (VOID FAR *)GlobalLock(hdib);

    if (!lpbi)
  return FALSE;

    pBuf = (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi);
    SetDIBitsToDevice (hdc, x0, y0, dx, dy,
           x1,y1,
           x1,
           dy,
           pBuf, (LPBITMAPINFO)lpbi,
           DIB_RGB_COLORS );

    GlobalUnlock(hdib);
    return TRUE;
}
/****************************************************************************
 *                      *
 *  FUNCTION   : StretchDibBlt( HDC hdc,            *
 *        int x, int y,            *
 *        int dx, int dy,           *
 *        HANDLE hdib,            *
 *        int x0, int y0,           *
 *        int dx0, int dy0,          *
 *        LONG rop)            *
 *                      *
 *  PURPOSE    : Draws a bitmap in CF_DIB format, using StretchDIBits()     *
 *     taking the same parameters as StretchBlt().        *
 *                      *
 *  RETURNS    : TRUE  - if function succeeds.            *
 *     FALSE - otherwise.              *
 *                      *
 ****************************************************************************
BOOL StretchDibBlt (hdc, x, y, dx, dy, hdib, x0, y0, dx0, dy0, rop)
HDC hdc;
int x, y;
int dx, dy;
HANDLE hdib;
int x0, y0;
int dx0, dy0;
LONG rop;

{
    LPBITMAPINFOHEADER lpbi;
    LPSTR        pBuf;
    BOOL         f;

    if (!hdib)
        return PatBlt(hdc,x,y,dx,dy,rop);

    lpbi = (VOID FAR *)GlobalLock(hdib);

    if (!lpbi)
        return FALSE;

    pBuf = (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi);

    f = StretchDIBits ( hdc,
      x, y,
      dx, dy,
      x0, y0,
      dx0, dy0,
      pBuf, (LPBITMAPINFO)lpbi,
      DIB_RGB_COLORS,
      rop);

    GlobalUnlock(hdib);
    return f;
}

 /************* PRIVATE ROUTINES TO READ/WRITE MORE THAN 64K ***************/
/****************************************************************************
 *                      *
 *  FUNCTION   : lread(int fh, VOID FAR *pv, DWORD ul)          *
 *                      *
 *  PURPOSE    : Reads data in steps of 32k till all the data has been read.*
 *                      *
 *  RETURNS    : 0 - If read did not proceed correctly.         *
 *     number of bytes read otherwise.          *
 *                      *
 ****************************************************************************
DWORD PASCAL lread (fh, pv, ul)
int        fh;
VOID far      *pv;
DWORD        ul;
{
    DWORD     ulT = ul;
    BYTE huge *hp = pv;

    while (ul > (DWORD)MAXREAD) {
  if (_lread(fh, (LPSTR)hp, (WORD)MAXREAD) != MAXREAD)
    return 0;
  ul -= MAXREAD;
  hp += MAXREAD;
    }
    if (_lread(fh, (LPSTR)hp, (WORD)ul) != (WORD)ul)
  return 0;
    return ulT;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : lwrite(int fh, VOID FAR *pv, DWORD ul)         *
 *                      *
 *  PURPOSE    : Writes data in steps of 32k till all the data is written.  *
 *                      *
 *  RETURNS    : 0 - If write did not proceed correctly.        *
 *     number of bytes written otherwise.          *
 *                      *
 ****************************************************************************
DWORD PASCAL lwrite (fh, pv, ul)
int       fh;
VOID FAR     *pv;
DWORD       ul;
{
    DWORD     ulT = ul;
    BYTE huge *hp = pv;

    while (ul > MAXREAD) {
  if (_lwrite(fh, (LPSTR)hp, (WORD)MAXREAD) != MAXREAD)
    return 0;
  ul -= MAXREAD;
  hp += MAXREAD;
    }
    if (_lwrite(fh, (LPSTR)hp, (WORD)ul) != (WORD)ul)
  return 0;
    return ulT;
}


DLGOPEN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SHOWDIB\DLGOPEN.C

/****************************************************************************
 *                         *
 *  MODULE  : DLGOPEN.C                   *
 *                         *
 *  DESCRIPTION : Routines to display a standard File/Open and File/Save
 *      dialog boxes.                  *
 *                         *
 *  FUNCTIONS  : DlgOpenFile() - Displays a dialog box for opening or saving
 *          file.                *
 *                         *
 *      DlgfnOpen()  - Dialog function for the above dialog.        *
 *                         *
 *      AddExt()  - Adds an extension to a filename if not       *
 *          already present.             *
 *                         *
 *      FSearchSpec() - Checks if given string contains a wildcard   *
 *          character.               *
 *                         *
 *      FillListBox() - Fills listbox with files that match specs.   *
 *                         *
 *      DlgCheckOkEnable() - Enables <OK> button iff there's text in *
 *               the edit control.           *
 *                         *
 *      NOTE : These routines require that the app. be running       *
 *       SS = DS since they use near pointers into the stack.  *
 *                         *
 ****************************************************************************
#include <windows.h>
#include "showdib.h"

static PSTR         szExt;
static PSTR         szFileName;
static PSTR         szTitle;
static DWORD        flags;
static WORD         fOpt;

/* Forward declarations of helper functions */

static void  NEAR DlgCheckOkEnable(HWND hwnd, int idEdit, unsigned message);
static char *NEAR FillListBox (HWND,char*);
static BOOL  NEAR FSearchSpec (char*);
static void  NEAR AddExt (char*,char*);
extern PASCAL chdir(LPSTR);     /* in dlgopena.asm */

#define DLGOPEN_UNUSED   0

/* Mask to eliminate bogus style and bitcount combinations ...
 * RLE formats, if chosen should be matched with the bitcounts:
 *   RLE4 scheme should be used only for 4 bitcount DIBs.
 *   RLE8   "      "   "   "   "    "  8   "       "
 *
 * BITCOUNTMASK is indexed by DLGOPEN_RLE4 >> 4, DLGOPEN_RLE8 >> 4
 * and DLGOPEN_RLE8 >> 4
 */

static WORD BITCOUNTMASK[] = { DLGOPEN_UNUSED,
             DLGOPEN_1BPP | DLGOPEN_8BPP | DLGOPEN_24BPP,
             DLGOPEN_1BPP | DLGOPEN_4BPP | DLGOPEN_24BPP,
             DLGOPEN_UNUSED,
             0 };

/****************************************************************************
 *                         *
 *  FUNCTION   :DlgOpen(LPSTR szFile)                 *
 *                         *
 *  PURPOSE    :Display dialog box for opening files. Allow user to interact
 *    with dialogbox, change directories as necessary, and try to    *
 *    open file if user selects one. Automatically append         *
 *    extension to filename if necessary.             *
 *    This routine correctly parses filenames containing KANJI       *
 *    characters.                   *
 *                         *
 *  RETURNS    :  - Handle to the opened file if legal filename.         *
 *      - 0 if user presses <cancel>               *
 *      - 1 if filename entered is illegal             *
 *                         *
 ****************************************************************************
int FAR PASCAL DlgOpenFile (hwndParent, szTitleIn, flagsIn, szExtIn,
          szFileNameIn, pfOpt)

HWND    hwndParent;
char    *szTitleIn;
DWORD    flagsIn;
char    *szExtIn;
char    *szFileNameIn;
WORD    *pfOpt;
{
    int      fh;
    FARPROC  lpProc;
    char     achFile[128];
    char     achExt[128];
    HANDLE   hInstance;
    WORD     w;

    if (pfOpt == NULL)
        pfOpt = &w;

    flags    = flagsIn;
    fOpt     = *pfOpt;

    lstrcpy (szFileName = achFile, szFileNameIn);
    lstrcpy (szExt = achExt, szExtIn);
    szTitle = szTitleIn;

    hInstance = GetWindowWord (hwndParent, GWW_HINSTANCE);

    /* Show the dialog box */
    lpProc = MakeProcInstance ((FARPROC)DlgfnOpen, hInstance);
    fh = DialogBox (hInstance, "DlgOpenBox", hwndParent, lpProc);
    FreeProcInstance (lpProc);

    if (fh != 0){
  lstrcpy (szFileNameIn, szFileName);
        *pfOpt = fOpt;
    }
    return fh;
}

/****************************************************************************
 *                      *
 *  FUNCTION   :DlgfnOpen (hwnd, msg, wParam, lParam)          *
 *                      *
 *  PURPOSE    :Dialog function for File/Open dialog.          *
 *                      *
 ****************************************************************************
int far PASCAL DlgfnOpen (hwnd, msg, wParam, lParam)

HWND hwnd;
unsigned msg;
WORD wParam;
LONG lParam;
{
    int      result = -1;    /* Assume illegal filename initially */
    WORD     w;
    char     c;
    WORD     f;
    OFSTRUCT of;
    RECT     rc, rcCtl;
    HWND     hwndT;
    BOOL     fEnable;

    switch (msg) {
  case WM_INITDIALOG:
      if (szTitle && *szTitle)
    SetWindowText (hwnd, szTitle);

      /* Set text on <OK> button according to mode (File/Open or File/Save) *
      if (flags & OF_SAVE)
    SetDlgItemText (hwnd, IDOK, "&Save");
      if (flags & OF_OPEN)
    SetDlgItemText (hwnd, IDOK, "&Open");

      if ((flags & OF_NOOPTIONS) &&
    (hwndT = GetDlgItem(hwnd,DLGOPEN_FOLDOUT)))
    EnableWindow (hwndT,FALSE);

      if (hwndT = GetDlgItem (hwnd, DLGOPEN_SMALL)) {
    GetWindowRect (hwnd,&rc);
    GetWindowRect (GetDlgItem(hwnd,DLGOPEN_SMALL),&rcCtl);

    SetWindowPos (hwnd,
            NULL,
            0,
            0,
            rcCtl.left - rc.left,
            rc.bottom - rc.top,
            SWP_NOZORDER | SWP_NOMOVE);
      }
      /* fill list box with filenames that match specifications, and
       * fill static field with path name.
       */
      FillListBox(hwnd,szExt);

      /* If in Save mode, set the edit control with default (current)
       * file name,and select the corresponding entry in the listbox.
       */
      if ((flags & OF_SAVE) && *szFileName) {
    SetDlgItemText (hwnd, DLGOPEN_EDIT, szFileName);
    SendDlgItemMessage (hwnd,
            DLGOPEN_FILE_LISTBOX,
            LB_SELECTSTRING,
            0,
            (LONG)(LPSTR)szFileName);
      }
      else {
    /*  Set the edit field with the default extensions... */
    if (flags & OF_NOSHOWSPEC)
        SetDlgItemText (hwnd, DLGOPEN_EDIT, "");
    else
        SetDlgItemText (hwnd, DLGOPEN_EDIT, szExt);
      }
      /*  ...and select all text in the edit field */
      SendDlgItemMessage (hwnd, DLGOPEN_EDIT, EM_SETSEL, 0, 0x7FFF0000L);

      /*  check all options that are set */
      for ( f = DLGOPEN_1BPP; f; f<<=1)
    CheckDlgButton(hwnd, FID(f), fOpt & f);

      break;

  case WM_COMMAND:
      w = wParam;
      switch (w) {
    case IDOK:
        if (IsWindowEnabled (GetDlgItem(hwnd, IDOK))) {
      /* Get contents of edit field and add search spec. if it
       * does not contain one.
       */
      GetDlgItemText (hwnd, DLGOPEN_EDIT, (LPSTR)szFileName, 128);

      w = lstrlen(szFileName)-1;
      c = szFileName[w];
      switch (c) {
          case '\\':
          case '/':
        szFileName[w] = 0;
        break;
      }
      if (chdir ((LPSTR)szFileName))
          lstrcpy (szFileName,szExt);

      /*  Try to open path.  If successful, fill listbox with
       *  contents of new directory.  Otherwise, open datafile.
       */
      if (FSearchSpec(szFileName)) {
          lstrcpy (szExt, FillListBox (hwnd, szFileName));
          if (flags & OF_NOSHOWSPEC)
        SetDlgItemText (hwnd, DLGOPEN_EDIT, "");
          else
        SetDlgItemText (hwnd, DLGOPEN_EDIT, szExt);
          break;
      }

      /*  Make filename upper case and if it's a legal DOS
       *  name, try to open the file.
       */
      AnsiUpper(szFileName);
      AddExt(szFileName,szExt);
      result = OpenFile(szFileName, &of, (WORD)flags);

      if (result != -1) {
          lstrcpy(szFileName,of.szPathName);
      }
      else if (flags & OF_MUSTEXIST) {
          MessageBeep(0);
          return 0L;
      }

      /*  Get the state of all checked options */
      for (f = DLGOPEN_1BPP; f; f <<= 1){
          if (IsDlgButtonChecked (hwnd, FID (f)))
        fOpt |= f;
          else
        fOpt &= ~f;
      }

      EndDialog (hwnd, result);
        }
        break;

    case DLGOPEN_OPTION + DLGOPEN_RLE4:
    case DLGOPEN_OPTION + DLGOPEN_RLE8:
    case DLGOPEN_OPTION + DLGOPEN_RGB:
        /* Mask out incompatible bitcount options and gray the
         * appropriate radiobuttons.
         */
        for (f = DLGOPEN_1BPP; f <= DLGOPEN_24BPP; f <<= 1){
      fEnable = !(f & BITCOUNTMASK [IDF(w) >> 4 ]);
      EnableWindow (GetDlgItem (hwnd, FID(f)), fEnable);

      /* If the radiobutton is being grayed, uncheck it and
       * and check an "allowed" option so the bitcount group
       * is still accessible via the keyboard
       */
      if (!fEnable && IsDlgButtonChecked (hwnd, FID (f))){
          CheckDlgButton(hwnd, FID(f), FALSE);
          CheckDlgButton(hwnd, FID(IDF(w) >> 3), TRUE);
      }
        }
        break;

    case IDCANCEL:
        /* User pressed cancel.  Just take down dialog box. */
        EndDialog (hwnd, 0);
        break;

    /*  User single clicked or doubled clicked in listbox -
     *  Single click means fill edit box with selection.
     *  Double click means go ahead and open the selection.
     */
    case DLGOPEN_FILE_LISTBOX:
    case DLGOPEN_DIR_LISTBOX:

        switch (HIWORD(lParam)) {
      /* Single click case */
      case 1:
          /* Get selection, which may be either a prefix to a
           * new search path or a filename. DlgDirSelect parses
           * selection, and appends a backslash if selection
           * is a prefix
           */
          DlgDirSelect(hwnd,szFileName,wParam);
          w = lstrlen(szFileName)-1;
          c = szFileName[w];
          switch (c) {
        case ':':
            lstrcat (szFileName,".");
            break;
        case '\\':
        case '/':
            szFileName[w] = 0;
            break;
          }
          SetDlgItemText(hwnd, DLGOPEN_EDIT, szFileName);
          break;
      /* Double click case - first click has already been
       * processed as single click
       */
      case 2:
          PostMessage (hwnd,WM_COMMAND,IDOK,0L);
          break;
        }
        break;

    case DLGOPEN_EDIT:
        DlgCheckOkEnable(hwnd, DLGOPEN_EDIT, HIWORD(lParam));
        break;

    case DLGOPEN_FOLDOUT:
        GetWindowRect(hwnd,&rc);
        GetWindowRect(GetDlgItem(hwnd,DLGOPEN_BIG),&rcCtl);

        if ((rcCtl.left <= rc.right) && (rcCtl.top <= rc.bottom))
       GetWindowRect (GetDlgItem (hwnd, DLGOPEN_SMALL), &rcCtl);

        SetWindowPos (hwnd,
          NULL,
          0,
          0,
          rcCtl.left - rc.left,
          rc.bottom - rc.top,
          SWP_NOZORDER | SWP_NOMOVE);
        break;
      }
  default:
      return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : static void NEAR DlgCheckOkEnable(hwnd, idEdit, message)   *
 *                      *
 *  PURPOSE    : Enables the <OK> button in a dialog box iff the edit item  *
 *     contains text.               *
 *                      *
 ****************************************************************************
static void NEAR DlgCheckOkEnable(hwnd, idEdit, message)

HWND  hwnd;
int  idEdit;
unsigned message;
{
    if (message == EN_CHANGE) {
  EnableWindow ( GetDlgItem (hwnd, IDOK),
           (BOOL)SendMessage (GetDlgItem (hwnd, idEdit),
            WM_GETTEXTLENGTH,
            0, 0L));
    }
}

/****************************************************************************
 *                      *
 *  FUNCTION   : AddExt (pch, ext)              *
 *                      *
 *  PURPOSE    : Add an extension to a filename if none is already specified*
 *                      *
 ****************************************************************************
static void NEAR AddExt (pch,ext)

char *pch;    /* File name    */
char *ext;    /* Extension to add */
{
    char acExt[20];
    char *pext = acExt;

    while (*ext && *ext != '.')
  ext++;
    while (*ext && *ext != ';')
  *pext++ = *ext++;
    *pext = 0;
    pext = acExt;

    while (*pch == '.') {
  pch++;
  if ((*pch == '.') && pch[1] == '\\')
      pch += 2;          /* ..\ */
  if (*pch == '\\')
      pch++;         /* .\ */
    }
    while (*pch != '\0')
  if (*pch++ == '.')
      return;

    // *pch++ = '.';
    do
  *pch++ = *pext;
    while (*pext++ != '\0');
}
/****************************************************************************
 *                      *
 *  FUNCTION   : FSearchSpec (sz)              *
 *                      *
 *  PURPOSE    : Checks to see if NULL-terminated strings contains a "*" or *
 *     a "?".                 *
 *                      *
 *  RETURNS    : TRUE  - if the above characters are found in the string    *
 *     FALSE - otherwise.              *
 *                      *
 ****************************************************************************
static BOOL NEAR FSearchSpec(sz)
char  *sz;
{
    for (; *sz ;sz++) {
  if (*sz == '*' || *sz == '?')
      return TRUE;
    }
    return FALSE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : static char * NEAR FillListBox (hDlg,pFile)        *
 *                      *
 *  PURPOSE    : Fill list box with filenames that match specifications, and*
 *     fills the static field with the path name.        *
 *                      *
 *  RETURNS    : A pointer to the pathname.                    *
 *                      *
 ****************************************************************************
static char * NEAR FillListBox (hDlg,pFile)

HWND  hDlg;
char  *pFile;  /* [path]{list of file wild cards, separated by ';'} */
{
    char  ach[20];
    char  *pch;
    char  *pDir;   /* Directory name or path */

    pch  = pFile;
    pDir = ach;

    while (*pch && *pch != ';')
  pch++;
    while ((pch > pFile) && (*pch != '/') && (*pch != '\\'))
  pch--;
    if (pch > pFile) {
       *pch = 0;
       lstrcpy (pDir, pFile);
       pFile = pch + 1;
    }
    else {
       lstrcpy (pDir,".");
    }

    DlgDirList (hDlg, pDir, DLGOPEN_DIR_LISTBOX, DLGOPEN_PATH,ATTRDIRLIST);
    SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, LB_RESETCONTENT, 0, 0L);
    SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, WM_SETREDRAW, FALSE, 0L);
    pDir = pFile;       /* save pFile to return */
    while (*pFile) {
  pch = ach;
  while (*pFile==' ')
      pFile++;
  while (*pFile && *pFile != ';')
      *pch++ = *pFile++;
  *pch = 0;
  if (*pFile)
      pFile++;
  SendDlgItemMessage (hDlg,
          DLGOPEN_FILE_LISTBOX,
          LB_DIR,ATTRFILELIST,
          (LONG)(LPSTR)ach);
    }
    SendDlgItemMessage (hDlg, DLGOPEN_FILE_LISTBOX, WM_SETREDRAW, TRUE, 0L);
    InvalidateRect (GetDlgItem (hDlg, DLGOPEN_FILE_LISTBOX), NULL, TRUE);

    return pDir;
}


DRAWDIB.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SHOWDIB\DRAWDIB.C

/****************************************************************************
 *                         *
 *  MODULE  : DrawDIB.c                   *
 *                         *
 *  PURPOSE  : Handles most of the SHOWDIB's DIB drawing and clipboard      *
 *      operations.                   *
 *                         *
 *  FUNCTIONS  :                     *
 *      PrintDIB()     -  Sets the current DIB bits to the   *
 *              printer DC.            *
 *                         *
 *      AppPaint()     -  Sets the DIB/bitmap bits on the    *
 *              screen or the given device.        *
 *                         *
 *      DrawSelect()     -  Draws selected clip rectangle on   *
 *              the DC/screen.           *
 *                         *
 *      NormalizeRect()   -  Swaps reversed rectangle coords.   *
 *                         *
 *      TrackMouse()     -  Draws rubberbanding rectangle and  *
 *              displays it's dimensions.          *
 *                         *
 *      BandDIB()     -  Outputs DIB in bands to device.    *
 *                         *
 *      SizeWindow()     -  Sizes app. window based on client  *
 *              dimensions and style.         *
 *                         *
 *      GetRealClientRect()   -  Calculates client rectangle dimen- *
 *              sions if scrollbars are present.   *
 *                         *
 *      SetScrollRanges()   -  Sets global scroll ranges.         *
 *                         *
 *      CopyHandle()     -  Makes a copy of memory block.      *
 *                         *
 *      CopyPalette()    -  Makes a copy of the GDI logical    *
 *              palette.             *
 *                         *
 *      CopyBitmap()     -  Copies given bitmap to another.    *
 *                         *
 *      CropBitmap()     -  Crops a bitmap to the given size.  *
 *                         *
 *      RenderFormat()   -  renders currently displayed DIB    *
 *              in CF_BITMAP or CF_DIB format.     *
 *                         *
 *      RealizeDibFormat()   -  Realizes the DIB in given format.  *
 *                         *
 *      ErrMsg()     -  Pops an error message to user.     *
 *                         *
 *      fDialog()     -  Displays a dialog box.         *
 *                         *
 *      AppAbout()     -  Shows the About.. dialog box.      *
 *                         *
 ****************************************************************************
#include <windows.h>
#include <io.h>
#include <stdio.h>
#include "showdib.h"

POINT          ptSize;      /* Stores DIB dimensions           */

/****************************************************************************
 *                      *
 *  FUNCTION   :  PrintDIB(HWND hWnd, HDC hDC, int x, int y, int dx, int dy)*
 *                      *
 *  PURPOSE    :  Set the DIB bits to the printer DC.          *
 *                      *
 ****************************************************************************
void PrintDIB (hWnd, hDC, x, y, dx, dy)
HWND hWnd;
HDC hDC;
int x, y;
int dx, dy;

{
    BITMAPINFOHEADER bi;
    int dibX,  dibY;
    int dibDX, dibDY;

    if (!bLegitDraw)
        return;

    DibInfo (hbiCurrent, &bi);

    if (IsRectEmpty (&rcClip)){
        dibX  = 0;
        dibY  = 0;
        dibDX = (int)bi.biWidth;
        dibDY = (int)bi.biHeight;
    }
    else{
        dibX  = rcClip.left;
  dibY  = (int)bi.biHeight - 1 - rcClip.bottom;
        dibDX = rcClip.right  - rcClip.left;
        dibDY = rcClip.bottom - rcClip.top;
    }

    if (hdibCurrent){
  /* Stretch the DIB to printer DC */
        StretchDibBlt ( hDC,
      x,
      y,
      dx,
      dy,
      hdibCurrent,
      dibX,
      dibY,
      dibDX,
      dibDY,
      SRCCOPY);
    }
    else if (achFileName[0]) {

  SetMapMode (hDC, MM_ANISOTROPIC);
  SetViewportOrg (hDC, x, y);
  SetViewportExt (hDC, dx, dy);

  BandDIB (hWnd, hDC, 0, 0);
    }
}

/****************************************************************************
 *                      *
 *  FUNCTION   :  AppPaint(HWND hWnd, HDC hDC, int x, int y)        *
 *                      *
 *  PURPOSE    :  Sets the DIB/bitmap bits on the screen or the given device*
 *                      *
 ****************************************************************************
void AppPaint (hWnd, hDC, x, y)

HWND hWnd;
HDC hDC;
int x, y;
{
    HPALETTE hpalT;
    BITMAPINFOHEADER bi;
    LPBITMAPINFOHEADER lpbi;

    SetWindowOrg (hDC, x, y);
    SetBkMode (hDC, wTransparent);

    if (bLegitDraw) {
  hpalT = SelectPalette (hDC, hpalCurrent, FALSE);
  RealizePalette (hDC);

        if (hbmCurrent && !bDIBToDevice) {
      DrawBitmap (hDC, 0, 0, hbmCurrent, SRCCOPY);
        }
        else if (hdibCurrent) {
      DibInfo (hdibCurrent, &bi);
      DibBlt (hDC,
        0,
        0,
        (int)bi.biWidth,
        (int)bi.biHeight,
        hdibCurrent,
        0,
        0,
        SRCCOPY);
        }
        else if (achFileName[0]) {
      BandDIB (hWnd, hDC, 0, 0);
        }

        SelectPalette(hDC,hpalT,FALSE);
    }

    DrawSelect(hDC, TRUE);
}

/****************************************************************************
 *                      *
 *  FUNCTION   :  DrawSelect(HDC hdc, BOOL fDraw)          *
 *                      *
 *  PURPOSE    :  Draws the selected clip rectangle with its dimensions on  *
 *      the DC/screen               *
 *                      *
 ****************************************************************************
void DrawSelect( hdc, fDraw)

HDC hdc;
BOOL fDraw;
{
    char  sz[80];
    DWORD dw;
    int   x,y,len,dx,dy;
    HDC   hdcBits;
    HBITMAP hbm;

    if (!IsRectEmpty (&rcClip)) {

  /* If a rectangular clip region has been selected, draw it */
        PatBlt(hdc, rcClip.left,    rcClip.top,        rcClip.right-rcClip.le
        PatBlt(hdc, rcClip.left,    rcClip.bottom, 1, -(rcClip.bottom-rcClip.
        PatBlt(hdc, rcClip.right-1, rcClip.top, 1,   rcClip.bottom-rcClip.top
        PatBlt(hdc, rcClip.right,   rcClip.bottom-1, -(rcClip.right-rcClip.le

  /* Format the dimensions string ...*/
  wsprintf( sz,
      "%dx%d",
      rcClip.right  - rcClip.left,
      rcClip.bottom - rcClip.top );
        len = lstrlen(sz);

  /* ... and center it in the rectangle */
  dw = GetTextExtent (hdc, sz, len);
  dx = LOWORD (dw);
  dy = HIWORD (dw);
  x  =  (rcClip.right  + rcClip.left - dx) / 2;
  y  =  (rcClip.bottom + rcClip.top  - dy) / 2;

  hdcBits = CreateCompatibleDC (hdc);
  SetTextColor (hdcBits, 0xFFFFFFL);
  SetBkColor (hdcBits, 0x000000L);

  /* Output the text to the DC */
  if (hbm = CreateBitmap (dx, dy, 1, 1, NULL)){
      hbm = SelectObject (hdcBits, hbm);
      ExtTextOut (hdcBits, 0, 0, 0, NULL, sz, len, NULL);
      BitBlt (hdc, x, y, dx, dy, hdcBits, 0, 0, SRCINVERT);
      hbm = SelectObject (hdcBits, hbm);
      DeleteObject (hbm);
        }
  DeleteDC (hdcBits);
    }
}
/****************************************************************************
 *                      *
 *  FUNCTION   : NormalizeRect(RECT *prc)            *
 *                      *
 *  PURPOSE    : If the rectangle coordinates are reversed, swaps them      *
 *                      *
 ****************************************************************************
void PASCAL NormalizeRect (prc)
RECT *prc;
{
    if (prc->right < prc->left)
        SWAP(prc->right,prc->left);
    if (prc->bottom < prc->top)
        SWAP(prc->bottom,prc->top);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : TrackMouse(HWND hwnd, POINT pt)          *
 *                      *
 *  PURPOSE    : Draws a rubberbanding rectangle and displays it's          *
 *     dimensions till the mouse button is released        *
 *                      *
 ****************************************************************************
void TrackMouse (hwnd, pt)
HWND hwnd;
POINT pt;
{
    POINT ptBase;
    HDC   hdc;
    MSG   msg;
    POINT ptOrigin;
    RECT  rcClient;

    hdc = GetDC(hwnd);
    SetCapture(hwnd);

    GetClientRect(hwnd,&rcClient);

    /* Get mouse coordinates relative to origin of DIB */
    ptOrigin.x = GetScrollPos(hwnd,SB_HORZ);
    ptOrigin.y = GetScrollPos(hwnd,SB_VERT);

    pt.x += ptOrigin.x;
    pt.y += ptOrigin.y;

    /* Display the coordinates */
    SetWindowOrg(hdc,ptOrigin.x,ptOrigin.y);
    DrawSelect(hdc,FALSE);

    /* Initialize clip rectangle to the point */
    rcClip.left   = pt.x;
    rcClip.top    = pt.y;
    rcClip.right  = pt.x;
    rcClip.bottom = pt.y;

    /* Eat mouse messages until a WM_LBUTTONUP is encountered. Meanwhile
     * continue to draw a rubberbanding rectangle and display it's dimensions
     */
    for (;;){
  WaitMessage();
  if (PeekMessage(&msg,NULL,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE)){
            DrawSelect(hdc,FALSE);

            rcClip.left   = pt.x;
            rcClip.top    = pt.y;
            rcClip.right  = LOWORD(msg.lParam) + ptOrigin.x;
            rcClip.bottom = HIWORD(msg.lParam) + ptOrigin.y;

            NormalizeRect(&rcClip);
            DrawSelect(hdc,TRUE);

            if (msg.message == WM_LBUTTONUP)
    break;
        }
  else
      continue;
    }

    ReleaseCapture();
    ReleaseDC(hwnd,hdc);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : BandDIB(HWND hWnd, HDC hDC, int x, int y)        *
 *                      *
 *  PURPOSE    : Outputs the DIB in bands to a device or the screen, using  *
 *     the maximum possible band size.          *
 *                      *
 ****************************************************************************
void BandDIB (hWnd, hDC, x, y)
HWND hWnd;
HDC hDC;
int x, y;
{
    HBITMAP         hBitmap, hOld ;
    HDC          hMemDC ;
    LPSTR         pBuf;
    LPBITMAPINFOHEADER lpbi;
    WORD         wRead, wActualPosition, wScansLeft  ;
    DWORD         dwMapSize;
    DWORD         dwScans;
    WORD         wBitmapHeight;
    RECT         Rect;
    HANDLE         hBuf;
    BOOL         bSuccess = FALSE;
    int          nBandSize;
    HPALETTE         hOldMemPal;
    HPALETTE         hOldPal;
    int          fh;
    OFSTRUCT         of;

    /* Open the map file and get the information out */
    fh = OpenFile (achFileName, (LPOFSTRUCT)&of, OF_READ);

    if (fh == -1)
  return;
    lpbi = (VOID FAR *)GlobalLock(hbiCurrent);
    if (!lpbi){
  _lclose (fh);
  return;
    }

    /* Compute scan size in bytes */
    dwScans = WIDTHBYTES((DWORD)lpbi->biWidth * lpbi->biBitCount);

    wBitmapHeight = (WORD)lpbi->biHeight ;
    wScansLeft    = (WORD)lpbi->biHeight ;

    hMemDC = NULL;
    for ( nBandSize = wScansLeft;
    nBandSize >= MINBAND || nBandSize == wScansLeft;
    nBandSize -= BANDINCREMENT) {

  /* Attempt to maximize band size by trying to allocate a buffer
   * for the given band size. If allocation fails, try again with the
   * smaller band size.
   */
  hBuf = GlobalAlloc (GMEM_FIXED | GMEM_ZEROINIT, dwScans * nBandSize) ;
  if (!hBuf)
      continue;

  /* Show success and exit loop if we're going to set bits to device. */
  if (bDIBToDevice) {
      hMemDC = 1;
      break;
  }
  else {
      /* Create a device-dependent bitmap to hold the bits */
      hBitmap = CreateCompatibleBitmap (hDC,
                (WORD)lpbi->biWidth,
                nBandSize);
      if (!hBitmap) {
    /* Try again for the next smaller band size */
    GlobalFree (hBuf);
    continue;
      }

      /* Create a memory context for the bitmap */
      if (!(hMemDC = CreateCompatibleDC (hDC))) {
    GlobalFree (hBuf);
    DeleteObject (hBitmap);
    continue;
      } else
    /* Success in creating a DC */
    break;
  }
    }
    if (!hMemDC) {

  /* We failed allocation , so give error message and quit */
  if (GetFocus () == hWnd) {
      ErrMsg ("No memory available!");
      ValidateRect (hWnd, (LPRECT) (NULL));
  } else
      MessageBeep(0);

  GlobalUnlock(hbiCurrent);
  _lclose (fh);
  return;
    }
    pBuf = GlobalLock (hBuf);

    /* Calculate number of bytes to be transferred */
    dwMapSize = dwScans * nBandSize ;

    /* Manipulate palette appropriately */
    if (!bDIBToDevice)
  hOldMemPal = SelectPalette (hMemDC, hpalCurrent, 0) ;

    /* Now get to the start of the map in the file */
    _llseek(fh, dwOffset, SEEK_SET);

    /* we are now all set to start off */
    wActualPosition = wScansLeft ;

    Rect.left  = 0;
    Rect.right = (WORD)lpbi->biWidth;

    hOldPal = SelectPalette(hDC, hpalCurrent, 0);
    RealizePalette(hDC);

    do {
  /* Read in nBandSize scans or whatever is left */
  if (wScansLeft > nBandSize)
      wRead = nBandSize ;
  else
      wRead = wScansLeft ;

  Rect.bottom = wActualPosition;
  wActualPosition -= wRead ;
  Rect.top = wActualPosition;

  dwMapSize = ((DWORD) wRead) * dwScans ;

  /* Now read in the map to the global buffer */
  if (RectVisible (hDC, &Rect)) {
      lread(fh, (LPSTR)pBuf, dwMapSize);

      if (bDIBToDevice) {
    if (wRead != SetDIBitsToDevice (hDC, x, y,
            (WORD)lpbi->biWidth,
            wBitmapHeight,
            0,
            0,
            wBitmapHeight - wScansLeft,
            wRead,
            pBuf,
            (LPBITMAPINFO)lpbi,
            fPalColors ?
            DIB_PAL_COLORS :
            DIB_RGB_COLORS)){
        ErrMsg ("Could not draw DIB scans to device!");
        GlobalUnlock (hBuf);
        GlobalFree (hBuf);
        GlobalUnlock(hbiCurrent);
        _lclose (fh);
        return;
    }
      } else {
    lpbi->biHeight = wRead ;

    /* Set the DIB bits to a device-dependent format */
    if ((WORD)lpbi->biHeight != SetDIBits (hMemDC,
                   hBitmap,
                   0,
                   (WORD)lpbi->biHeight,
                   pBuf,
                   (LPBITMAPINFO)lpbi,
                   fPalColors ?
                   DIB_PAL_COLORS :
                   DIB_RGB_COLORS)){
        ErrMsg ("Could not draw DIB scans!");
        GlobalUnlock (hBuf);
        GlobalFree (hBuf);
        GlobalUnlock(hbiCurrent);
        _lclose (fh);
        return;
    }

    /* Blt own map onto the screen, remembering the point to start */
    hOld = SelectObject (hMemDC, hBitmap) ;
    if (!BitBlt (hDC, 0, wActualPosition,
           (WORD)lpbi->biWidth,
           (WORD)lpbi->biHeight,
           hMemDC, 0, 0, SRCCOPY)){
        ErrMsg ("Could not draw map to screen!");
        GlobalUnlock (hBuf);
        GlobalFree (hBuf);
        GlobalUnlock(hbiCurrent);
        _lclose (fh);
        return;
    }
    SelectObject (hMemDC, hOld) ;

    /* Restore the value of bitmap height */
    lpbi->biHeight = wBitmapHeight ;
      }
  }
  else {
      /* This chunk is not visible, seek over the data in the file */
      _llseek(fh, dwMapSize, SEEK_CUR);
  }
  wScansLeft -= wRead ;
    } while (wScansLeft > 0 ) ;

    /* Delete the objects just created above */
    GlobalUnlock (hBuf);
    GlobalFree (hBuf);
    SelectPalette (hDC, hOldPal, 0);

    /* Set success flag */
    bSuccess = TRUE;

    if (!bDIBToDevice) {
  SelectPalette (hMemDC, hOldMemPal, 0);
  DeleteDC (hMemDC) ;
  DeleteObject (hBitmap) ;
    }
    GlobalUnlock(hbiCurrent);

    /* Close the file */
    _lclose (fh);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : SizeWindow(HWND hWnd)              *
 *                      *
 *  PURPOSE    : Sizes the app. window based on client dimensions (DIB      *
 *     dimensions) and style. Sets the caption text.        *
 *                      *
 ****************************************************************************
void SizeWindow (hWnd)
HWND hWnd;
{
    char  *pstr;
    char  Name[60];
    RECT  Rectangle;
    int   dx,dy;
    POINT pt;
    BITMAPINFOHEADER bi;

    /* Get information about current DIB */
    DibInfo(hbiCurrent,&bi);

    /* Extract the filename from the full pathname */
    pstr = achFileName + lstrlen(achFileName) - 1;
    while ((*pstr != '\\') && (*pstr != ':') && (pstr >= achFileName))
      pstr--;
    pstr++;

    /* Format filename along with the DIB attributes */
    wsprintf (Name,
        "%ls (%ls %dx%dx%d%ls)",
        (LPSTR)szAppName,
        (LPSTR)pstr,
        (WORD)bi.biWidth,
        (WORD)bi.biHeight,
        (WORD)bi.biBitCount,
        bi.biCompression == BI_RGB  ? (LPSTR)" RGB" :
        bi.biCompression == BI_RLE8 ? (LPSTR)" RLE8" : (LPSTR)" RLE4" );

    /* Show formatted text in the caption bar */
    SetWindowText (hWnd, Name);

    /* Store the size in ptSize, so the scroll bars will work. */
    ptSize.x = (WORD)bi.biWidth;
    ptSize.y = (WORD)bi.biHeight;

    if (IsZoomed (hWnd))
  SetScrollRanges (hWnd);
    else {
  Rectangle.left   = 0;
  Rectangle.top   = 0;
  Rectangle.right  = (WORD)bi.biWidth;
  Rectangle.bottom = (WORD)bi.biHeight;

  /* Compute the size of the window rectangle based on the given
   * client rectangle size and the window style, then size the
   * window.
   */
  AdjustWindowRect (&Rectangle, dwStyle, TRUE);
  SetWindowPos (hWnd, (HWND)NULL, 0, 0,
          Rectangle.right  - Rectangle.left + 1,
          Rectangle.bottom - Rectangle.top + 1,
          SWP_NOMOVE | SWP_NOZORDER);
    }

    InvalidateRect(hWnd,NULL,TRUE);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : GetRealClientRect(HWND hwnd, LPRECT lprc)        *
 *                      *
 *  PURPOSE    : Calculates the client rectangle taking scrollbars into     *
 *     consideration.               *
 *                      *
 ****************************************************************************
void GetRealClientRect (hwnd, lprc)
HWND hwnd;
PRECT lprc;
{
    DWORD dwStyle;

    dwStyle = GetWindowLong (hwnd, GWL_STYLE);
    GetClientRect (hwnd,lprc);

    if (dwStyle & WS_HSCROLL)
  lprc->bottom += GetSystemMetrics (SM_CYHSCROLL);

    if (dwStyle & WS_VSCROLL)
  lprc->right  += GetSystemMetrics (SM_CXVSCROLL);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : SetScrollRanges(hwnd)              *
 *                      *
 *  PURPOSE    :                  *
 *                      *
 ****************************************************************************
void SetScrollRanges(hwnd)

HWND hwnd;
{
    RECT       rc;
    int        iRangeH, iRangeV, i;
    static int iSem = 0;

    if (!iSem){
        iSem++;
  GetRealClientRect (hwnd, &rc);

  for (i = 0; i < 2; i++){
            iRangeV = ptSize.y - rc.bottom;
            iRangeH = ptSize.x - rc.right;

            if (iRangeH < 0) iRangeH = 0;
            if (iRangeV < 0) iRangeV = 0;

      if (GetScrollPos ( hwnd,
             SB_VERT) > iRangeV ||
             GetScrollPos (hwnd, SB_HORZ) > iRangeH)
    InvalidateRect (hwnd, NULL, TRUE);

      SetScrollRange (hwnd, SB_VERT, 0, iRangeV, TRUE);
      SetScrollRange (hwnd, SB_HORZ, 0, iRangeH, TRUE);

      GetClientRect (hwnd, &rc);
        }
        iSem--;
    }
}

/*********** THE FOLLOWING FUNCTIONS ARE FOR CLIPBOARD SUPPORT **************
/****************************************************************************
 *                      *
 *  FUNCTION   : CopyHandle (HANDLE h)              *
 *                      *
 *  PURPOSE    : Makes a copy of the given global memory block.       *
 *                      *
 *  RETURNS    : A handle to the new block.            *
 *                      *
 ****************************************************************************
HANDLE CopyHandle (h)
HANDLE h;
{
    BYTE huge *lpCopy;
    BYTE huge *lp;
    HANDLE hCopy;
    DWORD  dwLen;

    dwLen = GlobalSize (h);
    if (hCopy = GlobalAlloc (GHND, dwLen)) {

  lpCopy = (BYTE huge *)GlobalLock (hCopy);
  lp     = (BYTE huge *)GlobalLock (h);
  while (dwLen--) *lpCopy++ = *lp++;
  GlobalUnlock (hCopy);
  GlobalUnlock (h);
    }
    return hCopy;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : CopyPalette(HPALETTE hpal)            *
 *                      *
 *  PURPOSE    : Makes a copy of a GDI logical palette          *
 *                      *
 *  RETURNS    : A handle to the new palette.            *
 *                      *
 ****************************************************************************
HPALETTE CopyPalette (hpal)
HPALETTE hpal;
{
    PLOGPALETTE ppal;
    int         nNumEntries;

    if (!hpal)
  return NULL;

    GetObject(hpal,sizeof(int),(LPSTR)&nNumEntries);

    if (nNumEntries == 0)
        return NULL;

    ppal = (PLOGPALETTE)LocalAlloc(LPTR,sizeof(LOGPALETTE) +
                nNumEntries * sizeof(PALETTEENTRY));

    if (!ppal)
        return NULL;

    ppal->palVersion    = PALVERSION;
    ppal->palNumEntries = nNumEntries;

    GetPaletteEntries(hpal,0,nNumEntries,ppal->palPalEntry);

    hpal = CreatePalette(ppal);

    LocalFree((HANDLE)ppal);
    return hpal;
}
/****************************************************************************
 *                      *
 *  FUNCTION   : CopyBitmap (HBITMAP hbm)            *
 *                      *
 *  PURPOSE    : Copies the given bitmap to another.          *
 *                      *
 *  RETURNS    : A handle to the new bitmap.            *
 *                      *
 ****************************************************************************
HBITMAP CopyBitmap (hbm)
HBITMAP hbm;
{
    BITMAP  bm;
    RECT    rc;

    if (!hbm)
         return NULL;

    GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm);
    rc.left   = 0;
    rc.top    = 0;
    rc.right  = bm.bmWidth;
    rc.bottom = bm.bmHeight;

    return CropBitmap (hbm, &rc);
}
/****************************************************************************
 *                      *
 *  FUNCTION   :  CropBitmap (hbm,lprect)            *
 *                      *
 *  PURPOSE    :  Crops a bitmap to a new size specified by the lprect      *
 *      parameter.                *
 *                      *
 *  RETURNS    :  A handle to the new bitmap.            *
 *                      *
 ****************************************************************************
HBITMAP CropBitmap (hbm, prc)
HBITMAP hbm;
PRECT prc;
{
    HDC     hMemDCsrc;
    HDC     hMemDCdst;
    HDC     hdc;
    HBITMAP hNewBm;
    BITMAP  bm;
    int     dx,dy;

    if (!hbm)
         return NULL;

    hdc = GetDC (NULL);
    hMemDCsrc = CreateCompatibleDC (hdc);
    hMemDCdst = CreateCompatibleDC (hdc);

    GetObject (hbm, sizeof(BITMAP), (LPSTR)&bm);
    dx = prc->right  - prc->left;
    dy = prc->bottom - prc->top;

    hNewBm = CreateBitmap (dx, dy, bm.bmPlanes, bm.bmBitsPixel, NULL);
    if (hNewBm){
  SelectObject (hMemDCsrc, hbm);
  SelectObject (hMemDCdst, hNewBm);

  BitBlt (hMemDCdst,
    0,
    0,
    dx,
    dy,
    hMemDCsrc,
    prc->left,
    prc->top,
    SRCCOPY);
    }

    ReleaseDC (NULL,hdc);
    DeleteDC (hMemDCsrc);
    DeleteDC (hMemDCdst);
    return hNewBm;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : RenderFormat(int cf)              *
 *                      *
 *  PURPOSE    : Renders the currently displayed DIB in CF_DIB or      *
 *     CF_BITMAP format.The bitmap is clipped to the current      *
 *     rcClip.                *
 *                      *
 *  RETURNS    : A handle to the DIB              *
 *                      *
 ****************************************************************************
HANDLE RenderFormat (cf)
int cf;
{
    HANDLE  h = NULL;
    HBITMAP hbm;

    if (!bLegitDraw)
        return NULL;

    switch (cf){
        case CF_BITMAP:
      if (hbmCurrent && !IsRectEmpty (&rcClip))
    h = CropBitmap (hbmCurrent, &rcClip);
      else{
                if (hbmCurrent)
        h = CopyBitmap (hbmCurrent);
                else if (hdibCurrent)
        h = BitmapFromDib (hdibCurrent, hpalCurrent);
    else if (achFileName[0] && (hdibCurrent = OpenDIB (achFileName)))
        h = BitmapFromDib (hdibCurrent, hpalCurrent);
                else
                    h = NULL;

    if (h && !IsRectEmpty (&rcClip)){
        hbm = CropBitmap (h,&rcClip);
        DeleteObject (h);
                    h = hbm;
                }
            }
            break;

        case CF_DIB:
      if (!IsRectEmpty (&rcClip)){
    if (hbm = RenderFormat (CF_BITMAP)){
        h = DibFromBitmap (hbm, BI_RGB, 0, hpalCurrent);
        DeleteObject (hbm);
                }
            }
      else{
                if (!hdibCurrent && hbmCurrent)
        h = DibFromBitmap (hbmCurrent, BI_RGB, 0, hpalCurrent);
                else if (hdibCurrent)
        h = CopyHandle (hdibCurrent);
                else if (achFileName[0])
        h = OpenDIB (achFileName);
                else
                    h = NULL;
            }
            break;

        case CF_PALETTE:
            if (hpalCurrent)
    h = CopyPalette (hpalCurrent);
            break;
    }
    return h;
}
/****************************************************************************
 *                      *
 *  FUNCTION   :  RealizeDibFormat(DWORD biStyle, WORD biBits)        *
 *                      *
 *  PURPOSE    :  Realize the current DIB in the specifed format      *
 *      This function is used to get a specific format of CF_DIB  *
 *                      *
 *          biStyle    DIB format    RGB or RLE        *
 *          biBits    Bits per pixel  1,4,8,24        *
 *                      *
 *  RETURNS    :  A handle to the created DIB.            *
 *                      *
 ****************************************************************************
HANDLE RealizeDibFormat (biStyle, biBits)
DWORD biStyle;
WORD biBits;
{
    BITMAPINFOHEADER bi;

    if (!bLegitDraw)
        return NULL;

    DibInfo (hbiCurrent, &bi);

    /*  Do we have the requested format already? */
    if (bi.biCompression == biStyle && bi.biBitCount == biBits){
        if (!hdibCurrent)
      hdibCurrent = RenderFormat (CF_DIB);
    }
    else{
        if (!hbmCurrent)
      hbmCurrent = RenderFormat (CF_BITMAP);

  if (hbmCurrent){
            if (hdibCurrent)
    GlobalFree (hdibCurrent);

      hdibCurrent = DibFromBitmap (hbmCurrent, biStyle, biBits, hpalCurrent);
        }
    }

    return hdibCurrent;
}
/****************************************************************************
 *                      *
 *  FUNCTION   : ErrMsg (PSTR sz,...)              *
 *                      *
 *  PURPOSE    : Opens a Message box with a error message in it.The user can*
 *     select the OK button to continue          *
 *                      *
 *  RETURNS    : FALSE to indicate an error has occured.        *
 *                      *
 ****************************************************************************
int ErrMsg (PSTR sz,...)
{
    char ach[128];

    wvsprintf (ach, sz, (LPSTR)(&sz+1));   /* Format the string */
    MessageBox (NULL, ach, NULL, MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
    return FALSE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : fDialog(int id,HWND hwnd,FARPROC fpfn)         *
 *                      *
 *  PURPOSE    : This function displays a dialog box          *
 *                      *
 *  RETURNS    : The exit code.               *
 *                      *
 ****************************************************************************
BOOL fDialog (id, hwnd, fpfn)
int id;
HWND hwnd;
FARPROC fpfn;
{
    BOOL  f;
    HANDLE  hInst;

    hInst = GetWindowWord (hwnd, GWW_HINSTANCE);
    fpfn  = MakeProcInstance (fpfn, hInst);
    f = DialogBox (hInst, MAKEINTRESOURCE(id), hwnd, fpfn);
    FreeProcInstance (fpfn);
    return f;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : AppAbout( hDlg, uiMessage, wParam, lParam )        *
 *                      *
 *  PURPOSE    : Dialog function for the About... dialog box        *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL AppAbout( hDlg, uiMessage, wParam, lParam )

HWND   hDlg;
unsigned uiMessage;
WORD   wParam;
long   lParam;
{
    switch (uiMessage) {
        case WM_COMMAND:
            if (wParam == IDOK)
    EndDialog (hDlg, TRUE);
      break;

  case WM_INITDIALOG:
      return TRUE;
    }
    return FALSE;
}


EDITCNTL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\EDITCNTL\EDITCNTL.C

/****************************************************************************

    PROGRAM: EditCntl.c

    PURPOSE: Creates an edit window

    FUNCTIONS:

  WinMain() - calls initialization function, processes message loop
  InitApplication() - initializes window data and registers window
  InitInstance() - saves instance handle and creates main window
  MainWndProc() - processes messages
  About() - processes messages for "About" dialog box

    COMMENTS:

  After setting up the application's window, the size of the client
  area is determined and a child window is created to use for editing.

****************************************************************************/

#include "windows.h"
#include "editcntl.h"

HANDLE hInst;

HANDLE hAccTable;                                /* handle to accelerator tab
HWND hEditWnd;              /* handle to edit window */
HWND hwnd;                    /* handle to main windows  */

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
  if (!InitApplication(hInstance))
      return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {

    /* Only translate message if it is not an accelerator message */

        if (!TranslateAccelerator(hwnd, hAccTable, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "EditCntlMenu";
    wc.lpszClassName = "EditCntlWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    RECT            Rect;

    hInst = hInstance;

    hAccTable = LoadAccelerators(hInst, "EditCntlAcc");

    hwnd = CreateWindow(
        "EditCntlWClass",
        "EditCntl Sample Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hwnd)
        return (FALSE);

    GetClientRect(hwnd, (LPRECT) &Rect);

    /* Create a child window */

    hEditWnd = CreateWindow("Edit",
  NULL,
  WS_CHILD | WS_VISIBLE |
  ES_MULTILINE |
  WS_VSCROLL | WS_HSCROLL |
  ES_AUTOHSCROLL | ES_AUTOVSCROLL,
  0,
  0,
  (Rect.right-Rect.left),
  (Rect.bottom-Rect.top),
  hwnd,
  IDC_EDIT,                          /* Child control i.d. */
  hInst,
  NULL);

    if (!hEditWnd) {
  DestroyWindow(hwnd);
  return (NULL);
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

  WM_COMMAND    - application menu (About dialog box)
  WM_DESTROY    - destroy window

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout;

    switch (message) {
  case WM_COMMAND:
            switch (wParam) {
                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
                    FreeProcInstance(lpProcAbout);
                    break;

                /* file menu commands */

                case IDM_NEW:
                case IDM_OPEN:
                case IDM_SAVE:
                case IDM_SAVEAS:
                case IDM_PRINT:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "EditCntl Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;

                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;

                /* edit menu commands */

                case IDM_UNDO:
                case IDM_CUT:
                case IDM_COPY:
                case IDM_PASTE:
                case IDM_CLEAR:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "EditCntl Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;

                case IDC_EDIT:
                    if (HIWORD (lParam) == EN_ERRSPACE) {
                        MessageBox (
                              GetFocus ()
                            , "Out of memory."
                            , "EditCntl Sample Application"
                            , MB_ICONHAND | MB_OK
                        );
                    }
                    break;

            }
            break;

        case WM_SETFOCUS:
            SetFocus (hEditWnd);
            break;

        case WM_SIZE:
            MoveWindow(hEditWnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
            break;

  case WM_DESTROY:
      PostQuitMessage(0);
      break;

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


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}


EDITFILE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\EDITFILE\EDITFILE.C

/****************************************************************************

    PROGRAM: EditFile.c

    PURPOSE: Loads, saves, and edits text files

    FUNCTIONS:

        WinMain() - calls initialization function, processes message loop
        InitApplication() - initializes window data and registers window
        InitInstance() - saves instance handle and creates main window
        MainWndProc() - processes messages
        About() - processes messages for "About" dialog box
        SaveAsDlg() - save file under different name
        OpenDlg() - let user select a file, and open it.
        UpdateListBox() - Update the list box of OpenDlg
        ChangeDefExt() - Change the default extension
        SeparateFile() - Separate filename and pathname
        AddExt() - Add default extension
        CheckFileName() - Check for wildcards, add extension if needed
        SaveFile() - Save current file
        QuerySaveFile() - Called when some action might lose current contents
        SetNewBuffer() - Set new buffer for edit window

****************************************************************************/

#include "windows.h"
#include "editfile.h"

HANDLE hInst;

HANDLE hAccTable;                                /* handle to accelerator tab
HWND hEditWnd;                                      /* handle to edit window
/* Additional includes needed for the fstat() function */

#include <sys\types.h>
#include <sys\stat.h>

char FileName[128];
char PathName[128];
char OpenName[128];
char DefPath[128];
char DefSpec[13] = "*.*";
char DefExt[] = ".txt";
char str[255];

HANDLE hEditBuffer;                       /* handle to editing buffer      */
HANDLE hOldBuffer;                        /* old buffer handle        */
HANDLE hHourGlass;                        /* handle to hourglass cursor
HANDLE hSaveCursor;                       /* current cursor handle      */
int hFile;                                /* file handle              */
int count;                                /* number of chars read or written
PSTR pBuffer;                             /* address of read/write buffer
OFSTRUCT OfStruct;                        /* information from OpenFile()
struct stat FileStatus;                   /* information from fstat()      */
BOOL bChanges = FALSE;                    /* TRUE if the file is changed
BOOL bSaveEnabled = FALSE;                /* TRUE if text in the edit buffer
PSTR pEditBuffer;                         /* address of the edit buffer
RECT Rect;                                /* dimension of the client window
HWND hwnd;                                /* handle to main window


char Untitled[] =                         /* default window title      */
     "Edit File - (untitled)";

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
        if (!InitApplication(hInstance))
            return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {

    /* Only translate message if it is not an accelerator message */

        if (!TranslateAccelerator(hwnd, hAccTable, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "EditFileMenu";
    wc.lpszClassName = "EditFileWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    RECT            Rect;

    hInst = hInstance;

    hAccTable = LoadAccelerators(hInst, "EditFileAcc");

    hwnd = CreateWindow(
        "EditFileWClass",
        "EditFile Sample Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hwnd)
        return (FALSE);

    GetClientRect(hwnd, (LPRECT) &Rect);

    /* Create a child window */

    hEditWnd = CreateWindow("Edit",
        NULL,
        WS_CHILD | WS_VISIBLE |
        ES_MULTILINE |
        WS_VSCROLL | WS_HSCROLL |
        ES_AUTOHSCROLL | ES_AUTOVSCROLL,
        0,
        0,
        (Rect.right-Rect.left),
        (Rect.bottom-Rect.top),
        hwnd,
        IDC_EDIT,                          /* Child control i.d. */
        hInst,
        NULL);

    if (!hEditWnd) {
        DestroyWindow(hwnd);
        return (NULL);
    }

    /* Get an hourglass cursor to use during file transfers */

    hHourGlass = LoadCursor(NULL, IDC_WAIT);

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

        WM_COMMAND    - application menu (About dialog box)
        WM_DESTROY    - destroy window
        WM_SIZE       - window size has changed
        WM_QUERYENDSESSION - willing to end session?
        WM_ENDSESSION - end Windows session
        WM_CLOSE      - close the window
        WM_SIZE       - window resized

    COMMENTS:

        WM_COMMAND processing:

            IDM_NEW - query to save current file if there is one and it has
                      been changed, clear buffer and start new file.

            IDM_OPEN - query to save current file if there is one and it
                       has been changed, open a new file.

            IDM_SAVE - save current file, prompt for name if none exists.

            IDM_SAVEAS - prompt for new filename to save to, save file.

            IDC_EDIT - change "bChanges" flag to indicate if edit buffer has
                      been modified.  Affects actions of IDM_NEW and
                      IDM_OPEN.  Reset when file is saved.

            IDM_EXIT - query to save current file if there is one and it
                       has been changed, then exit.

            IDM_ABOUT - display "About" box.

        When more then one string needs to be sent to a message box,
        sprintf() is used to combine the strings into str[], and then str[]
        is passed to the MessageBox() function.  A message box string cannot
        exceed 255 characters, but may contain \n to generate separate
        lines.

        After the size of the file is determined, only enough memory to store
        the file is allocated for the Edit buffer.  The edit control will
        automatically expand this memory as needed.  Once the file has been
        read into the edit buffer, unlock the memory.  Use whatever was
        obtained from the read() function, even if an error occured.  This
        allows partial salvage of a file with a bad sector.

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout, lpOpenDlg, lpSaveAsDlg;

    int Success;                            /* return value from SaveAsDlg()
    int IOStatus;                           /* result of file i/o      */


    switch (message) {
        case WM_COMMAND:
            switch (wParam) {
                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
                    FreeProcInstance(lpProcAbout);
                    break;

                case IDM_NEW:

                    /* If current file has been modified, query user about
                     * saving it.
                     */

                    if (!QuerySaveFile(hWnd))
                        return (NULL);

                    /* bChanges is set to FALSE to indicate there have been
                     * no changes since the last file save.
                     */

                    bChanges = FALSE;
                    FileName[0] = 0;

                    /* Update the edit buffer */

                    SetNewBuffer(hWnd, NULL, Untitled);
                    break;

                case IDM_OPEN:
                    if (!QuerySaveFile(hWnd))
                        return (NULL);

                    lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);

                    /* Open the file and get its handle */

                    hFile = DialogBox(hInst, "Open", hWnd, lpOpenDlg);
                    FreeProcInstance(lpOpenDlg);
                    if (!hFile)
                        return (NULL);

                    /* Allocate edit buffer to the size of the file + 1 */

                    hEditBuffer =
                        LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,
          (WORD)(FileStatus.st_size+1));

                    if (!hEditBuffer) {
                        MessageBox(hWnd, "Not enough memory.",
                            NULL, MB_OK | MB_ICONHAND);
                        return (NULL);
                    }
                    hSaveCursor = SetCursor(hHourGlass);
                    pEditBuffer = LocalLock(hEditBuffer);

                    IOStatus = read(hFile, pEditBuffer, FileStatus.st_size);
                    close(hFile);

                    /* # bytes read must equal file size */

                    if (IOStatus != FileStatus.st_size) {

                        sprintf(str, "Error reading %s.", FileName);
                        SetCursor(hSaveCursor);      /* Remove the hourglass
                        MessageBox(hWnd, str, NULL, MB_OK | MB_ICONEXCLAMATIO
                    }

                    LocalUnlock(hEditBuffer);

                    /* Set up a new buffer and window title */

                    sprintf(str, "EditFile - %s", FileName);
                    SetNewBuffer(hWnd, hEditBuffer, str);
                    SetCursor(hSaveCursor);            /* restore the cursor
                    break;

                case IDM_SAVE:

                    /* If there is no filename, use the saveas command to get
                     * one.  Otherwise, save the file using the current
                     * filename.
                     */

                    if (!FileName[0])
                        goto saveas;
                    if (bChanges)
                        SaveFile(hWnd);
                    break;

                case IDM_SAVEAS:
saveas:
                    lpSaveAsDlg = MakeProcInstance(SaveAsDlg, hInst);

                    /* Call the SaveAsDlg() function to get the new filename

                    Success = DialogBox(hInst, "SaveAs", hWnd, lpSaveAsDlg);
                    FreeProcInstance(lpSaveAsDlg);

                    /* If successful, update the window title, save the file

                    if (Success == IDOK) {
                        sprintf(str, "EditFile - %s", FileName);
                        SetWindowText(hWnd, str);
                        SaveFile(hWnd);
                    }
                    break;                                  /* User canceled
                case IDM_PRINT:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "EditFile Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;

                /* edit menu commands */

                case IDM_UNDO:
                case IDM_CUT:
                case IDM_COPY:
                case IDM_PASTE:
                case IDM_CLEAR:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "EditFile Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;

                case IDM_EXIT:
                    QuerySaveFile(hWnd);
                    DestroyWindow(hWnd);
                    break;

                case IDC_EDIT:
                    if (HIWORD (lParam) == EN_ERRSPACE) {
                        MessageBox (
                              GetFocus ()
                            , "Out of memory."
                            , "EditFile Sample Application"
                            , MB_ICONHAND | MB_OK
                        );
                    }
                    break;

            }
            break;

        case WM_SETFOCUS:
            SetFocus (hEditWnd);
            break;

        case WM_SIZE:
            MoveWindow(hEditWnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
            break;

        case WM_QUERYENDSESSION:             /* message: to end the session?
            return (QuerySaveFile(hWnd));

        case WM_CLOSE:                       /* message: close the window
            if (QuerySaveFile(hWnd))
                DestroyWindow(hWnd);
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

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

/****************************************************************************

    FUNCTION: SaveAsDlg(HWND, unsigned, WORD, LONG)

    PURPOSE: Allows user to change name to save file to

    COMMENTS:

        This will initialize the window class if it is the first time this
        application is run.  It then creates the window, and processes the
        message loop until a PostQuitMessage is received.  It exits the
        application by returning the value passed by the PostQuitMessage.

****************************************************************************/

int FAR PASCAL SaveAsDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    char TempName[128];

    switch (message) {
        case WM_INITDIALOG:

            /* If no filename is entered, don't allow the user to save to it

            if (!FileName[0])
                bSaveEnabled = FALSE;
            else {
                bSaveEnabled = TRUE;

                /* Process the path to fit within the IDC_PATH field */

                DlgDirList(hDlg, DefPath, NULL, IDC_PATH, 0x4010);

                /* Send the current filename to the edit control */

                SetDlgItemText(hDlg, IDC_EDIT, FileName);

                /* Accept all characters in the edit control */

                SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL, 0,
                    MAKELONG(0, 0x7fff));
            }

            /* Enable or disable the save control depending on whether the
             * filename exists.
             */

            EnableWindow(GetDlgItem(hDlg, IDOK), bSaveEnabled);

            /* Set the focus to the edit control within the dialog box */

            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE);                 /* FALSE since Focus was changed

        case WM_COMMAND:
            switch (wParam) {
                case IDC_EDIT:

                    /* If there was previously no filename in the edit
                     * control, then the save control must be enabled as soon
                     * a character is entered.
                     */

                    if (HIWORD(lParam) == EN_CHANGE && !bSaveEnabled)
                    EnableWindow(GetDlgItem(hDlg, IDOK), bSaveEnabled = TRUE)
                    return (TRUE);

                case IDOK:

                   /* Get the filename from the edit control */

                    GetDlgItemText(hDlg, IDC_EDIT, TempName, 128);

                    /* If there are no wildcards, then separate the name into
                     * path and name.  If a path was specified, replace the
                     * default path with the new path.
                     */

                    if (CheckFileName(hDlg, FileName, TempName)) {
                        SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,
                            (LPSTR) FileName);
                        if (str[0])
                            strcpy(DefPath, str);

                        /* Tell the caller a filename was selected */

                        EndDialog(hDlg, IDOK);
                    }
                    return (TRUE);

                case IDCANCEL:

                    /* Tell the caller the user canceled the SaveAs function

                    EndDialog(hDlg, IDCANCEL);
                    return (TRUE);
            }
            break;

    }
    return (FALSE);
}

/****************************************************************************

    FUNCTION: OpenDlg(HWND, unsigned, WORD, LONG)

    PURPOSE: Let user select a file, and open it.

****************************************************************************/

HANDLE FAR PASCAL OpenDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    WORD index;
    PSTR pTptr;
    HANDLE hFile;

    switch (message) {
        case WM_COMMAND:
            switch (wParam) {

                case IDC_LISTBOX:
                    switch (HIWORD(lParam)) {

                        case LBN_SELCHANGE:
                            /* If item is a directory name, append "*.*" */
                            if (DlgDirSelect(hDlg, str, IDC_LISTBOX))
                                strcat(str, DefSpec);

                            SetDlgItemText(hDlg, IDC_EDIT, str);
                            SendDlgItemMessage(hDlg,
                                IDC_EDIT,
                                EM_SETSEL,
                                NULL,
                                MAKELONG(0, 0x7fff));
                            break;

                        case LBN_DBLCLK:
                            goto openfile;
                    }
                    return (TRUE);

                case IDOK:
openfile:
                    GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);
                    if (strchr(OpenName, '*') || strchr(OpenName, '?')) {
                        SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,
                            (LPSTR) OpenName);
                        if (str[0])
                            strcpy(DefPath, str);
                        ChangeDefExt(DefExt, DefSpec);
                        UpdateListBox(hDlg);
                        return (TRUE);
                    }

                    if (!OpenName[0]) {
                        MessageBox(hDlg, "No filename specified.",
                            NULL, MB_OK | MB_ICONHAND);
                        return (TRUE);
                    }

                    AddExt(OpenName, DefExt);

                    /* Open the file */

                    if ((hFile = OpenFile(OpenName, (LPOFSTRUCT) &OfStruct,
                            OF_READ)) == -1) {
                        sprintf(str, "Error %d opening %s.",
                            OfStruct.nErrCode, OpenName);
                        MessageBox(hDlg, str, NULL,
                            MB_OK | MB_ICONHAND);
                    }
                    else {

                        /* Make sure there's enough room for the file */

                        fstat(hFile, &FileStatus);
                        if (FileStatus.st_size > MAXFILESIZE) {
                            sprintf(str,
                    "Not enough memory to load %s.\n%s exceeds %ld bytes.",
                                OpenName, OpenName, MAXFILESIZE);
                            MessageBox(hDlg, str, NULL,
                                MB_OK | MB_ICONHAND);
                            return (TRUE);
                        }

                        /* File is opened and there is enough room so return
                         * the handle to the caller.
                         */

                        strcpy(FileName, OpenName);
                        EndDialog(hDlg, hFile);
                        return (TRUE);
                    }
                    return (TRUE);

                case IDCANCEL:
                    EndDialog(hDlg, NULL);
                    return (TRUE);
            }
            break;

        case WM_INITDIALOG:                        /* message: initialize
            UpdateListBox(hDlg);
            SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
            SendDlgItemMessage(hDlg,               /* dialog handle      */
                IDC_EDIT,                          /* where to send message
                EM_SETSEL,                         /* select characters
                NULL,                              /* additional information
                MAKELONG(0, 0x7fff));              /* entire contents      */
            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE); /* Indicates the focus is set to a control */
    }
    return FALSE;
}

/****************************************************************************

    FUNCTION: UpdateListBox(HWND);

    PURPOSE: Update the list box of OpenDlg

****************************************************************************/

void UpdateListBox(hDlg)
HWND hDlg;
{
    strcpy(str, DefPath);
    strcat(str, DefSpec);
    DlgDirList(hDlg, str, IDC_LISTBOX, IDC_PATH, 0x4010);

    /* To ensure that the listing is made for a subdir. of
     * current drive dir...
     */
    if (!strchr (DefPath, ':'))
  DlgDirList(hDlg, DefSpec, IDC_LISTBOX, IDC_PATH, 0x4010);

    /* Remove the '..' character from path if it exists, since this
     * will make DlgDirList move us up an additional level in the tree
     * when UpdateListBox() is called again.
     */
    if (strstr (DefPath, ".."))
  DefPath[0] = '\0';

    SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
}

/****************************************************************************

    FUNCTION: ChangeDefExt(PSTR, PSTR);

    PURPOSE: Change the default extension

****************************************************************************/

void ChangeDefExt(Ext, Name)
PSTR Ext, Name;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr)
        if (!strchr(pTptr, '*') && !strchr(pTptr, '?'))
            strcpy(Ext, pTptr);
}

/****************************************************************************

    FUNCTION: SeparateFile(HWND, LPSTR, LPSTR, LPSTR)

    PURPOSE: Separate filename and pathname

****************************************************************************/

void SeparateFile(hDlg, lpDestPath, lpDestFileName, lpSrcFileName)
HWND hDlg;
LPSTR lpDestPath, lpDestFileName, lpSrcFileName;
{
    LPSTR lpTmp;
    char  cTmp;

    lpTmp = lpSrcFileName + (long) lstrlen(lpSrcFileName);
    while (*lpTmp != ':' && *lpTmp != '\\' && lpTmp > lpSrcFileName)
        lpTmp = AnsiPrev(lpSrcFileName, lpTmp);
    if (*lpTmp != ':' && *lpTmp != '\\') {
        lstrcpy(lpDestFileName, lpSrcFileName);
        lpDestPath[0] = 0;
        return;
    }
    lstrcpy(lpDestFileName, lpTmp + 1);
    cTmp = *(lpTmp + 1);
    lstrcpy(lpDestPath, lpSrcFileName);
     *(lpTmp + 1) = cTmp;
    lpDestPath[(lpTmp - lpSrcFileName) + 1] = 0;
}

/****************************************************************************

    FUNCTION: AddExt(PSTR, PSTR);

    PURPOSE: Add default extension

/***************************************************************************/

void AddExt(Name, Ext)
PSTR Name, Ext;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr != '.')
        strcat(Name, Ext);
}

/****************************************************************************

    FUNCTION: CheckFileName(HWND, PSTR, PSTR)

    PURPOSE: Check for wildcards, add extension if needed

    COMMENTS:

        Make sure you have a filename and that it does not contain any
        wildcards.  If needed, add the default extension.  This function is
        called whenever your application wants to save a file.

****************************************************************************/

BOOL CheckFileName(hWnd, pDest, pSrc)
HWND hWnd;
PSTR pDest, pSrc;
{
    PSTR pTmp;

    if (!pSrc[0])
        return (FALSE);               /* Indicates no filename was specified

    pTmp = pSrc;
    while (*pTmp) {                     /* Searches the string for wildcards
        switch (*pTmp++) {
            case '*':
            case '?':
                MessageBox(hWnd, "Wildcards not allowed.",
                    NULL, MB_OK | MB_ICONEXCLAMATION);
                return (FALSE);
        }
    }

    AddExt(pSrc, DefExt);            /* Adds the default extension if needed

    if (OpenFile(pSrc, (LPOFSTRUCT) &OfStruct, OF_EXIST) >= 0) {
        sprintf(str, "Replace existing %s?", pSrc);
        if (MessageBox(hWnd, str, "EditFile",
                MB_OKCANCEL | MB_ICONHAND) == IDCANCEL)
            return (FALSE);
    }
    strcpy(pDest, pSrc);
    return (TRUE);
}

/****************************************************************************

    FUNCTION: SaveFile(HWND)

    PURPOSE: Save current file

    COMMENTS:

        This saves the current contents of the Edit buffer, and changes
        bChanges to indicate that the buffer has not been changed since the
        last save.

        Before the edit buffer is sent, you must get its handle and lock it
        to get its address.  Once the file is written, you must unlock the
        buffer.  This allows Windows to move the buffer when not in immediate
        use.

****************************************************************************/

BOOL SaveFile(hWnd)
HWND hWnd;
{
    BOOL bSuccess;
    int IOStatus;                                  /* result of a file write

    if ((hFile = OpenFile(FileName, &OfStruct,
        OF_PROMPT | OF_CANCEL | OF_CREATE)) < 0) {

        /* If the file can't be saved */

        sprintf(str, "Cannot write to %s.", FileName);
        MessageBox(hWnd, str, NULL, MB_OK | MB_ICONEXCLAMATION);
        return (FALSE);
    }


    hEditBuffer = SendMessage(hEditWnd, EM_GETHANDLE, 0, 0L);
    pEditBuffer = LocalLock(hEditBuffer);

    /* Set the cursor to an hourglass during the file transfer */

    hSaveCursor = SetCursor(hHourGlass);
    IOStatus = write(hFile, pEditBuffer, strlen(pEditBuffer));
    close(hFile);
    SetCursor(hSaveCursor);
    if (IOStatus != strlen(pEditBuffer)) {
        sprintf(str, "Error writing to %s.", FileName);
        MessageBox(hWnd, str,
            NULL, MB_OK | MB_ICONHAND);
        bSuccess = FALSE;
    }
    else {
        bSuccess = TRUE;                /* Indicates the file was saved
        bChanges = FALSE;               /* Indicates changes have been saved
    }

    LocalUnlock(hEditBuffer);
    return (bSuccess);
}

/****************************************************************************

    FUNCTION: QuerySaveFile(HWND);

    PURPOSE: Called when some action might lose current contents

    COMMENTS:

        This function is called whenever we are about to take an action that
        would lose the current contents of the edit buffer.

****************************************************************************/

BOOL QuerySaveFile(hWnd)
HWND hWnd;
{
    int Response;
    FARPROC lpSaveAsDlg;

    if (bChanges) {
        sprintf(str, "Save current changes: %s", FileName);
        Response = MessageBox(hWnd, str,
            "EditFile",  MB_YESNOCANCEL | MB_ICONEXCLAMATION);
        if (Response == IDYES) {
check_name:

            /* Make sure there is a filename to save to */

            if (!FileName[0]) {
                lpSaveAsDlg = MakeProcInstance(SaveAsDlg, hInst);
                Response = DialogBox(hInst, "SaveAs",
                    hWnd, lpSaveAsDlg);
                FreeProcInstance(lpSaveAsDlg);
                if (Response == IDOK)
                    goto check_name;
                else
                    return (FALSE);
            }
            SaveFile(hWnd);
        }
        else if (Response == IDCANCEL)
            return (FALSE);
    }
    else
        return (TRUE);
}

/****************************************************************************

    FUNCTION: SetNewBuffer(HWND, HANDLE, PSTR)

    PURPOSE: Set new buffer for edit window

    COMMENTS:

        Point the edit window to the new buffer, update the window title, and
        redraw the edit window.  If hNewBuffer is NULL, then create an empty
        1K buffer, and return its handle.

****************************************************************************/

void SetNewBuffer(hWnd, hNewBuffer, Title)
HWND hWnd;
HANDLE hNewBuffer;
PSTR Title;
{
    HANDLE hOldBuffer;

    hOldBuffer = SendMessage(hEditWnd, EM_GETHANDLE, 0, 0L);
    LocalFree(hOldBuffer);
    if (!hNewBuffer)                    /* Allocates a buffer if none exists
        hNewBuffer = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, 1);

    /* Updates the buffer and displays new buffer */
    SendMessage(hEditWnd, EM_SETHANDLE, hNewBuffer, 0L);

    SetWindowText(hWnd, Title);
    SetFocus(hEditWnd);
    bChanges = FALSE;
}


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

        WM_INITDIALOG - initialize dialog box
        WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:
            return (TRUE);

        case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
                EndDialog(hDlg, TRUE);
                return (TRUE);
            }
            break;
    }
    return (FALSE);
}


EDITMENU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\EDITMENU\EDITMENU.C

/****************************************************************************

    PROGRAM: EditMenu.c

    PURPOSE: EditMenu template for Windows applications

    FUNCTIONS:

  WinMain() - calls initialization function, processes message loop
  InitApplication() - initializes window data and registers window
  InitInstance() - saves instance handle and creates main window
  MainWndProc() - processes messages
  About() - processes messages for "About" dialog box

****************************************************************************/

#include "windows.h"
#include "editmenu.h"

HANDLE hInst;

HANDLE hAccTable;                                /* handle to accelerator tab

HWND   hwnd;                                    /* handle to main window */

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
  if (!InitApplication(hInstance))
      return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {

    /* Only translate message if it is not an accelerator message */

        if (!TranslateAccelerator(hwnd, hAccTable, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "EditMenuMenu";
    wc.lpszClassName = "EditMenuWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{

    hInst = hInstance;

    hAccTable = LoadAccelerators(hInst, "EditMenuAcc");

    hwnd = CreateWindow(
        "EditMenuWClass",
        "EditMenu Sample Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hwnd)
        return (FALSE);

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

  WM_COMMAND    - application menu (About dialog box)
  WM_DESTROY    - destroy window

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout;

    switch (message) {
  case WM_COMMAND:
            switch (wParam) {
                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
                    FreeProcInstance(lpProcAbout);
                    break;

                /* file menu commands */

                case IDM_NEW:
                case IDM_OPEN:
                case IDM_SAVE:
                case IDM_SAVEAS:
                case IDM_PRINT:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "EditMenu Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;

                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;

                /* edit menu commands */

                case IDM_UNDO:
                case IDM_CUT:
                case IDM_COPY:
                case IDM_PASTE:
                case IDM_CLEAR:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "EditMenu Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;
            }
            break;

  case WM_DESTROY:
      PostQuitMessage(0);
      break;

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


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}


FILEOPEN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\FILEOPEN\FILEOPEN.C

/****************************************************************************

    PROGRAM: FileOpen.c

    PURPOSE: Loads, saves, and edits text files

    FUNCTIONS:

        WinMain() - calls initialization function, processes message loop
        InitApplication() - initializes window data and registers window
        InitInstance() - saves instance handle and creates main window
        MainWndProc() - processes messages
        About() - processes messages for "About" dialog box
        OpenDlg() - let user select a file, and open it.
        UpdateListBox() - Update the list box of OpenDlg
        ChangeDefExt() - Change the default extension
        SeparateFile() - Separate filename and pathname
        AddExt() - Add default extension

****************************************************************************/

#include "windows.h"
#include "fileopen.h"

HANDLE hInst;

HANDLE hAccTable;                                /* handle to accelerator tab
HWND hEditWnd;                                      /* handle to edit window
HWND hwnd;                                      /* handle to main window */

char FileName[128];
char PathName[128];
char OpenName[128];
char DefPath[128];
char DefSpec[13] = "*.*";
char DefExt[] = ".txt";
char str[255];

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
        if (!InitApplication(hInstance))
            return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {

    /* Only translate message if it is not an accelerator message */

        if (!TranslateAccelerator(hwnd, hAccTable, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "FileOpenMenu";
    wc.lpszClassName = "FileOpenWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    RECT            Rect;

    hInst = hInstance;

    hAccTable = LoadAccelerators(hInst, "FileOpenAcc");

    hwnd = CreateWindow(
        "FileOpenWClass",
        "FileOpen Sample Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hwnd)
        return (FALSE);

    GetClientRect(hwnd, (LPRECT) &Rect);

    /* Create a child window */

    hEditWnd = CreateWindow("Edit",
        NULL,
        WS_CHILD | WS_VISIBLE |
        ES_MULTILINE |
        WS_VSCROLL | WS_HSCROLL |
        ES_AUTOHSCROLL | ES_AUTOVSCROLL,
        0,
        0,
        (Rect.right-Rect.left),
        (Rect.bottom-Rect.top),
        hwnd,
        IDC_EDIT,                          /* Child control i.d. */
        hInst,
        NULL);

    if (!hEditWnd) {
        DestroyWindow(hwnd);
        return (NULL);
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

        WM_COMMAND    - application menu (About dialog box)
        WM_DESTROY    - destroy window

    COMMENTS:

        WM_COMMAND processing:

            IDM_OPEN - query to save current file if there is one and it
                       has been changed, open a new file.

            IDM_ABOUT - display "About" box.

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout, lpOpenDlg, lpSaveAsDlg;

    int Success;                            /* return value from SaveAsDlg()
    int IOStatus;                           /* result of file i/o      */
    int Return;

    switch (message) {
        case WM_COMMAND:
            switch (wParam) {
                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
                    FreeProcInstance(lpProcAbout);
                    break;

                case IDM_OPEN:
                    /* Call OpenDlg() to get the filename */

                    lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
                    Return = DialogBox(hInst, "Open", hWnd, lpOpenDlg);
                    FreeProcInstance(lpOpenDlg);

                    /* Let user know that "open" functionality is not yet
                       implemented */
                    if (Return)
                       MessageBox (
                             GetFocus(),
                             "Command not implemented",
                             "FileOpen Sample Application",
                             MB_ICONASTERISK | MB_OK);
                    break;

                case IDM_NEW:
                case IDM_SAVE:
                case IDM_SAVEAS:
                case IDM_PRINT:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "FileOpen Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;

                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;

                /* edit menu commands */

                case IDM_UNDO:
                case IDM_CUT:
                case IDM_COPY:
                case IDM_PASTE:
                case IDM_CLEAR:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "FileOpen Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;

                case IDC_EDIT:
                    if (HIWORD (lParam) == EN_ERRSPACE) {
                        MessageBox (
                              GetFocus ()
                            , "Out of memory."
                            , "FileOpen Sample Application"
                            , MB_ICONHAND | MB_OK
                        );
                    }
                    break;

            }
            break;

        case WM_SETFOCUS:
            SetFocus (hEditWnd);
            break;

        case WM_SIZE:
            MoveWindow(hEditWnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

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

/****************************************************************************

    FUNCTION: OpenDlg(HWND, unsigned, WORD, LONG)

    PURPOSE: Let user select a file, and return.  Open code not provided.

****************************************************************************/

HANDLE FAR PASCAL OpenDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    WORD index;
    PSTR pTptr;
    HANDLE hFile=1;     /* Temp value for return */

    switch (message) {
        case WM_COMMAND:
            switch (wParam) {

                case IDC_LISTBOX:
                    switch (HIWORD(lParam)) {

                        case LBN_SELCHANGE:
                            /* If item is a directory name, append "*.*" */
                            if (DlgDirSelect(hDlg, str, IDC_LISTBOX))
                                strcat(str, DefSpec);

                            SetDlgItemText(hDlg, IDC_EDIT, str);
                            SendDlgItemMessage(hDlg,
                                IDC_EDIT,
                                EM_SETSEL,
                                NULL,
                                MAKELONG(0, 0x7fff));
                            break;

                        case LBN_DBLCLK:
                            goto openfile;
                    }
                    return (TRUE);

                case IDOK:
openfile:
                    GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);
                    if (strchr(OpenName, '*') || strchr(OpenName, '?')) {
                        SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,
                            (LPSTR) OpenName);
                        if (str[0])
                            strcpy(DefPath, str);
                        ChangeDefExt(DefExt, DefSpec);
                        UpdateListBox(hDlg);
                        return (TRUE);
                    }

                    if (!OpenName[0]) {
                        MessageBox(hDlg, "No filename specified.",
                            NULL, MB_OK | MB_ICONHAND);
                        return (TRUE);
                    }

                    AddExt(OpenName, DefExt);

                    /* The routine to open the file would go here, and the */
                    /* file handle would be returned instead of NULL.
                    EndDialog(hDlg, hFile);
                    return (TRUE);

                case IDCANCEL:
                    EndDialog(hDlg, NULL);
                    return (FALSE);
            }
            break;

        case WM_INITDIALOG:                        /* message: initialize
            UpdateListBox(hDlg);
            SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
            SendDlgItemMessage(hDlg,               /* dialog handle      */
                IDC_EDIT,                          /* where to send message
                EM_SETSEL,                         /* select characters
                NULL,                              /* additional information
                MAKELONG(0, 0x7fff));              /* entire contents      */
            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE); /* Indicates the focus is set to a control */
    }
    return FALSE;
}

/****************************************************************************

    FUNCTION: UpdateListBox(HWND);

    PURPOSE: Update the list box of OpenDlg

****************************************************************************/

void UpdateListBox(hDlg)
HWND hDlg;
{
    strcpy(str, DefPath);
    strcat(str, DefSpec);
    DlgDirList(hDlg, str, IDC_LISTBOX, IDC_PATH, 0x4010);

    /* To ensure that the listing is made for a subdir. of
     * current drive dir...
     */
    if (!strchr (DefPath, ':'))
  DlgDirList(hDlg, DefSpec, IDC_LISTBOX, IDC_PATH, 0x4010);

    /* Remove the '..' character from path if it exists, since this
     * will make DlgDirList move us up an additional level in the tree
     * when UpdateListBox() is called again.
     */
    if (strstr (DefPath, ".."))
  DefPath[0] = '\0';

    SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
}

/****************************************************************************

    FUNCTION: ChangeDefExt(PSTR, PSTR);

    PURPOSE: Change the default extension

****************************************************************************/

void ChangeDefExt(Ext, Name)
PSTR Ext, Name;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr)
        if (!strchr(pTptr, '*') && !strchr(pTptr, '?'))
            strcpy(Ext, pTptr);
}

/****************************************************************************

    FUNCTION: SeparateFile(HWND, LPSTR, LPSTR, LPSTR)

    PURPOSE: Separate filename and pathname

****************************************************************************/

void SeparateFile(hDlg, lpDestPath, lpDestFileName, lpSrcFileName)
HWND hDlg;
LPSTR lpDestPath, lpDestFileName, lpSrcFileName;
{
    LPSTR lpTmp;
    char  cTmp;

    lpTmp = lpSrcFileName + (long) lstrlen(lpSrcFileName);
    while (*lpTmp != ':' && *lpTmp != '\\' && lpTmp > lpSrcFileName)
        lpTmp = AnsiPrev(lpSrcFileName, lpTmp);
    if (*lpTmp != ':' && *lpTmp != '\\') {
        lstrcpy(lpDestFileName, lpSrcFileName);
        lpDestPath[0] = 0;
        return;
    }
    lstrcpy(lpDestFileName, lpTmp + 1);
    cTmp = *(lpTmp + 1);
    lstrcpy(lpDestPath, lpSrcFileName);
     *(lpTmp + 1) = cTmp;
    lpDestPath[(lpTmp - lpSrcFileName) + 1] = 0;
}

/****************************************************************************

    FUNCTION: AddExt(PSTR, PSTR);

    PURPOSE: Add default extension

/***************************************************************************/

void AddExt(Name, Ext)
PSTR Name, Ext;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr != '.')
        strcat(Name, Ext);
}

/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

        WM_INITDIALOG - initialize dialog box
        WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:
            return (TRUE);

        case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
                EndDialog(hDlg, TRUE);
                return (TRUE);
            }
            break;
    }
    return (FALSE);
}


GENERIC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\GENERIC\GENERIC.C

/****************************************************************************

    PROGRAM: Generic.c

    PURPOSE: Generic template for Windows applications

    FUNCTIONS:

  WinMain() - calls initialization function, processes message loop
  InitApplication() - initializes window data and registers window
  InitInstance() - saves instance handle and creates main window
  MainWndProc() - processes messages
  About() - processes messages for "About" dialog box

    COMMENTS:

        Windows can have several copies of your application running at the
        same time.  The variable hInst keeps track of which instance this
        application is so that processing will be to the correct window.

****************************************************************************/

 "windows.h"        /* required for all Windows applications */
 "generic.h"        /* specific to this program         */

HANDLE hInst;          /* current instance           */

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

    COMMENTS:

        Windows recognizes this function by name as the initial entry point
        for the program.  This function calls the application initialization
        routine, if no other instance of the program is running, and always
        calls the instance initialization routine.  It then executes a messag
        retrieval and dispatch loop that is the top-level control structure
        for the remainder of execution.  The loop is terminated when a WM_QUI
        message is received, at which time this function exits the applicatio
        instance by returning the value passed by PostQuitMessage().

        If this function must abort before entering the message loop, it
        returns the conventional value NULL.

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;           /* current instance       */
HANDLE hPrevInstance;           /* previous instance       */
LPSTR lpCmdLine;           /* command line         */
int nCmdShow;             /* show-window type (open/icon) */
{
    MSG msg;             /* message           */

    if (!hPrevInstance)       /* Other instances of app running? */
  if (!InitApplication(hInstance)) /* Initialize shared things */
      return (FALSE);     /* Exits if unable to initialize     */

    /* Perform initializations that apply to a specific instance */

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    /* Acquire and dispatch messages until a WM_QUIT message is received. */

    while (GetMessage(&msg,     /* message structure           */
      NULL,       /* handle of window receiving the message */
      NULL,       /* lowest message to examine         */
      NULL))       /* highest message to examine       */
  {
  TranslateMessage(&msg);     /* Translates virtual key codes       */
  DispatchMessage(&msg);     /* Dispatches message to window       */
    }
    return (msg.wParam);     /* Returns the value from PostQuitMessage */
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

    COMMENTS:

        This function is called at initialization time only if no other
        instances of the application are running.  This function performs
        initialization tasks that can be done once for any number of running
        instances.

        In this case, we initialize a window class by filling out a data
        structure of type WNDCLASS and calling the Windows RegisterClass()
        function.  Since all instances of this application use the same windo
        class, we only need to do this when the first instance is initialized


****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;             /* current instance       */
{
    WNDCLASS  wc;

    /* Fill in window class structure with parameters that describe the
    /* main window.

    wc.style = NULL;                    /* Class style(s).
    wc.lpfnWndProc = MainWndProc;       /* Function to retrieve messages for
                                        /* windows of this class.
    wc.cbClsExtra = 0;                  /* No per-class extra data.
    wc.cbWndExtra = 0;                  /* No per-window extra data.
    wc.hInstance = hInstance;           /* Application that owns the class.
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "GenericMenu";   /* Name of menu resource in .RC file.
    wc.lpszClassName = "GenericWClass"; /* Name used in call to CreateWindow.

    /* Register the window class and return success/failure code. */

    return (RegisterClass(&wc));

}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

    COMMENTS:

        This function is called at initialization time for every instance of
        this application.  This function performs initialization tasks that
        cannot be shared by multiple instances.

        In this case, we save the instance handle in a static variable and
        create and display the main program window.

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;          /* Current instance identifier.
    int             nCmdShow;           /* Param for first ShowWindow() call.
{
    HWND            hWnd;               /* Main window handle.

    /* Save the instance handle in static variable, which will be used in  */
    /* many subsequence calls from this application to Windows.            */

    hInst = hInstance;

    /* Create a main window for this application instance.  */

    hWnd = CreateWindow(
        "GenericWClass",                /* See RegisterClass() call.
        "Generic Sample Application",   /* Text for window title bar.
        WS_OVERLAPPEDWINDOW,            /* Window style.
        CW_USEDEFAULT,                  /* Default horizontal position.
        CW_USEDEFAULT,                  /* Default vertical position.
        CW_USEDEFAULT,                  /* Default width.
        CW_USEDEFAULT,                  /* Default height.
        NULL,                           /* Overlapped windows have no parent.
        NULL,                           /* Use the window class menu.
        hInstance,                      /* This instance owns this window.
        NULL                            /* Pointer not needed.
    );

    /* If window could not be created, return "failure" */

    if (!hWnd)
        return (FALSE);

    /* Make the window visible; update its client area; and return "success"

    ShowWindow(hWnd, nCmdShow);  /* Show the window                        */
    UpdateWindow(hWnd);          /* Sends WM_PAINT message                 */
    return (TRUE);               /* Returns the value from PostQuitMessage */

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

  WM_COMMAND    - application menu (About dialog box)
  WM_DESTROY    - destroy window

    COMMENTS:

  To process the IDM_ABOUT message, call MakeProcInstance() to get the
  current instance address of the About() function.  Then call Dialog
  box which will create the box according to the information in your
  generic.rc file and turn control over to the About() function.  When
  it returns, free the intance address.

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;          /* window handle         */
unsigned message;        /* type of message         */
WORD wParam;          /* additional information       */
LONG lParam;          /* additional information       */
{
    FARPROC lpProcAbout;      /* pointer to the "About" function */

    switch (message) {
  case WM_COMMAND:     /* message: command from application menu */
      if (wParam == IDM_ABOUT) {
    lpProcAbout = MakeProcInstance(About, hInst);

    DialogBox(hInst,     /* current instance       */
        "AboutBox",       /* resource to use       */
        hWnd,       /* parent handle       */
        lpProcAbout);     /* About() instance address */

    FreeProcInstance(lpProcAbout);
    break;
      }
      else          /* Lets Windows process it       */
    return (DefWindowProc(hWnd, message, wParam, lParam));

  case WM_DESTROY:      /* message: window being destroyed */
      PostQuitMessage(0);
      break;

  default:        /* Passes it on if unproccessed    */
      return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (NULL);
}


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

    COMMENTS:

  No initialization is needed for this particular dialog box, but TRUE
  must be returned to Windows.

  Wait for user to click on "Ok" button, then close the dialog box.

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;                                /* window handle of the dialog box
unsigned message;                         /* type of message
WORD wParam;                              /* message-specific information
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:       /* message: initialize dialog box */
      return (TRUE);

  case WM_COMMAND:          /* message: received a command */
      if (wParam == IDOK                /* "OK" box selected?       */
                || wParam == IDCANCEL) {      /* System menu close command? *
    EndDialog(hDlg, TRUE);        /* Exits the dialog box       */
    return (TRUE);
      }
      break;
    }
    return (FALSE);            /* Didn't process a message    */
}


HELPEX.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\HELPEX\HELPEX.C

/****************************************************************************

   PROGRAM:    HelpEx.c

   PURPOSE:    Illustrates calls to WinHelp and context-sensitive help.
               HelpEx loads library MenuHook, which detects F1 keystrokes in
               the HelpEx application menus.

   FUNCTIONS:

   WinMain() - Calls initialization function, processes message loop.
   InitApplication() - Initializes window data and registers window class.
   InitInstance() - Saves instance handle and creates main window.
   MainWndProc() - Processes window messages.
   About() - Processes messages for "About" dialog box.
   MakeHelpPathName() - Derives path name of help file.

****************************************************************************/

#include <windows.h>
#include "helpex.h"
#include "helpids.h"

HWND       hWnd;               /* Handle to main window */
HANDLE     hInst;              /* Handle to instance data*/
BOOL       bHelp = FALSE;      /* Help mode flag; TRUE = "ON"*/
HCURSOR    hHelpCursor;        /* Cursor displayed when in help mode*/
char       szHelpFileName[EXE_NAME_MAX_SIZE+1];    /* Help file name*/
HANDLE     hAccTable;                              /* handle to accelerator t

void MakeHelpPathName(char*);  /* Function deriving help file path */


/****************************************************************************

   FUNCTION:   WinMain(HANDLE, HANDLE, LPSTR, int)

   PURPOSE:    Calls initialization function, processes message loop.

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR  lpCmdLine;
int    nCmdShow;
{
   MSG msg;

   if (!hPrevInstance)
       if (!InitApplication(hInstance))
       return (FALSE);

   if (!InitInstance(hInstance, nCmdShow))
       return (FALSE);

   while (GetMessage(&msg, NULL, NULL, NULL)) {

      /* Only translate message if it is not an accelerator message */
      if (!TranslateAccelerator(hWnd, hAccTable, &msg)) {

          TranslateMessage(&msg);
          DispatchMessage(&msg);
      }
   }
   return (msg.wParam);
}


/****************************************************************************

   FUNCTION:   InitApplication(HANDLE)

   PURPOSE:    Initializes window data and registers window class.

   RETURNS:    Status of RegisterClass() call.

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
   WNDCLASS wc;

   wc.style = NULL;
   wc.lpfnWndProc = MainWndProc;
   wc.cbClsExtra = 0;
   wc.cbWndExtra = 0;
   wc.hInstance = hInstance;
   wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
   wc.hbrBackground = GetStockObject(WHITE_BRUSH);
   wc.lpszMenuName ="HelpexMenu";
   wc.lpszClassName = "HelpexWClass";

   return (RegisterClass(&wc));
}


/****************************************************************************

   FUNCTION:   InitInstance(HANDLE, int)

   PURPOSE:    Saves instance handle in global variable and creates main
               window.

   RETURNS:    Status of CreateWindow() call.

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
HANDLE hInstance;
int    nCmdShow;
{

   hInst = hInstance;

   hAccTable = LoadAccelerators(hInst, "HelpexAcc");

   hWnd = CreateWindow(
       "HelpexWClass",
       "Help Example ",
       WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
       NULL,
       NULL,
       hInstance,
       NULL
       );

   if (!hWnd)
       return (FALSE);

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   EnableMenuItem(GetSubMenu(GetMenu(hWnd), 1), IDM_CLEAR, MF_ENABLED);

   MakeHelpPathName(szHelpFileName);
   hHelpCursor = LoadCursor(hInst,"HelpCursor");

   return (TRUE);

}

/****************************************************************************

   FUNCTION:   MainWndProc(HWND, unsigned, WORD, LONG)

   PURPOSE:    Processes window messages.

   MESSAGES:

       WM_COMMAND- Application menu item
       WM_DESTROY- Destroy window

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND       hWnd;
unsigned   message;
WORD       wParam;
LONG       lParam;
{
   FARPROC lpProcAbout;
   DWORD   dwHelpContextId;
   RECT    rect;
   POINT   pt;
   DWORD   dword;
   WORD    wFormat;
   HCURSOR hArrow;

   switch (message) {

       case WM_COMMAND:
           /* Was F1 just pressed in a menu, or are we in help mode */
           /* (Shift-F1)? */

           if (bHelp) {
               dwHelpContextId =
                   (wParam == IDM_NEW)    ? (DWORD) HELPID_FILE_NEW     :
                   (wParam == IDM_OPEN)   ? (DWORD) HELPID_FILE_OPEN    :
                   (wParam == IDM_SAVE)   ? (DWORD) HELPID_FILE_SAVE    :
                   (wParam == IDM_SAVEAS) ? (DWORD) HELPID_FILE_SAVE_AS :
                   (wParam == IDM_PRINT)  ? (DWORD) HELPID_FILE_PRINT   :
                   (wParam == IDM_EXIT)   ? (DWORD) HELPID_FILE_EXIT    :
                   (wParam == IDM_UNDO)   ? (DWORD) HELPID_EDIT_UNDO    :
                   (wParam == IDM_CUT)    ? (DWORD) HELPID_EDIT_CUT     :
                   (wParam == IDM_CLEAR)  ? (DWORD) HELPID_EDIT_CLEAR   :
                   (wParam == IDM_COPY)   ? (DWORD) HELPID_EDIT_COPY    :
                   (wParam == IDM_PASTE)  ? (DWORD) HELPID_EDIT_PASTE   :
                                            (DWORD) 0L;

               if (!dwHelpContextId)
         {
                   MessageBox( hWnd, "Help not available for Help Menu item",
             "Help Example", MB_OK                          );
                   return (DefWindowProc(hWnd, message, wParam, lParam));
         }

               bHelp = FALSE;
               WinHelp(hWnd,szHelpFileName,HELP_CONTEXT,dwHelpContextId);
               break;
           }

           switch (wParam) {
               case IDM_NEW:
               case IDM_OPEN:
               case IDM_SAVE:
               case IDM_SAVEAS:
               case IDM_PRINT:
               case IDM_UNDO:
               case IDM_CUT:
               case IDM_CLEAR:
               case IDM_COPY:
               case IDM_PASTE:
                   MessageBox(hWnd,
                   "Command not implemented",
                   "Help Example",
                   MB_OK);
                   break;

               case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;

               case IDM_HELP_INDEX:
                   WinHelp(hWnd,szHelpFileName,HELP_INDEX,0L);
                   break;

               case IDM_HELP_KEYBOARD:
       WinHelp(hWnd,szHelpFileName,HELP_KEY,(DWORD)(LPSTR)"keys");
                   break;

               case IDM_HELP_HELP:
       WinHelp(hWnd,"WINHELP.HLP",HELP_INDEX,0L);
                   break;

               case IDM_ABOUT:
                   lpProcAbout = MakeProcInstance(About, hInst);
                   DialogBox(hInst,
                       "AboutBox",
                       hWnd,
                       lpProcAbout);
                   FreeProcInstance(lpProcAbout);
                   break;

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

           break;

       case WM_LBUTTONDOWN:
     if (bHelp)
     {
         bHelp = FALSE;
         WinHelp( hWnd, szHelpFileName, HELP_CONTEXT,
      (DWORD) HELPID_EDIT_WINDOW          );
         break;
     }

           return (DefWindowProc(hWnd, message, wParam, lParam));

       case WM_NCLBUTTONDOWN:
           /* If we are in help mode (Shift-F1) then display context- */
           /* sensitive help for non-client area. */

           if (bHelp) {
               dwHelpContextId =
                   (wParam == HTCAPTION)     ? (DWORD) HELPID_TITLE_BAR     :
                   (wParam == HTREDUCE)      ? (DWORD) HELPID_MINIMIZE_ICON :
                   (wParam == HTZOOM)        ? (DWORD) HELPID_MAXIMIZE_ICON :
                   (wParam == HTSYSMENU)     ? (DWORD) HELPID_SYSTEM_MENU   :
                   (wParam == HTBOTTOM)      ? (DWORD) HELPID_SIZING_BORDER :
                   (wParam == HTBOTTOMLEFT)  ? (DWORD) HELPID_SIZING_BORDER :
                   (wParam == HTBOTTOMRIGHT) ? (DWORD) HELPID_SIZING_BORDER :
                   (wParam == HTTOP)         ? (DWORD) HELPID_SIZING_BORDER :
                   (wParam == HTLEFT)        ? (DWORD) HELPID_SIZING_BORDER :
                   (wParam == HTRIGHT)       ? (DWORD) HELPID_SIZING_BORDER :
                   (wParam == HTTOPLEFT)     ? (DWORD) HELPID_SIZING_BORDER :
                   (wParam == HTTOPRIGHT)    ? (DWORD) HELPID_SIZING_BORDER :
                                               (DWORD) 0L;

               if (!((BOOL)dwHelpContextId))
                   return (DefWindowProc(hWnd, message, wParam, lParam));

               bHelp = FALSE;
               WinHelp(hWnd,szHelpFileName,HELP_CONTEXT,dwHelpContextId);
               break;
           }

           return (DefWindowProc(hWnd, message, wParam, lParam));

       case WM_KEYDOWN:
           if (wParam == VK_F1) {

               /* If Shift-F1, turn help mode on and set help cursor */

               if (GetKeyState(VK_SHIFT)<0) {
                   bHelp = TRUE;
                   SetCursor(hHelpCursor);
                   return (DefWindowProc(hWnd, message, wParam, lParam));
               }

               /* If F1 without shift, then call up help main index topic */
               else {
                   WinHelp(hWnd,szHelpFileName,HELP_INDEX,0L);
               }
           }

           else if (wParam == VK_ESCAPE && bHelp) {

               /* Escape during help mode: turn help mode off */
               bHelp = FALSE;
               SetCursor((HCURSOR)GetClassWord(hWnd,GCW_HCURSOR));
           }

           break;

       case WM_SETCURSOR:
           /* In help mode it is necessary to reset the cursor in response */
           /* to every WM_SETCURSOR message.Otherwise, by default, Windows */
           /* will reset the cursor to that of the window class. */

           if (bHelp) {
               SetCursor(hHelpCursor);
               break;
           }
           return (DefWindowProc(hWnd, message, wParam, lParam));
           break;

       case WM_INITMENU:
           if (bHelp) {
               SetCursor(hHelpCursor);
           }
           return (TRUE);

       case WM_ENTERIDLE:
           if ((wParam == MSGF_MENU) && (GetKeyState(VK_F1) & 0x8000)) {
               bHelp = TRUE;
               PostMessage(hWnd, WM_KEYDOWN, VK_RETURN, 0L);
           }
           break;

       case WM_DESTROY:
           WinHelp(hWnd,szHelpFileName,HELP_QUIT,0L);
           PostQuitMessage(0);
           break;

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

   return (NULL);
}


/****************************************************************************

   FUNCTION:   About(HWND, unsigned, WORD, LONG)

   PURPOSE:    Processes messages for "About" dialog box

   MESSAGES:

       WM_INITDIALOG - Initialize dialog box
       WM_COMMAND- Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND       hDlg;
unsigned   message;
WORD       wParam;
LONG       lParam;
{
   switch (message) {
       case WM_INITDIALOG:
           return (TRUE);

       case WM_COMMAND:
           if (wParam == IDOK) {
               EndDialog(hDlg, TRUE);
               return (TRUE);
           }
           break;
   }

   return (FALSE);
}


/****************************************************************************

   FUNCTION:   MakeHelpPathName

   PURPOSE:    HelpEx assumes that the .HLP help file is in the same
               directory as the HelpEx executable.This function derives
               the full path name of the help file from the path of the
               executable.

****************************************************************************/

void MakeHelpPathName(szFileName)
char * szFileName;
{
   char *  pcFileName;
   int     nFileNameLen;

   nFileNameLen = GetModuleFileName(hInst,szFileName,EXE_NAME_MAX_SIZE);
   pcFileName = szFileName + nFileNameLen;

   while (pcFileName > szFileName) {
       if (*pcFileName == '\\' || *pcFileName == ':') {
           *(++pcFileName) = '\0';
           break;
       }
   nFileNameLen--;
   pcFileName--;
   }

   if ((nFileNameLen+13) < EXE_NAME_MAX_SIZE) {
       lstrcat(szFileName, "helpex.hlp");
   }

   else {
       lstrcat(szFileName, "?");
   }

   return;
}


ICON.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\ICON\ICON.C

/****************************************************************************

    PROGRAM: Icon.c

    PURPOSE: Demonstrates using an icon for the About box and minimize box

    FUNCTIONS:

  WinMain() - calls initialization function, processes message loop
  InitApplication() - initializes window data and registers window
  InitInstance() - saves instance handle and creates main window
  MainWndProc() - processes messages
  About() - processes messages for "About" dialog box

****************************************************************************/

#include "windows.h"
#include "icon.h"

HANDLE hInst;

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
  if (!InitApplication(hInstance))
      return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, "MyIcon");           /* loads icon */
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "IconMenu";
    wc.lpszClassName = "IconWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    HWND            hWnd;

    hInst = hInstance;

    hWnd = CreateWindow(
        "IconWClass",
        "Icon Sample Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
        return (FALSE);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

  WM_COMMAND    - application menu (About dialog box)
  WM_DESTROY    - destroy window

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout;

    switch (message) {
  case WM_COMMAND:
      if (wParam == IDM_ABOUT) {
    lpProcAbout = MakeProcInstance(About, hInst);

    DialogBox(hInst,
        "AboutBox",
        hWnd,
        lpProcAbout);

    FreeProcInstance(lpProcAbout);
    break;
      }
      else
    return (DefWindowProc(hWnd, message, wParam, lParam));

  case WM_DESTROY:
      PostQuitMessage(0);
      break;

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


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}


INPUT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\INPUT\INPUT.C

/****************************************************************************

    PROGRAM: Input.c

    PURPOSE: Input template for Windows applications

    FUNCTIONS:

  WinMain() - calls initialization function, processes message loop
  InitApplication() - initializes window data and registers window
  InitInstance() - saves instance handle and creates main window
  MainWndProc() - processes messages
  About() - processes messages for "About" dialog box

****************************************************************************/

#include "windows.h"
#include "input.h"

HANDLE hInst;

char MouseText[48];                                   /* mouse state
char ButtonText[48];                                  /* mouse-button state
char KeyboardText[48];                                /* keyboard state
char CharacterText[48];                               /* latest character
char ScrollText[48];                                  /* scroll status
char TimerText[48];                                   /* timer state
RECT rectMouse;
RECT rectButton;
RECT rectKeyboard;
RECT rectCharacter;
RECT rectScroll;
RECT rectTimer;
int idTimer;                                          /* timer ID
int nTimerCount = 0;                                  /* current timer count

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
  if (!InitApplication(hInstance))
      return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = CS_DBLCLKS;          /* double-click messages */
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "InputMenu";
    wc.lpszClassName = "InputWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    HWND            hWnd;
    HDC             hDC;
    TEXTMETRIC      textmetric;
    RECT            rect;
    int             nLineHeight;


    hInst = hInstance;

    hWnd = CreateWindow(
        "InputWClass",
        "Input Sample Application",
        WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,  /* horz & vert scroll
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
        return (FALSE);


    hDC = GetDC(hWnd);
    GetTextMetrics(hDC, &textmetric);
    ReleaseDC(hWnd, hDC);
    nLineHeight = textmetric.tmExternalLeading + textmetric.tmHeight;

    rect.left   = GetDeviceCaps(hDC, LOGPIXELSX) / 4;   /* 1/4 inch */
    rect.right  = GetDeviceCaps(hDC, HORZRES);
    rect.top    = GetDeviceCaps(hDC, LOGPIXELSY) / 4;   /* 1/4 inch */
    rect.bottom = rect.top + nLineHeight;
    rectMouse   = rect;

    rect.top += nLineHeight;
    rect.bottom += nLineHeight;
    rectButton = rect;

    rect.top += nLineHeight;
    rect.bottom += nLineHeight;
    rectKeyboard = rect;

    rect.top += nLineHeight;
    rect.bottom += nLineHeight;
    rectCharacter = rect;

    rect.top += nLineHeight;
    rect.bottom += nLineHeight;
    rectScroll = rect;

    rect.top += nLineHeight;
    rect.bottom += nLineHeight;
    rectTimer = rect;

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

  WM_COMMAND    - application menu (About dialog box)
  WM_CREATE     - create window
        WM_MOUSEMOVE  - mouse movement
        WM_LBUTTONDOWN - left mouse button pressed
        WM_LBUTTONUP  - left mouse button released
        WM_LBUTTONDBLCLK - left mouse button double clicked
        WM_KEYDOWN    - key pressed
        WM_KEYUP      - key released
        WM_CHAR       - ASCII character received
        WM_TIMER      - timer has elapsed
        WM_HSCROLL    - mouse click in horizontal scroll bar
        WM_VSCROLL    - mouse click in vertical scroll bar
        WM_PAINT      - update window, draw objects
        WM_DESTROY    - destroy window

    COMMENTS:

        This demonstrates how input messages are received, and what the
        additional information is that comes with the message.

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout;

    HDC hDC;                         /* display-context variable     */
    PAINTSTRUCT ps;                  /* paint structure              */
    char HorzOrVertText[12];
    char ScrollTypeText[20];
    RECT rect;

    switch (message) {
  case WM_COMMAND:
      if (wParam == IDM_ABOUT) {
    lpProcAbout = MakeProcInstance(About, hInst);

    DialogBox(hInst,
        "AboutBox",
        hWnd,
        lpProcAbout);

    FreeProcInstance(lpProcAbout);
    break;
      }
      else
    return (DefWindowProc(hWnd, message, wParam, lParam));

        case WM_CREATE:

            /* Set the timer for five-second intervals */

            idTimer =  SetTimer(hWnd, NULL, 5000, (FARPROC) NULL);

            break;

        case WM_MOUSEMOVE:
            wsprintf(MouseText, "WM_MOUSEMOVE: %x, %d, %d",
                wParam, LOWORD(lParam), HIWORD(lParam));
            InvalidateRect(hWnd, &rectMouse, TRUE);
            break;

        case WM_LBUTTONDOWN:
            wsprintf(ButtonText, "WM_LBUTTONDOWN: %x, %d, %d",
                wParam, LOWORD(lParam), HIWORD(lParam));
            InvalidateRect(hWnd, &rectButton, TRUE);
            break;

        case WM_LBUTTONUP:
            wsprintf(ButtonText, "WM_LBUTTONUP: %x, %d, %d",
                wParam, LOWORD(lParam), HIWORD(lParam));
            InvalidateRect(hWnd, &rectButton, TRUE);
            break;

        case WM_LBUTTONDBLCLK:
            wsprintf(ButtonText, "WM_LBUTTONDBLCLK: %x, %d, %d",
                wParam, LOWORD(lParam), HIWORD(lParam));
            InvalidateRect(hWnd, &rectButton, TRUE);
            break;

        case WM_KEYDOWN:
            wsprintf(KeyboardText, "WM_KEYDOWN: %x, %x, %x",
                wParam, LOWORD(lParam), HIWORD(lParam));
            InvalidateRect(hWnd, &rectKeyboard, TRUE);
            break;

        case WM_KEYUP:
            wsprintf(KeyboardText, "WM_KEYUP: %x, %x, %x",
                wParam, LOWORD(lParam), HIWORD(lParam));
            InvalidateRect(hWnd, &rectKeyboard, TRUE);
            break;

        case WM_CHAR:
            wsprintf(CharacterText, "WM_CHAR: %c, %x, %x",
                wParam, LOWORD(lParam), HIWORD(lParam));
            InvalidateRect(hWnd, &rectCharacter, TRUE);
            break;

        case WM_TIMER:
            wsprintf(TimerText, "WM_TIMER: %d seconds",
                nTimerCount += 5);
            InvalidateRect(hWnd, &rectTimer, TRUE);
            break;

        case WM_HSCROLL:
        case WM_VSCROLL:
            strcpy(HorzOrVertText,
                (message == WM_HSCROLL) ? "WM_HSCROLL" : "WM_VSCROLL");
            strcpy(ScrollTypeText,
                (wParam == SB_LINEUP) ? "SB_LINEUP" :
                (wParam == SB_LINEDOWN) ? "SB_LINEDOWN" :
                (wParam == SB_PAGEUP) ? "SB_PAGEUP" :
                (wParam == SB_PAGEDOWN) ? "SB_PAGEDOWN" :
                (wParam == SB_THUMBPOSITION) ? "SB_THUMBPOSITION" :
                (wParam == SB_THUMBTRACK) ? "SB_THUMBTRACK" :
                (wParam == SB_ENDSCROLL) ? "SB_ENDSCROLL" : "unknown");
            wsprintf(ScrollText, "%s: %s, %x, %x",
                (LPSTR)HorzOrVertText,
                (LPSTR)ScrollTypeText,
                LOWORD(lParam),
                HIWORD(lParam));
            InvalidateRect(hWnd, &rectScroll, TRUE);
            break;

        case WM_PAINT:
            hDC = BeginPaint (hWnd, &ps);

            if (IntersectRect(&rect, &rectMouse, &ps.rcPaint))
                TextOut(hDC, rectMouse.left, rectMouse.top,
                        MouseText, strlen(MouseText));
            if (IntersectRect(&rect, &rectButton, &ps.rcPaint))
                TextOut(hDC, rectButton.left, rectButton.top,
                        ButtonText, strlen(ButtonText));
            if (IntersectRect(&rect, &rectKeyboard, &ps.rcPaint))
                TextOut(hDC, rectKeyboard.left, rectKeyboard.top,
                        KeyboardText, strlen(KeyboardText));
            if (IntersectRect(&rect, &rectCharacter, &ps.rcPaint))
                TextOut(hDC, rectCharacter.left, rectCharacter.top,
                        CharacterText, strlen(CharacterText));
            if (IntersectRect(&rect, &rectTimer, &ps.rcPaint))
                TextOut(hDC, rectTimer.left, rectTimer.top,
                        TimerText, strlen(TimerText));
            if (IntersectRect(&rect, &rectScroll, &ps.rcPaint))
                TextOut(hDC, rectScroll.left, rectScroll.top,
                        ScrollText, strlen(ScrollText));

            EndPaint(hWnd, &ps);
            break;

        case WM_DESTROY:
            KillTimer(hWnd, idTimer);                     /* Stops the timer
            PostQuitMessage(0);
            break;

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


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}


MEMORY1.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MEMORY\MEMORY1.C

#include "windows.h"
#include "memory.h"

HANDLE hInst;

/****************************************************************************
    MODULE:  memory1.c

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
  if (!InitApplication(hInstance))
      return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
    }
    return (msg.wParam);
}


MEMORY2.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MEMORY\MEMORY2.C

#include "windows.h"
#include "memory.h"

/****************************************************************************
    MODULE:  memory2.c

    FUNCTION: MemoryInit(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "MemoryMenu";
    wc.lpszClassName = "MemoryWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************
    MODULE:  memory3.c


    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    HWND            hwnd;

    hInst = hInstance;

    hwnd = CreateWindow(
        "MemoryWClass",
        "Memory Sample Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hwnd)
        return (FALSE);

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    return (TRUE);

}


MEMORY3.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MEMORY\MEMORY3.C

#include "windows.h"
#include "memory.h"

/****************************************************************************
    MODULE:  memory3.c

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

  WM_COMMAND    - application menu (About dialog box)
  WM_DESTROY    - destroy window

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout;

    switch (message) {
  case WM_COMMAND:
      if (wParam == IDM_ABOUT) {
    lpProcAbout = MakeProcInstance(About, hInst);

    DialogBox(hInst,
        "AboutBox",
        hWnd,
        lpProcAbout);

    FreeProcInstance(lpProcAbout);
    break;
      }
      else
    return (DefWindowProc(hWnd, message, wParam, lParam));

  case WM_DESTROY:
      PostQuitMessage(0);
      break;

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


MEMORY4.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MEMORY\MEMORY4.C

#include "windows.h"
#include "memory.h"

/****************************************************************************
    MODULE:  memory4.c

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}


MENU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MENU\MENU.C

/***************************************************************************
 *                     *
 *  PROGRAM  : Menu.c               *
 *                     *
 *  PURPOSE  : To give a demonstration of the use of popup menus, user  *
 *      defined menus and menu functions.         *
 *                     *
 *  FUNCTIONS  : WinMain()        - Calls the initialization function  *
 *          and enters the message loop.     *
 *                     *
 *      MenuInit()        - Registers the app. window class.   *
 *                     *
 *      About()        - Dialog function for the About..    *
 *          dialog.          *
 *                     *
 *      ShrinkBitmap()      - Shrinks a 64x64 bitmap to a size   *
 *          useable for a user-defined menu    *
 *          checkmark.         *
 *                     *
 *      HandleCreate()      - Creates a new menu and appends it  *
 *          to the main menu       *
 *                     *
 *      HandlePaint()       - Handles repainting the app's client*
 *          area           *
 *                     *
 *      HandleChangeColors()- Changes the state of the "colors"  *
 *          menu item.         *
 *                     *
 *      HandleDrawItem()    - Redraws the menu items in the     *
 *          "colors" menu         *
 *                     *
 *      HandlePopupMenu()   - handles display of the "floating"  *
 *          popup.           *
 *                     *
 *      MenuWndProc()       - Window function for the app.     *
 *                     *
 *                     *
 ***************************************************************************/
#include "windows.h"
#include "menu.h"

HANDLE   hInst;
HMENU   hBigMenu;
HBITMAP  hbmCheckOn;
HBITMAP  hbmCheckOff;

/****************************************************************************
 *                      *
 *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)          *
 *                      *
 *  PURPOSE    : Creates the main app. window, calls an initialization      *
 *     function and enters the message loop.          *
 *                      *
 ****************************************************************************
int PASCAL WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)

HANDLE hInstance, hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;

{
    HWND  hWnd;
    MSG   msg;

    /* Register main window class if this is the first instance of the app. *
    if (!hPrevInstance)
  if (!MenuInit (hInstance))
      return NULL;

    hInst = hInstance;

    /* Create the app. window */
    hWnd = CreateWindow ("menu",
       "Menu Example",
       WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
       (HWND) NULL,
       NULL,
       hInstance,
       (LPSTR) NULL);

    if (!hWnd)
  return NULL;

    ShowWindow (hWnd, nCmdShow);
    UpdateWindow (hWnd);

    while (GetMessage (&msg, NULL, NULL, NULL)){
  /* Since we have no accelerators, no need to call
   * TranslateAccelerator here.
   */
  TranslateMessage (&msg);
  DispatchMessage (&msg);
    }
    return(msg.wParam);
}


/****************************************************************************
 *                      *
 *  FUNCTION   : MenuInit (hInstance)              *
 *                      *
 *  PURPOSE    : Registers the main window class.          *
 *                      *
 *  RETURNS    : TRUE  -  if RegisterClass() went off ok        *
 *     FALSE  -  otherwise.              *
 *                      *
 ****************************************************************************
BOOL NEAR PASCAL MenuInit (hInstance)

HANDLE hInstance;

{
    HANDLE    hMemory;
    PWNDCLASS pWndClass;
    BOOL      bSuccess;

    /* Initialize the menu window class */
    hMemory   = LocalAlloc(LPTR, sizeof(WNDCLASS));
    pWndClass = (PWNDCLASS) LocalLock(hMemory);

    pWndClass->style       = NULL;
    pWndClass->lpfnWndProc   = MenuWndProc;
    pWndClass->hInstance     = hInstance;
    pWndClass->hIcon       = LoadIcon (hInstance, "menu");
    pWndClass->hCursor       = LoadCursor (NULL, IDC_ARROW);
    pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
    pWndClass->lpszMenuName  = (LPSTR) "MenuMenu",
    pWndClass->lpszClassName = (LPSTR) "menu";

    bSuccess = RegisterClass (pWndClass);
    LocalUnlock (hMemory);
    LocalFree (hMemory);

    return bSuccess;
}


/****************************************************************************
 *                      *
 *  FUNCTION   : About (hDlg, message, wParam, lParam)          *
 *                      *
 *  PURPOSE    : Dialog function for the About menu... dialog.        *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL About(hDlg, message, wParam, lParam)

HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;

{
    switch (message){
  case WM_INITDIALOG:
      return(TRUE);

  case WM_COMMAND:
      if (wParam == IDOK){
    EndDialog(hDlg,NULL);
    return(TRUE);
      }
      break;
    }
    return(FALSE);
}


/****************************************************************************
 *                      *
 *  FUNCTION   : ShrinkBitmap(hwnd, hbm)            *
 *                      *
 *  PURPOSE    : This function shrinks a 64x64 bitmap into a bitmap useable *
 *     for the user-defined checkmark for menu items. This can be *
 *     easily generalized to shrink bitmaps of any size.      *
 *                      *
 *  RETURNS    : HBITMAP - A handle to the new bitmap.          *
 *                      *
 ****************************************************************************
HBITMAP FAR PASCAL ShrinkBitmap (hwnd, hbm)

HWND hwnd;
HBITMAP hbm;

{
    HDC     hdc;
    HDC     hmemorydcNew;
    HDC     hmemorydcOld;
    LONG    checkMarkSize;
    HBITMAP hCheckBitmap;
    HBITMAP hOldBitmapSave;
    HBITMAP hNewBitmapSave;

    hdc = GetDC (hwnd);

    /* Create DCs for the source (old) and target (new) bitmaps */
    hmemorydcNew = CreateCompatibleDC (hdc);
    hmemorydcOld = CreateCompatibleDC (hdc);

    /* Determine the dimensions of the default menu checkmark and
     * create a target bitmap of the same dimensions
     */
    checkMarkSize = GetMenuCheckMarkDimensions ();
    hCheckBitmap  = CreateCompatibleBitmap (hdc,
              LOWORD (checkMarkSize),
              HIWORD (checkMarkSize));

    /* Select the source bitmap and the target bitmap into their
     * respective DCs.
     */
    hOldBitmapSave = SelectObject (hmemorydcNew, hCheckBitmap);
    hNewBitmapSave = SelectObject (hmemorydcOld, hbm);

    /* Shrink the source bitmap into the target DC */
    StretchBlt (hmemorydcNew,
    0,
    0,
    LOWORD(checkMarkSize),
    HIWORD(checkMarkSize),
    hmemorydcOld,
    0,
    0,
    64,
    64,
    SRCCOPY);

    /* De-select the bitmaps and clean up .. */
    SelectObject (hmemorydcNew, hOldBitmapSave);
    SelectObject (hmemorydcOld, hNewBitmapSave);
    DeleteDC (hmemorydcNew);
    DeleteDC (hmemorydcOld);
    ReleaseDC (hwnd, hdc);

    /* .. and return a handle to the target bitmap */
    return hCheckBitmap;
}


/****************************************************************************
 *                      *
 *  FUNCTION   : HandleCreate ( hwnd )              *
 *                      *
 *  PURPOSE    : Creates a new (empty) menu and appends to it the "State"   *
 *     menu items. It sets up the user-defined checkmarks for the *
 *     menu. It then inserts this menu into the main menu bar.    *
 *                      *
 ****************************************************************************
void FAR PASCAL HandleCreate (hwnd)
HWND hwnd;
{
    HMENU   hMenu;
    HMENU   hWndMenu;
    HBITMAP hbmOn;
    HBITMAP hbmOff;

    /* Create a new menu into the menubar on the fly */
    hMenu = CreateMenu ();
    if (!hMenu)
  return;

    /* Append the state menu items to it */
    AppendMenu (hMenu, MF_STRING, IDM_STATE1, "South Dakota");
    AppendMenu (hMenu, MF_STRING, IDM_STATE2, "Washington");
    AppendMenu (hMenu, MF_STRING, IDM_STATE3, "California");
    if (!AppendMenu (hMenu, MF_STRING, IDM_STATE4, "Oregon")){
  /* It is unlikely the other appends will fail and this will succeed.
   * So just check this one. And if it fails, Destroy the menu for
   * good measure and return.
   */
  DestroyMenu(hMenu);
  return;
    }
    hbmCheckOn  = ShrinkBitmap (hwnd, LoadBitmap (hInst, "checkon"));
    hbmCheckOff = ShrinkBitmap (hwnd, LoadBitmap (hInst, "checkoff"));

    /* Set up the user-defined check marks */
    SetMenuItemBitmaps (hMenu, 0, MF_BYPOSITION, hbmCheckOff, hbmCheckOn);
    SetMenuItemBitmaps (hMenu, 1, MF_BYPOSITION, hbmCheckOff, hbmCheckOn);
    SetMenuItemBitmaps (hMenu, 2, MF_BYPOSITION, hbmCheckOff, hbmCheckOn);
    SetMenuItemBitmaps (hMenu, 3, MF_BYPOSITION, hbmCheckOff, hbmCheckOn);

    /* Now insert the menu into the main menu bar. */
    hWndMenu = GetMenu (hwnd);
    InsertMenu (hWndMenu, 2, MF_POPUP|MF_BYPOSITION, (WORD)hMenu, "States");

    return;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : HandlePaint ( hwnd )              *
 *                      *
 *  PURPOSE    : Handles the repainting of the main app's client area.      *
 *                      *
 ****************************************************************************
void FAR PASCAL HandlePaint (hwnd)
HWND hwnd;
{
    HDC   hdc;
    PAINTSTRUCT ps;
    RECT  rc;

    hdc = BeginPaint (hwnd, (LPPAINTSTRUCT)&ps);

    /* Center the text in the client area */
    GetClientRect (hwnd, (LPRECT)&rc);
    DrawText (hdc,
        "Down click in the window for a popup menu",
         41,
         (LPRECT)&rc,
         DT_CENTER | DT_WORDBREAK);
    EndPaint(hwnd, (LPPAINTSTRUCT)&ps);
}


/****************************************************************************
 *                      *
 *  FUNCTION   : HandleChangeColors (hwnd)            *
 *                      *
 *  PURPOSE    : Toggles the state of the Owner Draw item in the Colors     *
 *     menu. If it is on, the "Black", "Blue", "Red", and "Green" *
 *               individual menu text items are modified so that they will  *
 *     contain bands of color. Otherwise, the colors are replaced *
 *     by the text.                                               *
 *                      *
 ****************************************************************************
void FAR PASCAL HandleChangeColors(hwnd)
HWND hwnd;
{
    HMENU hMenu;
    BOOL  fOwnerDraw;

    /* Get a handle to the Colors menu. This is at position 1. */
    hMenu = GetSubMenu (GetMenu (hwnd), IDCOLORS_POS);

    /* Get the current state of the item */
    fOwnerDraw = GetMenuState ( hMenu,
        IDM_COLOROWNERDR, MF_BYCOMMAND) & MF_CHECKED;

    /* Toggle the state of the item. */
    CheckMenuItem ( hMenu,
        IDM_COLOROWNERDR,
        MF_BYCOMMAND | (fOwnerDraw ? MF_UNCHECKED : MF_CHECKED));

    if (!fOwnerDraw){
  /* Change the items to owner-draw items. Pass the RGB value for the
   * color as the application-supplied data. This makes it easier for
   * us to draw the items.
   */
  ModifyMenu(hMenu,
       IDM_BLACK,
       MF_OWNERDRAW | MF_BYCOMMAND,
       IDM_BLACK,
       (LPSTR)RGB (0,0,0));

  ModifyMenu(hMenu,
       IDM_BLUE,
       MF_OWNERDRAW | MF_BYCOMMAND,
       IDM_BLUE,
       (LPSTR)RGB (0,0,255));

  ModifyMenu(hMenu,
       IDM_RED,
       MF_OWNERDRAW | MF_BYCOMMAND,
       IDM_RED,
       (LPSTR)RGB (255,0,0));

  ModifyMenu(hMenu,
       IDM_GREEN,
       MF_OWNERDRAW | MF_BYCOMMAND,
       IDM_GREEN,
       (LPSTR)RGB (0,255,0));
    }
    else {
  /* Change the items to normal text items. */
  ModifyMenu(hMenu, IDM_BLACK, MF_BYCOMMAND, IDM_BLACK, "Black");

  ModifyMenu(hMenu, IDM_BLUE, MF_BYCOMMAND, IDM_BLUE, "Blue");

  ModifyMenu(hMenu, IDM_RED, MF_BYCOMMAND, IDM_RED, "Red");

  ModifyMenu(hMenu, IDM_GREEN, MF_BYCOMMAND, IDM_GREEN, "Green");
    }
}


/****************************************************************************
 *                      *
 *  FUNCTION   : HandleDrawItem ( hwnd, lpdis)            *
 *                      *
 *  PURPOSE    : Called in response to a WM_DRAWITEM message, i.e. when the *
 *     colors menu is being modified to an owner-draw menu, or    *
 *     one of the items is selected. It sizes the checkmark bitmap*
 *     to fit next to a color band and draws the color bands and  *
 *     the checkmark on the popup menu.          *
 *                      *
 ****************************************************************************
void FAR PASCAL HandleDrawItem(hwnd, lpdis)
HWND     hwnd;
LPDRAWITEMSTRUCT lpdis;

{
    HDC     hdcBitmap;
    HBITMAP hbmSave;
    HBRUSH  hbr;
    RECT    rc;
    LONG    checkMarkSize;
    DWORD   textColorSave;
    DWORD   bkColorSave;

    /* Get the size of the checkmark so we can leave room for it since we
     * want to be able to check the selected color.
     */
    checkMarkSize = GetMenuCheckMarkDimensions ();

    if (lpdis->itemAction == ODA_SELECT ||
  lpdis->itemAction == ODA_DRAWENTIRE){

  CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
  InflateRect ((LPRECT)&rc, (-2 - LOWORD(checkMarkSize)), -2);

  if (lpdis->itemState & ODS_SELECTED)
  {
      /* Item has been selected -- hilite with a gray frame */
      hbr = GetStockObject (GRAY_BRUSH);
      FrameRect (lpdis->hDC, (LPRECT)&rc, hbr);
  }
  else if (lpdis->itemAction == ODA_SELECT)
  {
      /* Item has been de-selected -- remove gray frame */
      hbr = CreateSolidBrush (GetSysColor (COLOR_MENU));
      FrameRect (lpdis->hDC, (LPRECT)&rc, hbr);
      DeleteObject (hbr);
  }
    }

    if (lpdis->itemAction == ODA_DRAWENTIRE){

  /* Paint the color item in the color requested. */
  hbr = CreateSolidBrush (lpdis->itemData);
  CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
  InflateRect ((LPRECT)&rc, -10-LOWORD(checkMarkSize), -10);
  FillRect (lpdis->hDC, (LPRECT)&rc, hbr);
  DeleteObject (hbr);

  if (lpdis->itemState & ODS_CHECKED){
      /* Draw the check mark if the item is checked. */
      hdcBitmap = CreateCompatibleDC (lpdis->hDC);
      hbmSave = SelectObject (hdcBitmap, hbmCheckOn);

      textColorSave = SetTextColor (lpdis->hDC, 0x00000000L);
      bkColorSave   = SetBkColor (lpdis->hDC, 0x00FFFFFFL);

      /* Use Magic bitblt op so that monochrome bitmaps preserve
         background and foreground colors. */
      BitBlt (lpdis->hDC,
        lpdis->rcItem.left,
        lpdis->rcItem.top+
         (MEASUREITEMHEIGHT - HIWORD (checkMarkSize)) / 2,
        LOWORD (checkMarkSize),
        HIWORD (checkMarkSize),
        hdcBitmap,
        0,
        0,
        ROP_PSDPxax);

      /* Restore colors and bitmap and clean up */
      SetTextColor (lpdis->hDC, textColorSave);
      SetBkColor (lpdis->hDC, bkColorSave);
      SelectObject (hdcBitmap, hbmSave);
      DeleteDC (hdcBitmap);

  }
    }
}

/****************************************************************************
 *                      *
 *  FUNCTION   : HandlePopupMenu (hwnd, point)            *
 *                      *
 *  PURPOSE    : Handles the display of the "floating" popup that appears   *
 *     on a mouse click in the app's client area.                 *
 *                      *
 ****************************************************************************
void FAR PASCAL HandlePopupMenu (hwnd, point)
HWND   hwnd;
POINT  point;

{
    HMENU hMenu;
    HMENU hMenuTrackPopup;

    /* Get the menu for the popup from the resource file. */
    hMenu = LoadMenu (hInst, "PopupMenu");
    if (!hMenu)
  return;

    /* Get the first menu in it which we will use for the call to
     * TrackPopup(). This could also have been created on the fly using
     * CreatePopupMenu and then we could have used InsertMenu() or
     * AppendMenu.
     */
    hMenuTrackPopup = GetSubMenu (hMenu, 0);

    /* Convert the mouse point to screen coordinates since that is what
     * TrackPopup expects.
     */
    ClientToScreen (hwnd, (LPPOINT)&point);

    /* Draw and track the "floating" popup */
    TrackPopupMenu (hMenuTrackPopup, 0, point.x, point.y, 0, hwnd, NULL);

    /* Destroy the menu since were are done with it. */
    DestroyMenu (hMenu);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : MenuWndProc (hWnd, message, wParam, lParam)        *
 *                      *
 *  PURPOSE    : Window function for the main app. window. Processes all the*
 *     menu selections and oter messages.          *
 *                      *
 ****************************************************************************
long FAR PASCAL MenuWndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;

{
    FARPROC lpProc;
    HMENU hMenu;
    LPDRAWITEMSTRUCT dis;
    RECT rc;


    switch (message){
  case WM_SYSCOMMAND:
      /* Show the About ... dialog */
      if (wParam == ID_ABOUT){
    lpProc = MakeProcInstance (About, hInst);
    DialogBox (hInst,
         "AboutBox",
         hWnd,
         lpProc);

    FreeProcInstance (lpProc);
    break;
      }
      else
        return DefWindowProc (hWnd, message, wParam, lParam);

  case WM_COMMAND:
      switch (wParam){
     case IDM_EXIT:
       DestroyWindow (hWnd);
       break;

     case IDM_ABOUT:
       /* Bring up the About.. dialog box */
       lpProc = MakeProcInstance (About, hInst);
       DialogBox (hInst,
            "AboutBox",
            hWnd,
            lpProc);

       FreeProcInstance (lpProc);
       break;

     case IDM_COLOROWNERDR:
         /* Change colors in color menu depending on state of this
      menu item. */
         HandleChangeColors (hWnd);
         break;

     case IDM_STATE1:
     case IDM_STATE2:
     case IDM_STATE3:
     case IDM_STATE4:
          /* Get a handle to the states menu... */
          hMenu = GetSubMenu (GetMenu (hWnd), IDSTATES_POS);

          /* Uncheck all the items. */
          CheckMenuItem (hMenu, IDM_STATE1,
             MF_BYCOMMAND | MF_UNCHECKED);
          CheckMenuItem (hMenu, IDM_STATE2,
             MF_BYCOMMAND | MF_UNCHECKED);
          CheckMenuItem (hMenu, IDM_STATE3,
             MF_BYCOMMAND | MF_UNCHECKED);
          CheckMenuItem (hMenu, IDM_STATE4,
             MF_BYCOMMAND | MF_UNCHECKED);

          /* ...and just check the selected one.*/
          CheckMenuItem (hMenu, wParam,
             MF_BYCOMMAND | MF_CHECKED);
         break;

     case IDM_BLACK:
     case IDM_RED:
     case IDM_BLUE:
     case IDM_GREEN:
          /* Get a handle to the Colors menu. */
          hMenu = GetSubMenu (GetMenu (hWnd),IDCOLORS_POS);

          /* Uncheck all the items. */
          CheckMenuItem (hMenu, IDM_BLACK,
             MF_BYCOMMAND | MF_UNCHECKED);
          CheckMenuItem (hMenu, IDM_RED,
             MF_BYCOMMAND | MF_UNCHECKED);
          CheckMenuItem (hMenu, IDM_BLUE,
             MF_BYCOMMAND | MF_UNCHECKED);
          CheckMenuItem (hMenu, IDM_GREEN,
             MF_BYCOMMAND | MF_UNCHECKED);

          /* ...and just check the selected one.*/
          CheckMenuItem (hMenu, wParam,
             MF_BYCOMMAND | MF_CHECKED);
          break;

     case IDM_FONT:
          /* Messages sent to us from TrackPopupMenu when
           * items are selected from the "floating" popups
           */
          MessageBox (hWnd,
          "A font was selected",
          "Popup Menu Alert",
          MB_APPLMODAL|MB_OK);
          break;

     case IDM_SIZE:
          MessageBox (hWnd,
          "A size was selected",
          "Popup Menu Alert",
          MB_APPLMODAL|MB_OK);
          break;

     case IDM_STYLE:
          MessageBox (hWnd,
          "A style was selected",
          "Popup Menu Alert",
          MB_APPLMODAL|MB_OK);
          break;
      }
      break;

  case WM_SIZE:
      if (lParam){
    /* If window is being sized to a non zero value...
     * invalidate it's client area.
     */
    InvalidateRect (hWnd, NULL, TRUE);
      }
      break;

  case WM_PAINT:
      HandlePaint (hWnd);
      break;

  case WM_MEASUREITEM:
      /* Use the same width for all items. We could examine the item id
         and use different widths/heights for each item. */
      ((LPMEASUREITEMSTRUCT)lParam)->itemWidth  = MEASUREITEMWIDTH;
      ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = MEASUREITEMHEIGHT;
      return TRUE;

  case WM_DRAWITEM:
      /* Redraw the "colors" menu in normal/ownerdrawmode */
      HandleDrawItem (hWnd,(LPDRAWITEMSTRUCT)lParam);
      return TRUE;
      break;

  case WM_CREATE:
      /* Create the menu */
      HandleCreate (hWnd);
      break;

  case WM_DESTROY:
      /* Delete the on/off bitmaps so that they don't waste memory. */
      DeleteObject (hbmCheckOn);
      DeleteObject (hbmCheckOff);

      PostQuitMessage (0);
      break;

  case WM_LBUTTONDOWN:
      /* Draw the "floating" popup in the app's client area */
      GetClientRect (hWnd, (LPRECT)&rc);
      if (PtInRect ((LPRECT)&rc, MAKEPOINT (lParam)))
    HandlePopupMenu (hWnd, lParam);
      break;

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


MPFILE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MULTIPAD\MPFILE.C

/***************************************************************************
 *                                                                         *
 *  MODULE    : MpFile.c                                                   *
 *                                                                         *
 *  PURPOSE   : Contains the code for File I/O for Multipad.               *
 *                                                                         *
 *  FUNCTIONS : AlreadyOpen   - Determines if a file is already open.      *
 *                                                                         *
 *              AddFile       - Creates a new MDI window and, if specified,*
 *        loads a file into it.                      *
 *                                                                         *
 *              LoadFile      - Loads a file into a MDI window.            *
 *                                                                         *
 *              ReadFile      - Calls File/Open dialog and appropriately   *
 *                              responds to the user's input.              *
 *                                                                         *
 *              SaveFile      - Saves the contents of a MDI window's edit  *
 *                              control to a file.                         *
 *                                                                         *
 *              SetSaveFrom   - Formats the "Save 'file' to" string.       *
 *                                                                         *
 *              SaveAsDlgProc - Dialog function for the File/SaveAs dialog.*
 *                                                                         *
 *              ChangeFile    - Calls File/SaveAs dialog.                  *
 *                                                                         *
 ***************************************************************************/
#include "multipad.h"

VOID NEAR PASCAL GetFileName(PSTR);
int FAR PASCAL DialogBoxParam(HANDLE,LPSTR,HWND,FARPROC,LONG);

OFSTRUCT  of;
/****************************************************************************
 *                                                                          *
 *  FUNCTION   : AlreadyOpen(szFile)                                        *
 *                                                                          *
 *  PURPOSE    : Checks to see if the file described by the string pointed  *
 *               to by 'szFile' is already open.                            *
 *                                                                          *
 *  RETURNS    : a handle to the described file's window if that file is    *
 *               already open;  NULL otherwise.                             *
 *                                                                          *
 ****************************************************************************

HWND AlreadyOpen(char *szFile)
{
    int     iDiff;
    HWND    hwndCheck;
    char    szChild[64];
    LPSTR   lpChild, lpFile;
    int     wFileTemp;

    /* Open the file with the OF_PARSE flag to obtain the fully qualified
     * pathname in the OFSTRUCT structure.
     */
    wFileTemp = OpenFile ((LPSTR)szFile, (LPOFSTRUCT)&of, OF_PARSE);
    if (! wFileTemp)
  return(NULL);
    _lclose (wFileTemp);

    /* Check each MDI child window in Multipad */
    for (   hwndCheck = GetWindow(hwndMDIClient, GW_CHILD);
      hwndCheck;
      hwndCheck = GetWindow(hwndCheck, GW_HWNDNEXT)   ) {
  /* Initialization  for comparison */
  lpChild = szChild;
  lpFile = AnsiUpper((LPSTR) of.szPathName);
  iDiff = 0;

  /* Skip icon title windows */
  if (GetWindow(hwndCheck, GW_OWNER))
      continue;

  /* Get current child window's name */
  GetWindowText(hwndCheck, lpChild, 64);

  /* Compare window name with given name */
  while ((*lpChild) && (*lpFile) && (!iDiff)){
      if (*lpChild++ != *lpFile++)
    iDiff = 1;
  }

  /* If the two names matched, the file is already   */
  /* open -- return handle to matching child window. */
  if (!iDiff)
      return(hwndCheck);
    }
    /* No match found -- file is not open -- return NULL handle */
    return(NULL);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : AddFile (lpName)              *
 *                      *
 *  PURPOSE    : Creates a new MDI window. If the lpName parameter is not   *
 *     NULL, it loads a file into the window.         *
 *                      *
 *  RETURNS    : HWND  - A handle to the new window.          *
 *                      *
 ****************************************************************************

HWND FAR PASCAL AddFile(pName)
char * pName;
{
    HWND hwnd;

    char      sz[160];
    MDICREATESTRUCT mcs;

    if (!pName) {
  /* The pName parameter is NULL -- load the "Untitled" string from */
  /* STRINGTABLE and set the title field of the MDI CreateStruct.    */
  LoadString (hInst, IDS_UNTITLED, sz, sizeof(sz));
  mcs.szTitle = (LPSTR)sz;
    }
    else
  /* Title the window with the fully qualified pathname obtained by
   * calling OpenFile() with the OF_PARSE flag (in function
   * AlreadyOpen(), which is called before AddFile().
   */
  mcs.szTitle = of.szPathName;

    mcs.szClass = szChild;
    mcs.hOwner  = hInst;

    /* Use the default size for the window */
    mcs.x = mcs.cx = CW_USEDEFAULT;
    mcs.y = mcs.cy = CW_USEDEFAULT;

    /* Set the style DWORD of the window to default */
    mcs.style = styleDefault;

    /* tell the MDI Client to create the child */
    hwnd = (WORD)SendMessage (hwndMDIClient,
            WM_MDICREATE,
            0,
            (LONG)(LPMDICREATESTRUCT)&mcs);

    /* Did we get a file? Read it into the window */
    if (pName){
  if (!LoadFile(hwnd, pName)){
      /* File couldn't be loaded -- close window */
      SendMessage(hwndMDIClient, WM_MDIDESTROY, (WORD) hwnd, 0L);
  }
    }

    return hwnd;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : LoadFile (lpName)              *
 *                      *
 *  PURPOSE    : Given the handle to a MDI window and a filename, reads the *
 *     file into the window's edit control child.                 *
 *                      *
 *  RETURNS    : TRUE  - If file is sucessfully loaded.         *
 *     FALSE - Otherwise.              *
 *                      *
 ****************************************************************************

int FAR PASCAL LoadFile (hwnd, pName)
HWND hwnd;
char * pName;
{
    WORD   wLength;
    HANDLE hT;
    LPSTR  lpB;
    HWND   hwndEdit;
    int    fh;

    hwndEdit = GetWindowWord (hwnd, GWW_HWNDEDIT);

    /* The file has a title, so reset the UNTITLED flag. */
    SetWindowWord(hwnd, GWW_UNTITLED, FALSE);

    fh = _lopen (pName, 0);

    /* Make sure file has been opened correctly */
    if ( fh < 0 )
  goto error;

    /* Find the length of the file */
    wLength = (WORD)_llseek (fh, 0L, 2);
    _llseek (fh, 0L, 0);

    /* Attempt to reallocate the edit control's buffer to the file size */
    hT = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
    if (LocalReAlloc(hT, wLength+1, LHND) == NULL) {
  /* Couldn't reallocate to new size -- error */
  _lclose (fh);
  goto error;
    }

    /* read the file into the buffer */
    if (wLength != _lread (fh, (lpB = (LPSTR)LocalLock (hT)), wLength))
  MPError (hwnd, MB_OK|MB_ICONHAND, IDS_CANTREAD, (LPSTR)pName);

    /* Zero terminate the edit buffer */
    lpB[wLength] = 0;
    LocalUnlock (hT);

    SendMessage (hwndEdit, EM_SETHANDLE, hT, 0L);
    _lclose (fh);

    return TRUE;

error:
    /* Report the error and quit */
    MPError(hwnd, MB_OK | MB_ICONHAND, IDS_CANTOPEN, (LPSTR)pName);
    return FALSE;
}

/****************************************************************************
 *                                                                          *
 *  FUNCTION   : ReadFile(hwnd)                                             *
 *                                                                          *
 *  PURPOSE    : Called in response to a File/Open menu selection. It asks  *
 *               the user for a file name and responds appropriately.       *
 *                                                                          *
 ****************************************************************************

VOID FAR PASCAL ReadFile(HWND hwnd)
{
    char    szFile[128];
    HWND    hwndFile;

    GetFileName (szFile);

    /* If the result is not the empty string -- take appropriate action */
    if (*szFile) {
  /* Is file already open?? */
  if (hwndFile = AlreadyOpen(szFile)) {
      /* Yes -- bring the file's window to the top */
      BringWindowToTop(hwndFile);
  }
  else {
      /* No -- make a new window and load file into it */
      AddFile(szFile);
  }
    }
}

/****************************************************************************
 *                      *
 *  FUNCTION   : SaveFile (hwnd)              *
 *                      *
 *  PURPOSE    : Saves contents of current edit control to disk.      *
 *                      *
 ****************************************************************************

VOID FAR PASCAL SaveFile( hwnd )

HWND hwnd;
{
    HANDLE   hT;
    LPSTR    lpT;
    char     szFile[128];
    WORD     cch;
    int      fh;
    OFSTRUCT of;
    HWND     hwndEdit;

    PSTR     pch;

    hwndEdit = GetWindowWord ( hwnd, GWW_HWNDEDIT);
    GetWindowText (hwnd, szFile, sizeof(szFile));

    /* If there is no extension (control is 'Untitled') add .TXT as extension
    for (cch = FALSE, lpT = szFile; *lpT; lpT++)
  switch (*lpT){
      case '.':
     cch = TRUE;
     break;

      case '\\':
      case ':' :
     cch = FALSE;
     break;
  }
    if (!cch)
  LoadString (hInst, IDS_ADDEXT, lpT, lpT - (LPSTR)szFile);

    fh = OpenFile (szFile, &of, OF_WRITE | OF_CREATE);

    /* If file could not be opened, quit */
    if (fh < 0){
  MPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTCREATE, (LPSTR)szFile);
  return;
    }

    /* Find out the length of the text in the edit control */
    cch = GetWindowTextLength (hwndEdit);

    /* Obtain a handle to the text buffer */
    hT  = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
    lpT = (LPSTR)LocalLock (hT);

    /* Write out the contents of the buffer to the file. */
    if (cch != _lwrite (fh, lpT, cch))
  MPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTWRITE, (LPSTR)szFile);

    /* Clean up */
    LocalUnlock (hT);
    SendMessage (hwndEdit, EM_SETHANDLE, hT, 0L);

    _lclose (fh);

    return;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : SetSaveFrom ()               *
 *                      *
 *  PURPOSE    : Formats the "Save 'file' to .." string.        *
 *                      *
 ****************************************************************************

VOID NEAR PASCAL SetSaveFrom ( hwnd , psz)
HWND hwnd;
PSTR psz;
{
    char szFmt[32];
    char szText[160];

    /* The text string in the .RC file contains the format string... */
    GetDlgItemText( hwnd, IDD_SAVEFROM, szFmt, sizeof(szFmt));

    /* NOTE: this (LPSTR) cast MUST be here... wsprintf() is a cdecl
     * (C calling conventions) function with varying args... there is
     * no way for the compiler to know that all strings must be LPSTR's
     * and do the conversion, so we have to be careful about wsprintf()'s.
     */
    wsprintf ( szText, szFmt, (LPSTR)psz);

    /* set the text in the static control */
    SetDlgItemText (hwnd, IDD_SAVEFROM, szText);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : SaveAsDlgProc(hwnd, message, wParam, lParam)        *
 *                      *
 *  PURPOSE    : Dialog function File/SaveAs. It waits for a filename, and  *
 *     then calls SaveFile or cancels the operation.        *
 *                      *
 ****************************************************************************

BOOL FAR PASCAL SaveAsDlgProc( hwnd, message, wParam, lParam)
HWND hwnd;
WORD message;
WORD wParam;
LONG lParam;
{
    char   sz[64];
    char   *pch;
    BOOL   fExt;
    HWND   hwndSave;

    switch (message){

  case WM_INITDIALOG:

      /* Identify the window whose contents we're saving */
      hwndSave = LOWORD (lParam);

      /* Set it's name in the property list */
      SetProp (hwnd, PROP_FILENAME, hwndSave);

      GetWindowText (hwndSave, sz, sizeof(sz));

      /* Set the save from string... */
      SetSaveFrom (hwnd,sz);

      /* Generate a filename complete with extension */
      AnsiUpper (sz);
      for (fExt = FALSE, pch = sz; *pch; pch++)
    if (*pch == '.')
        fExt = TRUE;
    else if (*pch == '\\')
        fExt = FALSE;
      if (!fExt)
    LoadString (hInst, IDS_ADDEXT, (LPSTR)pch, pch - sz);

      /* Display the filename in the edit control */
      SetDlgItemText (hwnd, IDD_SAVETO, sz);

      /* Select the entire range of text */
      SendDlgItemMessage (hwnd, IDD_SAVETO, EM_SETSEL, 0, MAKELONG (0,100));

      DlgDirList (hwnd, "*.*", IDD_DIRS, IDD_PATH, ATTR_DIRS);

      /* enable OK butto iff edit control is nonempty */
      if (!*sz)
    EnableWindow (GetDlgItem (hwnd, IDOK), FALSE);
      break;

  case WM_COMMAND:
      switch (wParam){
    case IDCANCEL:
        /* Abort operation */
        EndDialog(hwnd,1);
        break;

    case IDOK:
       /*  Just change the title of the MDI child. The calling
        *  function of ChangeFile(), which uses the title text
        *  for the filename, will do the actual save.
        */
        hwndSave = GetProp (hwnd, PROP_FILENAME);
        GetDlgItemText (hwnd, IDD_SAVETO, sz, sizeof(sz));
        AnsiUpper ((LPSTR)sz);
        SetWindowText (hwndSave, sz);
        EndDialog (hwnd, 0);
        break;

    case IDD_SAVETO:
       /* If the edit control changes, check to see if its empty.
        * enable OK if it contains something
        */
        if (HIWORD (lParam) != EN_CHANGE)
      return FALSE;
        EnableWindow (GetDlgItem (hwnd, IDOK),
      (WORD) SendDlgItemMessage (hwnd,
               IDD_SAVETO,
               WM_GETTEXTLENGTH,
               0,
               0L));
        break;

    case IDD_DIRS:
        if (HIWORD(lParam)==LBN_DBLCLK){
      char szT[64];

      DlgDirSelect ( hwnd, szT, IDD_DIRS);
      lstrcat ( szT, "*.*");
      DlgDirList (hwnd, szT, IDD_DIRS, IDD_PATH, ATTR_DIRS);
      break;
        }
        return FALSE;

    default:
        return FALSE;
      }

  default:
      return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : ChangeFile (hwnd)              *
 *                      *
 *  PURPOSE    : Invokes the File/SaveAs dialog.          *
 *                      *
 *  RETURNS    : TRUE  - if user selected OK or NO.          *
 *     FALSE - otherwise.              *
 *                      *
 ****************************************************************************

BOOL FAR PASCAL ChangeFile (hwnd)
HWND hwnd;
{
    FARPROC lpfn;
    int     i;

    lpfn = MakeProcInstance (SaveAsDlgProc, hInst);
    i = DialogBoxParam (hInst, IDD_SAVEAS, hwnd, lpfn, MAKELONG (hwnd, 0));
    FreeProcInstance (lpfn);
    if (!i)
  SetWindowWord (hwnd, GWW_UNTITLED, 0);
    return !i;
}


MPFIND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MULTIPAD\MPFIND.C

/***************************************************************************
 *                     *
 *  MODULE  : MpFind.c                   *
 *                     *
 *  PURPOSE  : Code to do text searches in MultiPad.        *
 *                     *
 *  FUNCTIONS  : RealSlowCompare () - Compares subject string with target *
 *               string.           *
 *                     *
 *      FindText ()       - Looks for the search string in the  *
 *               active window.         *
 *                     *
 *      FindPrev ()       - Find previous occurence of search   *
 *               string.           *
 *                     *
 *      FindNext ()       - Find next occurence of search string*
 *                     *
 *      FindDlgProc ()     - Dialog function for Search/Find.    *
 *                     *
 *      Find ()       - Invokes FindDlgProc ()       *
 *                     *
 ***************************************************************************/
#include "multipad.h"

#undef HIWORD
#undef LOWORD

#define HIWORD(l) (((WORD*)&(l))[1])
#define LOWORD(l) (((WORD*)&(l))[0])

BOOL fCase     = FALSE;    /* Turn case sensitivity off */
char szSearch[160] = "";       /* Initialize search string  */

/****************************************************************************
 *                      *
 *  FUNCTION   : RealSlowCompare ()              *
 *                      *
 *  PURPOSE    : Compares subject string with the target string. This fn/   *
 *     is called repeatedly so that all substrings are compared,  *
 *     which makes it O(n ** 2), hence it's name.                 *
 *                      *
 *  RETURNS    : TRUE  - If pSubject is identical to pTarget.        *
 *     FALSE - otherwise.              *
 *                      *
 ****************************************************************************

BOOL NEAR PASCAL RealSlowCompare (pSubject, pTarget )
register PSTR pSubject;
register PSTR pTarget;
{
    if (fCase){
  while (*pTarget)
      if (*pTarget++ != *pSubject++)
    return FALSE;
    }
    else{
  /* If case-insensitive, convert both subject and target to lowercase
   * before comparing.
   */
  AnsiLower ((LPSTR)pTarget);
  while (*pTarget)
      if (*pTarget++ != (char)(DWORD)AnsiLower ((LPSTR)(DWORD)(BYTE)*pSubject
    return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : FindText ()                *
 *                      *
 *  PURPOSE    : Finds the search string in the active window according to  *
 *     search direction (dch) specified ( -1 for reverse and 1 for*
 *     forward searches).              *
 *                      *
 ****************************************************************************
VOID NEAR PASCAL FindText( dch )
register int dch;

{
    register PSTR pText;
    HANDLE    hT;
    LONG    l;
    WORD    cch;
    int     i;

    if (!*szSearch)
  return;

    /* Find the current selection range */
    l = SendMessage(hwndActiveEdit, EM_GETSEL, 0, 0L);

    /* Get the handle to the text buffer and lock it */
    hT    = (HANDLE)SendMessage (hwndActiveEdit, EM_GETHANDLE, 0, 0L);
    pText = LocalLock(hT);

    /* Get the length of the text */
    cch = (WORD)SendMessage (hwndActiveEdit, WM_GETTEXTLENGTH, 0, 0L);

    /* Start with the next char. in selected range ... */
    pText += LOWORD (l) + dch;

    /* Compute how many characters are before/after the current selection*/
    if (dch < 0)
  i = LOWORD (l);
    else
  i = cch - LOWORD (l) + 1 - lstrlen (szSearch);

    /* While there are uncompared substrings... */
    while ( i > 0){
  LOWORD(l)+=dch;

  /* Does this substring match? */
  if (RealSlowCompare(pText,szSearch)){

      /* Yes, unlock the buffer.*/
      LocalUnlock(hT);

      /* Select the located string */
      HIWORD(l) = LOWORD(l) + lstrlen (szSearch);
      SendMessage (hwndActiveEdit, EM_SETSEL, 0, l);
      return;
  }
  i--;

  /* increment/decrement start position by 1 */
  pText += dch;
    }

    /* Not found... unlock buffer. */
    LocalUnlock (hT);

    /* Give a message */
    MPError (hwndFrame, MB_OK | MB_ICONEXCLAMATION, IDS_CANTFIND, (LPSTR)szSe

    return;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : FindPrev ()                *
 *                      *
 *  PURPOSE    : Finds the previous occurence of the search string. Calls   *
 *     FindText () with a negative search direction.        *
 *                      *
 ****************************************************************************
VOID FAR PASCAL FindPrev(void)
{
    FindText(-1);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : FindNext ()                *
 *                      *
 *  PURPOSE    : Finds the next occurence of search string. Calls      *
 *     FindText () with a positive search direction.        *
 *                      *
 ****************************************************************************
VOID FAR PASCAL FindNext(void)
{
    FindText(1);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : FindDlgProc(hwnd, message, wParam, lParam)        *
 *                      *
 *  PURPOSE    : Dialog function for the Search/Find command. Prompts user  *
 *     for target string, case flag and search direction.      *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL FindDlgProc(hwnd, msg, wParam, lParam)
HWND hwnd;
WORD msg;
WORD wParam;
LONG lParam;
{
    switch (msg){
  case WM_INITDIALOG:{

      /* Check/uncheck case button */
      CheckDlgButton (hwnd, IDD_CASE, fCase);

      /* Set default search string to most recently searched string */
      SetDlgItemText (hwnd, IDD_SEARCH, szSearch);

      /* Allow search only if target is nonempty */
      if (!lstrlen (szSearch)){
    EnableWindow (GetDlgItem (hwnd, IDOK), FALSE);
    EnableWindow (GetDlgItem (hwnd, IDD_PREV), FALSE);
      }
      break;
  }

  case WM_COMMAND:{

      /* Search forward by default (see IDOK below) */
      int i = 1;

      switch (wParam){
    /* if the search target becomes non-empty, enable searching */
    case IDD_SEARCH:
        if (HIWORD (lParam) == EN_CHANGE){
      if (!(WORD) SendDlgItemMessage (hwnd,
              IDD_SEARCH,
              WM_GETTEXTLENGTH,
              0,
              0L))
          i = FALSE;
      else
          i = TRUE;
      EnableWindow (GetDlgItem (hwnd, IDOK), i);
      EnableWindow (GetDlgItem (hwnd, IDD_PREV), i);
        }
        break;

    case IDD_CASE:
        /* Toggle state of case button */
        CheckDlgButton (hwnd,
            IDD_CASE,
            !IsDlgButtonChecked (hwnd, IDD_CASE));
        break;

    case IDD_PREV:
        /* Set direction to backwards */
        i=-1;
        /*** FALL THRU ***/

    case IDOK:
        /* Save case selection */
        fCase = IsDlgButtonChecked( hwnd, IDD_CASE);

        /* Get search string */
        GetDlgItemText (hwnd, IDD_SEARCH, szSearch, sizeof (szSearch));

        /* Find the text */
        FindText (i);
        /*** FALL THRU ***/

    /* End the dialog */
    case IDCANCEL:
        EndDialog (hwnd, 0);
        break;

    default:
        return FALSE;
      }
      break;
  }
  default:
      return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : Find()                 *
 *                      *
 *  PURPOSE    : Invokes the Search/Find dialog.          *
 *                      *
 ****************************************************************************

VOID FAR PASCAL Find()
{
    FARPROC lpfn;

    lpfn = MakeProcInstance (FindDlgProc, hInst);
    DialogBox (hInst, IDD_FIND, hwndFrame, lpfn);
    FreeProcInstance (lpfn);
}


MPINIT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MULTIPAD\MPINIT.C

/***************************************************************************
 *                     *
 *  MODULE  : MpInit.c               *
 *                     *
 *  PURPOSE  : Contains initialization code for MultiPad.       *
 *                     *
 *  FUNCTIONS  : InitializeApplication() - Sets up Class data structure   *
 *              and registers window class.    *
 *                     *
 *      InitializeInstance ()   - Does a per-instance initial-   *
 *              ization of MultiPad. Creates   *
 *              the "frame" and MDI client.    *
 *                     *
 ***************************************************************************/
#include "multipad.h"

char szFrame[] = "mpframe";   /* Class name for "frame" window */
char szChild[] = "mpchild";   /* Class name for MDI window     */

/****************************************************************************
 *                      *
 *  FUNCTION   : InitializeApplication ()            *
 *                      *
 *  PURPOSE    : Sets up the class data structures and does a one-time      *
 *     initialization of the app by registering the window classes*
 *                      *
 *  RETURNS    : TRUE  - If RegisterClass() was successful for both classes.*
 *     FALSE - otherwise.              *
 *                      *
 ****************************************************************************

BOOL FAR PASCAL InitializeApplication()
{
    WNDCLASS  wc;

    /* Register the frame class */
    wc.style       = 0;
    wc.lpfnWndProc   = MPFrameWndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInst;
    wc.hIcon       = LoadIcon(hInst,IDMULTIPAD);
    wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
    wc.hbrBackground = COLOR_APPWORKSPACE+1;
    wc.lpszMenuName  = IDMULTIPAD;
    wc.lpszClassName = szFrame;

    if (!RegisterClass (&wc) )
  return FALSE;

    /* Register the MDI child class */
    wc.lpfnWndProc   = MPMDIChildWndProc;
    wc.hIcon       = LoadIcon(hInst,IDNOTE);
    wc.lpszMenuName  = NULL;
    wc.cbWndExtra    = CBWNDEXTRA;
    wc.lpszClassName = szChild;

    if (!RegisterClass(&wc))
  return FALSE;

    return TRUE;

}

/****************************************************************************
 *                      *
 *  FUNCTION   : InitializeInstance ()              *
 *                      *
 *  PURPOSE    : Performs a per-instance initialization of MultiPad. It     *
 *     also creates the frame and an MDI window.        *
 *                      *
 *  RETURNS    : TRUE  - If initialization was successful.        *
 *     FALSE - otherwise.              *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL InitializeInstance(LPSTR lpCmdLine, WORD nCmdShow)
{
    extern HWND  hwndMDIClient;
    char   sz[80], *pCmdLine;
    HDC    hdc;
    HMENU   hmenu;

    /* Get the base window title */
    LoadString (hInst, IDS_APPNAME, sz, sizeof(sz));

    /* Create the frame */
    hwndFrame = CreateWindow (szFrame,
            sz,
            WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
            CW_USEDEFAULT,
            0,
            CW_USEDEFAULT,
            0,
            NULL,
            NULL,
            hInst,
            NULL);

    if ((!hwndFrame) || (!hwndMDIClient))
  return FALSE;

    /* Load main menu accelerators */
    if (!(hAccel = LoadAccelerators (hInst, IDMULTIPAD)))
  return FALSE;

    /* Display the frame window */
    ShowWindow (hwndFrame, nCmdShow);
    UpdateWindow (hwndFrame);

    /* If the command line string is empty, nullify the pointer to it
    ** else copy command line into our data segment
    */
    if ( lpCmdLine && !(*lpCmdLine))
       pCmdLine = NULL;
    else {
        pCmdLine = (char *) LocalAlloc(LPTR, lstrlen(lpCmdLine) + 1);
        if (pCmdLine)
           lstrcpy(pCmdLine, lpCmdLine);
    }

    /* Add the first MDI window */
    AddFile (pCmdLine);

    /* if we allocated a buffer then free it */
    if (pCmdLine)
        LocalFree((LOCALHANDLE) pCmdLine);

    /* Default to minimized windows after the first. */
    styleDefault = 0L;

    return TRUE;

}


MPOPEN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MULTIPAD\MPOPEN.C

/***************************************************************************
 *                     *
 *  MODULE  : MpOpen.c               *
 *                     *
 *  PURPOSE  : Contains the file open dialog function and it's helper   *
 *      functions.               *
 *                     *
 *  FUNCTIONS  : IsWild ()        - Ascertains that the input string   *
 *          contains a DOS wildcard character. *
 *                     *
 *      SelectFile()        - If filename supplied contains a    *
 *          wildcard, this function fills the  *
 *          listboxes in File/Open dialog, else*
 *          the dialog is closed.       *
 *                     *
 *      FileOpenDlgProc()   - Dialog funcion for the File/Open   *
 *          dialog.          *
 *                     *
 *      GetFileName ()      - Gets a file name from the user.    *
 *                     *
 ***************************************************************************/
#include "multipad.h"

char szPropertyName [] = "FILENAME";/* Name of the File name property list it

int FAR PASCAL DialogBoxParam ( HANDLE, LPSTR, HWND, FARPROC, LONG);


/****************************************************************************
 *                      *
 *  FUNCTION   : IsWild ( psz )               *
 *                      *
 *  PURPOSE    : Checks if the string (referenced by a NEAR pointer)      *
 *     contains a DOS wildcard character ("*" or "?").      *
 *                      *
 *  RETURNS    : TRUE  - iff the string contains a wildcard character.      *
 *     FALSE - otherwise.             .      *
 *                      *
 ****************************************************************************
BOOL NEAR PASCAL IsWild( psz )
register PSTR psz;
{
    for(;;)
  switch (*psz++){
      case '*':
      case '?':
    /* Found wildcard */
    return TRUE;

      case 0:
    /* Reached end of string */
    return FALSE;

      default:
    continue;
  }
}

/****************************************************************************
 *                      *
 *  FUNCTION   : FileExists(pch)                                            *
 *                      *
 *  PURPOSE    : Checks to see if a file exists with the path/filename      *
 *               described by the string pointed to by 'pch'.               *
 *                      *
 *  RETURNS    : TRUE  - if the described file does exist.                  *
 *               FALSE - otherwise.                                         *
 *                      *
 ****************************************************************************

BOOL FileExists(PSTR pch)
{
  int fh;

  if ((fh = _lopen((LPSTR) pch, 0)) < 0)
       return(FALSE);

  _lclose(fh);
  return(TRUE);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : SelectFile ( hwnd )              *
 *                      *
 *  PURPOSE    : Reads the string in the edit control of the File/Open      *
 *     dialog. If it contains a wildcard, then it attempts to     *
 *     fill the listboxes in the File/Open dialog. Othewise it    *
 *     ends the dialog. Modifies the FILENAME item in the property*
 *     list of the window.              *
 *                      *
 ****************************************************************************

VOID NEAR PASCAL SelectFile( hwnd )

register HWND hwnd;
{
    register PSTR pch;
    PSTR    pch2;
    int     cch;

    char    szBuf[256];

    /* Get handle (near address) to filename data in window's property list *
    pch = (PSTR)GetProp (hwnd, PROP_FILENAME);

    /* Get the text from the dialog's edit control into this address */
    GetDlgItemText (hwnd, IDD_FILENAME, pch, 64);

    if ( IsWild (pch)){
  /* Select the directory and make a listing of the directories */
  DlgDirList(hwnd, (LPSTR)pch, IDD_DIRS, IDD_PATH, ATTR_DIRS);

  /* Obtain the filename-only part of the path in the edit control */
  for (pch2 = pch; *pch; pch++)
      if (*pch == '\\' || *pch == ':')
    pch2 = pch + 1;

  /* List the files in this directory based on the wildcard. */
  DlgDirList(hwnd, (LPSTR)pch2, IDD_FILES, IDD_PATH, ATTR_FILES);

  /* Set the dialog's edit control to the filename part of path
   * string.
   */
  SetDlgItemText (hwnd, IDD_FILENAME, pch2);
    }
    else
    {
  /* The filename in the property list is not a wildcard */
  if (FileExists (pch)){

      RemoveProp (hwnd, PROP_FILENAME);
      EndDialog (hwnd, 0);
  }
  else{
      MPError ( hwnd, MB_OK | MB_SYSTEMMODAL, IDS_CANTOPEN, (LPSTR) pch);
      SetActiveWindow (hwnd);
  }
    }
}
/****************************************************************************
 *                      *
 *  FUNCTION   : FileOpenDlgProc()              *
 *                      *
 *  PURPOSE    : Dialog function for the File/Open dialog. Takes care of    *
 *     calling the appropriate functions for extracting the      *
 *     filename and wildcard, filling the listboxes and changing  *
 *     the FILENAME item in the property list for the window.     *
 *                      *
 ****************************************************************************

BOOL FAR PASCAL FileOpenDlgProc ( hwnd, message, wParam, lParam)
register HWND hwnd;
WORD        message;
register WORD wParam;
LONG        lParam;
{
    PSTR pch;

    switch (message){

  case WM_INITDIALOG:
      /* Set the default file extension on edit window, and try to
       * get a listing of the files and directories.
       */
      SetDlgItemText ( hwnd, IDD_FILENAME, DEFFILESEARCH);
      SetProp (hwnd, PROP_FILENAME, LOWORD(lParam));
      SendDlgItemMessage (hwnd, IDD_FILENAME, EM_LIMITTEXT, 64, 0L);
      SelectFile (hwnd);
      break;

  case WM_COMMAND:
      switch (wParam){
    case IDOK:
        SelectFile(hwnd);
        break;

    case IDCANCEL:
        /* Set the filename in the prop. list to NULL and quit */
        pch  = (PSTR) GetProp (hwnd, PROP_FILENAME);
        *pch = 0;
        EndDialog (hwnd, 0);
        break;

    case IDD_FILENAME:
        /* Enable the OK button if the edit control has text. */
        EnableWindow ( GetDlgItem (hwnd, IDOK),
           GetWindowTextLength ((HWND)LOWORD (lParam)));
        break;

    case IDD_FILES:

        /* The files listbox. If file selection has changed, fill
         * the new filename into the property list buffer and set
         * text in edit control.
         */
        if (HIWORD(lParam) == LBN_SELCHANGE){
      pch = (PSTR) GetProp (hwnd, PROP_FILENAME);
      DlgDirSelect (hwnd, (LPSTR)pch, IDD_FILES);
      SetDlgItemText (hwnd, IDD_FILENAME, (LPSTR)pch);
        }
        else if (HIWORD(lParam) == LBN_DBLCLK)
      /* if the item was double-clicked, try to open it */
      SelectFile(hwnd);
        break;

    case IDD_DIRS:

        /* The directories listbox. Append current filename in edit
         * control (stripped of the path prefix) to the name from
         * the property list and set the new string in the edit
         * control.
         */
        if (HIWORD(lParam) == LBN_SELCHANGE){

      PSTR pch2, pchT, pchS;

      pch = (PSTR) GetProp (hwnd, PROP_FILENAME);

      /* Get the new drive/dir */
      DlgDirSelect (hwnd, pch, IDD_DIRS);
      pch2 = pch + lstrlen(pch);

      /* Fetch current contents of dialog's edit control and append
       * it to name from property list... */
      GetDlgItemText(hwnd,IDD_FILENAME,(LPSTR)pch2,64);
      if (*pch2 == 0){
          SetDlgItemText(hwnd, IDD_FILENAME, DEFFILESEARCH);
          GetDlgItemText(hwnd,IDD_FILENAME,(LPSTR)pch2,64);
      }
      else {
          pchS = pch;
          for (pchT = pch = pch2; *pch; pch++) {
        if (*pch == '\\' || *pch == ':')
            pchT = pch2;
        else
            *pchT++ = *pch;
          }
          *pchT = 0;
          pch = pchS;
      }

      /* Set the edit control with new string */
      SetDlgItemText (hwnd, IDD_FILENAME, (LPSTR)pch);
        }
        else if (HIWORD(lParam) == LBN_DBLCLK)
      SelectFile (hwnd);
        break;

    default:
        return FALSE;
      }
      break;

  default:
      return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : GetFilename ( pstr )              *
 *                      *
 *  PURPOSE    : Gets a filename from the user by calling the File/Open     *
 *     dialog.                *
 *                      *
 ****************************************************************************
VOID NEAR PASCAL GetFileName(PSTR pstr)
{
    FARPROC lpfn;

    lpfn = MakeProcInstance (FileOpenDlgProc, hInst);
    DialogBoxParam (hInst, IDD_FILEOPEN, hwndFrame, lpfn, MAKELONG(pstr,0));
    FreeProcInstance (lpfn);
}


MPPRINT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MULTIPAD\MPPRINT.C

/***************************************************************************
 *                     *
 *  MODULE  : MpPrint()               *
 *                     *
 *  PURPOSE  : Printing code for MultiPad.           *
 *                     *
 *  FUNCTIONS  : GetPrinterDC ()     -  Creates a printer DC for the *
 *                default device.       *
 *                     *
 *      AbortProc ()       -  Export proc. for GDI to check*
 *                print abort.       *
 *                     *
 *      PrintDlgProc ()     -  Dialog function for the print*
 *                cancel dialog.       *
 *                     *
 *      PrintFile ()       -  Prints the contents of the   *
 *                edit control.       *
 *                     *
 *      GetInitializationData () -  Gets DC initialisation data  *
 *                from a DC supporting     *
 *                ExtDeviceMode().       *
 *                     *
 ***************************************************************************/
#include "multipad.h"

BOOL fAbort;    /* TRUE if the user has aborted the print job   */
HWND hwndPDlg;    /* Handle to the cancel print dialog     */
char szDevice[160];  /* Contains the device, the driver, and the port */
PSTR szDriver;    /* Pointer to the driver name       */
PSTR szPort;    /* Port, ie, LPT1         */
PSTR szTitle;    /* Global pointer to job title       */
int iPrinter = 0;  /* level of available printer support.     */
      /* 0 - no printer available       */
      /* 1 - printer available       */
      /* 2 - driver supports 3.0 device initialization */
HANDLE hInitData=NULL;  /* handle to initialization data     */

char szExtDeviceMode[] = "EXTDEVICEMODE";

/****************************************************************************
 *                      *
 *  FUNCTION   : GetPrinterDC ()              *
 *                      *
 *  PURPOSE    : Creates a printer display context for the default device.  *
 *     As a side effect, it sets the szDevice and szPort variables*
 *     It also sets iPrinter to the supported level of printing.  *
 *                      *
 *  RETURNS    : HDC   - A handle to printer DC.          *
 *                      *
 ****************************************************************************
HDC FAR PASCAL GetPrinterDC(void)
{
    char     szT[32];
    HDC      hdc;
    LPSTR    lpdevmode = NULL;

    iPrinter = 0;

    /* Get the printer information from win.ini into a buffer and
     * null terminate it.
     */
    GetProfileString ( "windows", "device", "" ,szDevice, sizeof(szDevice));
    for (szDriver = szDevice; *szDriver && *szDriver != ','; szDriver++)
  ;
    if (*szDriver)
  *szDriver++ = 0;

    /* From the current position in the buffer, null teminate the
     * list of ports
     */
    for (szPort = szDriver; *szPort && *szPort != ','; szPort++)
  ;
    if (*szPort)
  *szPort++ = 0;

    /* if the device, driver and port buffers all contain meaningful data,
     * proceed.
     */
    if (!*szDevice || !*szDriver || !*szPort){
  *szDevice = 0;
  return NULL;
    }

    /* Create the printer display context */
    if (hInitData){
  /* Get a pointer to the initialization data */
  lpdevmode = (LPSTR) LocalLock (hInitData);

  if (lstrcmp (szDevice, lpdevmode)){
      /* User has changed the device... cancel this setup, as it is
       * invalid (although if we worked harder we could retain some
       * of it).
       */
      lpdevmode = NULL;
      LocalUnlock (hInitData);
      LocalFree (hInitData);
      hInitData = NULL;
  }
    }
    hdc = CreateDC (szDriver, szDevice, szPort, lpdevmode);

    /* Unlock initialization data */
    if (hInitData)
  LocalUnlock (hInitData);

    if (!hdc)
  return NULL;


    iPrinter = 1;

    /* Find out if ExtDeviceMode() is supported and set flag appropriately */
    if (GetProcAddress (GetModuleHandle (szDriver), szExtDeviceMode))
  iPrinter = 2;

    return hdc;

}

/****************************************************************************
 *                      *
 *  FUNCTION   : AbortProc()                *
 *                      *
 *  PURPOSE    : To be called by GDI print code to check for user abort.    *
 *                      *
 ****************************************************************************
int FAR PASCAL AbortProc ( hdc, reserved )
HDC hdc;
WORD reserved;
{
    MSG msg;

    /* Allow other apps to run, or get abort messages */
    while (!fAbort && PeekMessage (&msg, NULL, NULL, NULL, TRUE))
  if (!hwndPDlg || !IsDialogMessage (hwndPDlg, &msg)){
      TranslateMessage (&msg);
      DispatchMessage  (&msg);
  }
    return !fAbort;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : PrintDlgProc ()              *
 *                      *
 *  PURPOSE    : Dialog function for the print cancel dialog box.      *
 *                      *
 *  RETURNS    : TRUE  - OK to abort/ not OK to abort          *
 *     FALSE - otherwise.              *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL PrintDlgProc(HWND hwnd, WORD msg, WORD wParam, LONG lParam)
{
    switch (msg){
  case WM_INITDIALOG:
      /* Set up information in dialog box */
      SetDlgItemText (hwnd, IDD_PRINTDEVICE, (LPSTR)szDevice);
      SetDlgItemText (hwnd, IDD_PRINTPORT, (LPSTR)szPort);
      SetDlgItemText (hwnd, IDD_PRINTTITLE, (LPSTR)szTitle);
      break;

  case WM_COMMAND:
      /* abort printing if the only button gets hit */
      fAbort = TRUE;
      break;

  default:
      return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : PrintFile ()                *
 *                      *
 *  PURPOSE    : Prints the contents of the edit control.        *
 *                      *
 ****************************************************************************

VOID FAR PASCAL PrintFile(HWND hwnd)
{
    HDC     hdc;
    int     yExtPage;
    char    sz[32];
    WORD    cch;
    WORD    ich;
    PSTR    pch;
    WORD    iLine;
    WORD    nLinesEc;
    WORD    i;
    HANDLE  hT;
    FARPROC lpfnAbort;
    FARPROC lpfnPDlg;
    HWND    hwndPDlg;
    WORD    dy;
    int     yExtSoFar;
    WORD    fError = TRUE;
    HWND    hwndEdit;

    hwndEdit = (HWND)GetWindowWord(hwnd,GWW_HWNDEDIT);

    /* Create the job title by loading the title string from STRINGTABLE */
    cch = LoadString (hInst, IDS_PRINTJOB, sz, sizeof(sz));
    szTitle = sz + cch;
    cch += GetWindowText (hwnd, sz + cch, 32 - cch);
    sz[31] = 0;

    /* Make instances of the Abort proc. and the Print dialog function */
    lpfnAbort = MakeProcInstance (AbortProc, hInst);
    if (!lpfnAbort)
  goto getout;
    lpfnPDlg = MakeProcInstance (PrintDlgProc, hInst);
    if (!lpfnPDlg)
  goto getout4;

    /* Initialize the printer */
    hdc = GetPrinterDC();
    if (!hdc)
  goto getout5;

    /* Disable the main application window and create the Cancel dialog */
    EnableWindow (hwndFrame, FALSE);
    hwndPDlg = CreateDialog (hInst, IDD_PRINT, hwnd, lpfnPDlg);
    if (!hwndPDlg)
  goto getout3;
    ShowWindow (hwndPDlg, SW_SHOW);
    UpdateWindow (hwndPDlg);

    /* Allow the app. to inform GDI of the escape function to call */
    if (Escape (hdc, SETABORTPROC, 0, (LPSTR)lpfnAbort, NULL) < 0)
  goto getout1;

    /* Initialize the document */
    if (Escape (hdc, STARTDOC, cch, (LPSTR)sz, NULL) < 0)
  goto getout1;

    /* Get the height of one line and the height of a page */
    dy = HIWORD (GetTextExtent (hdc, "CC", 2));
    yExtPage = GetDeviceCaps (hdc, VERTRES);

    /* Get the lines in document and and a handle to the text buffer */
    iLine     = 0;
    yExtSoFar = 0;
    nLinesEc  = (WORD)SendMessage (hwndEdit, EM_GETLINECOUNT, 0, 0L);
    hT        = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);

    /* While more lines print out the text */
    while (iLine < nLinesEc){
  if (yExtSoFar + dy > yExtPage){
      /* Reached the end of a page. Tell the device driver to eject a
       * page
       */
      if (Escape (hdc, NEWFRAME, 0, NULL, NULL) < 0 || fAbort)
    goto getout2;
      yExtSoFar = 0;
  }

  /* Get the length and position of the line in the buffer
   * and lock from that offset into the buffer */
  ich = (WORD)SendMessage (hwndEdit, EM_LINEINDEX, iLine, 0L);
  cch = (WORD)SendMessage (hwndEdit, EM_LINELENGTH, ich, 0L);
  pch = LocalLock(hT) + ich;

  /* Print the line and unlock the text handle */
  TextOut (hdc, 0, yExtSoFar, (LPSTR)pch, cch);
  LocalUnlock (hT);

  /* Test and see if the Abort flag has been set. If yes, exit. */
  if (fAbort)
      goto getout2;

  /* Move down the page */
  yExtSoFar += dy;
  iLine++;
    }

    /* Eject the last page. */
    if (Escape (hdc, NEWFRAME, 0, NULL, NULL) < 0)
  goto getout2;

    /* Complete the document. */
    if (Escape (hdc, ENDDOC, 0, NULL, NULL) < 0){
getout2:
  /* Ran into a problem before NEWFRAME? Abort the document */
  Escape( hdc, ABORTDOC, 0, NULL, NULL);
    }
    else
  fError=FALSE;

getout3:
    /* Close the cancel dialog and re-enable main app. window */
    EnableWindow (hwndFrame, TRUE);
    DestroyWindow (hwndPDlg);

getout1:
    DeleteDC(hdc);

getout5:
    /* Get rid of dialog procedure instances */
    FreeProcInstance (lpfnPDlg);

getout4:
    FreeProcInstance (lpfnAbort);

getout:

    /* Error? make sure the user knows... */
    if (fError)
  MPError (hwnd, MB_OK | MB_ICONEXCLAMATION, IDS_PRINTERROR, (LPSTR)szTitle);

    return;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : GetInitializationData()            *
 *                      *
 *  PURPOSE    : Gets DC initialization data from a printer driver      *
 *     supporting ExtDeviceMode(). Called in response to the      *
 *     File/Printer setup menu selection.          *
 *                      *
 *     This function allows the user to change the printer      *
 *     settings FOR MULTIPAD ONLY.  This allows Multipad to print *
 *     in a variety of settings without messing up any other      *
 *     applications. In a more sophisticated application, this    *
 *     setup could even be saved on a document-by-document basis. *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL GetInitializationData( hwnd )
HWND hwnd ;
{
    LPSTR     lpOld;
    LPSTR     lpNew;
    FARPROC   lpfn;
    HANDLE    hT,hDrv;
    char      sz[32];
    WORD      cb;
    int       flag;

    /* Pop up dialog for user and retain data in app buffer */
    flag = DM_PROMPT | DM_COPY;

    /* Load the device driver and find the ExtDeviceMode() function */
    wsprintf (sz, "%s.drv", (LPSTR)szDriver);
    if ((hDrv = LoadLibrary (sz)) < 32)
  return FALSE;
    if (!(lpfn = GetProcAddress (hDrv, szExtDeviceMode)))
  return FALSE;

    if (hInitData){
  /* We have some old data... we want to modify the previously specified
   * setup rather than starting with the default setup.
   */
  lpOld = (LPSTR)LocalLock(hInitData);
  flag |= DM_MODIFY;
    }
    else
  lpOld = NULL;

    /* Get the number of bytes needed for the init data */
    cb = (*lpfn) (hwnd,
      hDrv,
      NULL,
      (LPSTR)szDevice,
      (LPSTR)szPort,
      (LPDEVMODE)NULL,
      (LPSTR)NULL,
      0);

    /* Grab some memory for the new data and lock it. */
    hT    = LocalAlloc (LHND,cb);
    lpNew = (LPSTR)LocalLock (hT);

    /* Post the device mode dialog. 0 flag iff user hits OK button */
    if ((*lpfn) (hwnd,
     hDrv,
     (LPDEVMODE)lpNew,
     (LPSTR)szDevice,
     (LPSTR)szPort,
     (LPDEVMODE)lpOld,
     (LPSTR)NULL,
     flag)==IDOK)
  flag = 0;

    /* Unlock the input structures */
    LocalUnlock (hT);
    if (hInitData)
  LocalUnlock (hInitData);

    /* If the user hit OK and everything worked, free the original init.
     * data and retain the new one.  Otherwise, toss the new buffer.
     */
    if (flag)
  LocalFree (hT);
    else{
  if (hInitData)
      LocalFree (hInitData);
  hInitData = hT;
    }

    FreeLibrary(hDrv);
    return (!flag);
}


MULTIPAD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MULTIPAD\MULTIPAD.C

/***************************************************************************
 *                     *
 *  PROGRAM  : MultiPad.c               *
 *                     *
 *  PURPOSE  : To give a multi-Notepad demonstration of the new MDI     *
 *      API in Windows 3.0             *
 *                     *
 *  FUNCTIONS  : WinMain()        - Calls the initialization function  *
 *          and processes message loop     *
 *                     *
 *      MPFrameWndProc()    - Window function for the "frame"    *
 *          window, which controls the menu    *
 *          and contains the MDI document     *
 *          windows as child windows.     *
 *                     *
 *      MPMDIChildWndProc() - Window function for the individual *
 *          document windows       *
 *                     *
 *      InitializeMenu()    - Handles enabling/greying of menu   *
 *          items according to the app's state.*
 *                     *
 *      CloseAllChildren    - Destroys all MDI child windows.    *
 *                     *
 *      CommandHandler()    - Processes the "frame" window's     *
 *          WM_COMMAND messages.       *
 *                     *
 *      AboutDlgProc()      - Dialog function for the ubiquitous *
 *          About.. dialog.        *
 *                     *
 *      SetWrap()        - Alters word wrapping in the edit   *
 *          control.         *
 *                     *
 *      MPError()        - Flashes an error messagebox.     *
 *                     *
 *      QueryCloseChild     - Prompts for saving current MDI     *
 *          child window.         *
 *                     *
 *      QueryCloseAllChildren() - Asks whether it is OK to close *
 *              down app.         *
 *                     *
 ***************************************************************************/

#include "multipad.h"

/* global variables used in this module or among more than one module */
HANDLE hInst;          /* Program instance handle         */
HANDLE hAccel;          /* Main accelerator resource       */
HWND hwndFrame     = NULL;    /* Handle to main window         */
HWND hwndMDIClient   = NULL;    /* Handle to MDI client         */
HWND hwndActive    = NULL;    /* Handle to currently activated child   */
HWND hwndActiveEdit   = NULL;    /* Handle to edit control         */
LONG styleDefault    = WS_MAXIMIZE; /* Default style bits for child windows
            /* The first window is created maximized */
            /* to resemble Notepad.  Later children  */
            /* are normal windows.         */
LPSTR lpMenu       = IDMULTIPAD;  /* Contains the resource id of the       */
            /* current frame menu         */


/* Forward declarations of helper functions in this module */
VOID NEAR PASCAL InitializeMenu (HANDLE);
VOID NEAR PASCAL CommandHandler (HWND,WORD);
VOID NEAR PASCAL SetWrap (HWND,BOOL);
BOOL NEAR PASCAL QueryCloseAllChildren ( VOID );
int  NEAR PASCAL QueryCloseChild (HWND);

/****************************************************************************
 *                      *
 *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)          *
 *                      *
 *  PURPOSE    : Creates the "frame" window, does some initialization and   *
 *     enters the message loop.            *
 *                      *
 ****************************************************************************
int NEAR PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR  lpszCmdLine;
int    nCmdShow;
{
    MSG msg;

    hInst = hInstance;

    /* If this is the first instance of the app. register window classes */
    if (!hPrevInstance){
  if (!InitializeApplication ())
      return 0;
    }

    /* Create the frame and do other initialization */
    if (!InitializeInstance (lpszCmdLine, nCmdShow))
  return 0;

    /* Enter main message loop */
    while (GetMessage (&msg, NULL, 0, 0)){
  /* If a keyboard message is for the MDI , let the MDI client
   * take care of it.  Otherwise, check to see if it's a normal
   * accelerator key (like F3 = find next).  Otherwise, just handle
   * the message as usual.
   */
  if ( !TranslateMDISysAccel (hwndMDIClient, &msg) &&
       !TranslateAccelerator (hwndFrame, hAccel, &msg)){
      TranslateMessage (&msg);
      DispatchMessage (&msg);
  }
    }
    return 0;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : MPFrameWndProc (hwnd, msg, wParam, lParam )        *
 *                      *
 *  PURPOSE    : The window function for the "frame" window, which controls *
 *     the menu and encompasses all the MDI child windows. Does   *
 *     the major part of the message processing. Specifically, in *
 *     response to:                *
 *                      *
 *         WM_CREATE    : Creates and displays the "frame". *
 *                      *
 *         WM_INITMENU  : Sets up the state of the menu.    *
 *                      *
 *         WM_WININICHANGE &  : If default printer characteristics*
 *         WM_DEVMODECHANGE    have been changed, reinitialises  *
 *            printer DC.          *
 *                      *
 *         WM_COMMAND   : Passes control to a command-      *
 *            handling function.        *
 *                      *
 *         WM_CLOSE    : Quits the app. if all the child   *
 *            windows agree.        *
 *                      *
 *         WM_QUERYENDSESSION : Checks that all child windows     *
 *            agree to quit.        *
 *                      *
 *         WM_DESTROY   : Destroys frame window and quits   *
 *            app.            *
 *                      *
 ****************************************************************************
LONG FAR PASCAL MPFrameWndProc ( hwnd, msg, wParam, lParam )

register HWND   hwnd;
WORD     msg;
register WORD   wParam;
LONG     lParam;

{
    switch (msg){
  case WM_CREATE:{

      CLIENTCREATESTRUCT ccs;
      HDC hdc;

      /* Find window menu where children will be listed */
      ccs.hWindowMenu = GetSubMenu (GetMenu(hwnd),WINDOWMENU);
      ccs.idFirstChild = IDM_WINDOWCHILD;

      /* Create the MDI client filling the client area */
      hwndMDIClient = CreateWindow ("mdiclient",
            NULL,
            WS_CHILD | WS_CLIPCHILDREN |
            WS_VSCROLL | WS_HSCROLL,
            0,
            0,
            0,
            0,
            hwnd,
            0xCAC,
            hInst,
            (LPSTR)&ccs);


      ShowWindow (hwndMDIClient,SW_SHOW);

      /* Check if printer can be initialized */
      if (hdc = GetPrinterDC ()){
    DeleteDC (hdc);
      }

      break;
  }

  case WM_INITMENU:
      /* Set up the menu state */
      InitializeMenu ((HMENU)wParam);
      break;

  case WM_WININICHANGE:
  case WM_DEVMODECHANGE:{

      /*  If control panel changes default printer characteristics,
       *  reinitialize our printer information...
       */
      HDC hdc;

      if (hdc = GetPrinterDC ()){
    DeleteDC (hdc);
      }
      break;
  }


  case WM_COMMAND:
      /* Direct all menu selection or accelerator commands to another
       * function
       */
      CommandHandler (hwnd,wParam);
      break;

  case WM_CLOSE:
      /* don't close if any children cancel the operation */
      if (!QueryCloseAllChildren ())
    break;
      DestroyWindow (hwnd);
      break;

  case WM_QUERYENDSESSION:
      /*  Before session ends, check that all files are saved */
      return QueryCloseAllChildren ();

  case WM_DESTROY:
      PostQuitMessage (0);
      break;

  default:
      /*  use DefFrameProc() instead of DefWindowProc() since there
       *  are things that have to be handled differently because of MDI
       */
      return DefFrameProc (hwnd,hwndMDIClient,msg,wParam,lParam);
    }
    return 0;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : MPMDIWndProc ( hwnd, msg, wParam, lParam )        *
 *                      *
 *  PURPOSE    : The window function for the individual document windows,   *
 *     each of which has a "note". Each of these windows contain  *
 *     one multi-line edit control filling their client area.     *
 *     In response to the following:            *
 *                      *
 *         WM_CREATE    : Creates & diplays an edit control *
 *            and does some initialization.     *
 *                      *
 *         WM_MDIACTIVATE  : Activates/deactivates the child.  *
 *                      *
 *         WM_SETFOCUS  : Sets focus on the edit control.   *
 *                      *
 *         WM_SIZE    : Resizes the edit control.      *
 *                      *
 *         WM_COMMAND   : Processes some of the edit      *
 *            commands, saves files and alters  *
 *            the edit wrap state.        *
 *                      *
 *         WM_CLOSE    : Closes child if it is ok to do so.*
 *                      *
 *         WM_QUERYENDSESSION : Same as above.        *
 *                      *
 ****************************************************************************

LONG FAR PASCAL MPMDIChildWndProc ( hwnd, msg, wParam, lParam )

register HWND  hwnd;
WORD    msg;
register WORD  wParam;
LONG    lParam;

{
    HWND hwndEdit;

    switch (msg){
  case WM_CREATE:
      /* Create an edit control */
      hwndEdit = CreateWindow ("edit",
             NULL,
             WS_CHILD|WS_HSCROLL|WS_MAXIMIZE|WS_VISIBLE|WS_VSCROLL|ES_AUTOHSC
             0,
             0,
             0,
             0,
             hwnd,
             ID_EDIT,
             hInst,
             NULL);

      /* Remember the window handle and initialize some window attributes */
      SetWindowWord (hwnd, GWW_HWNDEDIT, (WORD)hwndEdit);
      SetWindowWord (hwnd, GWW_CHANGED, FALSE);
      SetWindowWord (hwnd, GWW_WORDWRAP, FALSE);
      SetWindowWord (hwnd, GWW_UNTITLED, TRUE);
      SetFocus (hwndEdit);
      break;

  case WM_MDIACTIVATE:
      /* If we're activating this child, remember it */
      if (wParam){
    hwndActive     = hwnd;
    hwndActiveEdit = (HWND)GetWindowWord (hwnd, GWW_HWNDEDIT);
      }
      else{
    hwndActive     = NULL;
    hwndActiveEdit = NULL;
      }
      break;

  case WM_QUERYENDSESSION:
      /* Prompt to save the child */
      return !QueryCloseChild (hwnd);

  case WM_CLOSE:
      /* If its OK to close the child, do so, else ignore */
      if (QueryCloseChild (hwnd))
    goto CallDCP;
      else
    break;

  case WM_SIZE:{
      RECT rc;

      /* On creation or resize, size the edit control. */
      hwndEdit = GetWindowWord (hwnd, GWW_HWNDEDIT);
      GetClientRect (hwnd, &rc);
      MoveWindow (hwndEdit,
      rc.left,
      rc.top,
      rc.right-rc.left,
      rc.bottom-rc.top,
      TRUE);
      goto CallDCP;
  }

  case WM_SETFOCUS:
      SetFocus (GetWindowWord (hwnd, GWW_HWNDEDIT));
      break;

  case WM_COMMAND:
      switch (wParam){
    case ID_EDIT:
        switch (HIWORD(lParam)){
      case EN_CHANGE:

          /* If the contents of the edit control have changed,
             set the changed flag
           */
          SetWindowWord (hwnd, GWW_CHANGED, TRUE);
          break;

      case EN_ERRSPACE:
          /* If the control is out of space, honk */
          MessageBeep (0);
          break;

      default:
          goto CallDCP;
        }
        break;

    case IDM_FILESAVE:
        /* If empty file, ignore save */
        if ((GetWindowWord(hwnd, GWW_UNTITLED)) && (!ChangeFile(hwnd)))
      break;

        /* Save the contents of the edit control and reset the
         * changed flag
         */
        SaveFile (hwnd);
        SetWindowWord (hwnd, GWW_CHANGED, FALSE);
        break;

    case IDM_EDITWRAP: {
        int fWrap = GetWindowWord (hwnd, GWW_WORDWRAP);

        /* Set the wrap state, or report it */
        if (LOWORD (lParam)){
      fWrap = !fWrap;
      SetWrap (hwnd, fWrap);
        }

        /* return wrap state */
        return fWrap;
    }

    default:
        goto CallDCP;
      }
      break;

  default:
CallDCP:
      /* Again, since the MDI default behaviour is a little different,
       * call DefMDIChildProc instead of DefWindowProc()
       */
      return DefMDIChildProc (hwnd, msg, wParam, lParam);
    }
    return FALSE;
}


/****************************************************************************
 *                      *
 *  FUNCTION   : AboutDlgProc ( hwnd, msg, wParam, lParam )        *
 *                      *
 *  PURPOSE    : Dialog function for the About MultiPad... dialog.      *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL AboutDlgProc ( hwnd, msg, wParam, lParam )
HWND        hwnd;
register WORD msg;
register WORD wParam;
LONG        lParam;
{
    switch (msg){
  case WM_INITDIALOG:
      /* nothing to initialize */
      break;

  case WM_COMMAND:
      switch (wParam){
    case IDOK:
    case IDCANCEL:
        EndDialog(hwnd, 0);
        break;

    default:
        return FALSE;
      }
      break;

  default:
      return FALSE;
    }

    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : Initializemenu ( hMenu )            *
 *                      *
 *  PURPOSE    : Sets up greying, enabling and checking of main menu items  *
 *     based on the app's state.                                  *
 *                      *
 ****************************************************************************
VOID NEAR PASCAL InitializeMenu ( hmenu )
register HANDLE hmenu;
{
    register WORD status;
    int     i;
    int     j;
    long    l;

    /* Is there any active child to talk to? */
    if (hwndActiveEdit){
  /* If edit control can respond to an undo request, enable the
   * undo selection.
   */
  if (SendMessage (hwndActiveEdit, EM_CANUNDO, 0, 0L))
      status = MF_ENABLED;
  else
      status = MF_GRAYED;
  EnableMenuItem (hmenu, IDM_EDITUNDO, status);

  /* If edit control is non-empty, allow cut/copy/clear */
  l      = SendMessage (hwndActiveEdit, EM_GETSEL, 0, 0L);
  status = (HIWORD(l) == LOWORD(l)) ? MF_GRAYED : MF_ENABLED;
  EnableMenuItem (hmenu, IDM_EDITCUT, status);
  EnableMenuItem (hmenu, IDM_EDITCOPY, status);
  EnableMenuItem (hmenu, IDM_EDITCLEAR, status);

  status=MF_GRAYED;
  /* If the clipboard contains some CF_TEXT data, allow paste */
  if (OpenClipboard (hwndFrame)){
      int wFmt = 0;

      while (wFmt = EnumClipboardFormats (wFmt))
    if (wFmt == CF_TEXT){
        status = MF_ENABLED;
        break;
    }

      CloseClipboard ();
  }
  EnableMenuItem (hmenu, IDM_EDITPASTE, status);

  /* Set the word wrap state for the window */
  if ((WORD) SendMessage (hwndActive, WM_COMMAND, IDM_EDITWRAP, 0L))
      status = MF_CHECKED;
  else
      status = MF_UNCHECKED;
  CheckMenuItem (hmenu, IDM_EDITWRAP, status);

  /* Enable search menu items only if there is a search string */
  if (*szSearch)
      status = MF_ENABLED;
  else
      status = MF_GRAYED;
  EnableMenuItem (hmenu, IDM_SEARCHNEXT, status);
  EnableMenuItem (hmenu, IDM_SEARCHPREV, status);

  /* Enable File/Print only if a printer is available */
  status = iPrinter ? MF_ENABLED : MF_GRAYED;
  EnableMenuItem (hmenu, IDM_FILEPRINT, status);

  /* select all and wrap toggle always enabled */
  status = MF_ENABLED;
  EnableMenuItem(hmenu, IDM_EDITSELECT, status);
  EnableMenuItem(hmenu, IDM_EDITWRAP, status);
  EnableMenuItem(hmenu, IDM_SEARCHFIND, status);
    }
    else {
  /* There are no active child windows */
  status = MF_GRAYED;

  /* No active window, so disable everything */
  for (i = IDM_EDITFIRST; i <= IDM_EDITLAST; i++)
      EnableMenuItem (hmenu, i, status);

  CheckMenuItem (hmenu, IDM_EDITWRAP, MF_UNCHECKED);

  for (i = IDM_SEARCHFIRST; i <= IDM_SEARCHLAST; i++)
      EnableMenuItem (hmenu, i, status);

  EnableMenuItem (hmenu, IDM_FILEPRINT, status);

    }

    /* The following menu items are enabled if there is an active window */
    EnableMenuItem (hmenu, IDM_FILESAVE, status);
    EnableMenuItem (hmenu, IDM_FILESAVEAS, status);
    EnableMenuItem (hmenu, IDM_WINDOWTILE, status);
    EnableMenuItem (hmenu, IDM_WINDOWCASCADE, status);
    EnableMenuItem (hmenu, IDM_WINDOWICONS, status);
    EnableMenuItem (hmenu, IDM_WINDOWCLOSEALL, status);

    /* Allow printer setup only if printer driver supports device initializat
    if (iPrinter < 2)
  status = MF_GRAYED;
    EnableMenuItem ( hmenu, IDM_FILESETUP, status);

}

/****************************************************************************
 *                      *
 *  FUNCTION   : CloseAllChildren ()              *
 *                      *
 *  PURPOSE    : Destroys all MDI child windows.          *
 *                      *
 ****************************************************************************
VOID NEAR PASCAL CloseAllChildren ()
{
    register HWND hwndT;

    /* hide the MDI client window to avoid multiple repaints */
    ShowWindow(hwndMDIClient,SW_HIDE);

    /* As long as the MDI client has a child, destroy it */
    while ( hwndT = GetWindow (hwndMDIClient, GW_CHILD)){

  /* Skip the icon title windows */
  while (hwndT && GetWindow (hwndT, GW_OWNER))
      hwndT = GetWindow (hwndT, GW_HWNDNEXT);

  if (!hwndT)
      break;

  SendMessage (hwndMDIClient, WM_MDIDESTROY, (WORD)hwndT, 0L);
    }
}

/****************************************************************************
 *                      *
 *  FUNCTION   : CommandHandler ()              *
 *                      *
 *  PURPOSE    : Processes all "frame" WM_COMMAND messages.        *
 *                      *
 ****************************************************************************
VOID NEAR PASCAL CommandHandler ( hwnd, wParam )
register HWND hwnd;
register WORD wParam;

{
    switch (wParam){
  case IDM_FILENEW:
      /* Add a new, empty MDI child */
      AddFile (NULL);
      break;

  case IDM_FILEOPEN:
      ReadFile (hwnd);
      break;

  case IDM_FILESAVE:
      /* Save the active child MDI */
      SendMessage (hwndActive, WM_COMMAND, IDM_FILESAVE, 0L);
      break;

  case IDM_FILESAVEAS:
      /* Save active child MDI under another name */
      if (ChangeFile (hwndActive))
    SendMessage (hwndActive, WM_COMMAND, IDM_FILESAVE, 0L);
      break;

  case IDM_FILEPRINT:
      /* Print the active child MDI */
      PrintFile (hwndActive);
      break;

  case IDM_FILESETUP:
      /* Set up the printer environment for this app */
      GetInitializationData (hwnd);
      break;

  case IDM_FILEMENU:{

        /* lengthen / shorten the size of the MDI menu */
        HMENU hMenu;
        HMENU hWindowMenu;
        int i;

        if (lpMenu == IDMULTIPAD){
      lpMenu = IDMULTIPAD2;
      i   = SHORTMENU;
        }
        else{
      lpMenu = IDMULTIPAD;
      i   = WINDOWMENU;
        }

        hMenu = LoadMenu (hInst, lpMenu);
        hWindowMenu = GetSubMenu (hMenu, i);

        /* Set the new menu */
        hMenu = (HMENU)SendMessage (hwndMDIClient,
            WM_MDISETMENU,
            0,
            MAKELONG(hMenu,hWindowMenu));

        DestroyMenu (hMenu);
        DrawMenuBar (hwndFrame);
        break;
  }

  case IDM_FILEEXIT:
      /* Close Multipad */
      SendMessage (hwnd, WM_CLOSE, 0, 0L);
      break;

  case IDM_HELPABOUT:{
      /* Bring up the ubiquitous Ego box */
      FARPROC lpfn;

      lpfn = MakeProcInstance(AboutDlgProc, hInst);
      DialogBox (hInst, IDD_ABOUT, hwnd, lpfn);
      FreeProcInstance (lpfn);
      break;
  }

  /* The following are edit commands. Pass these off to the active
   * child's edit control window.
   */
  case IDM_EDITCOPY:
      SendMessage (hwndActiveEdit, WM_COPY, 0, 0L);
      break;

  case IDM_EDITPASTE:
      SendMessage (hwndActiveEdit, WM_PASTE, 0, 0L);
      break;

  case IDM_EDITCUT:
      SendMessage (hwndActiveEdit, WM_CUT, 0, 0L);
      break;

  case IDM_EDITCLEAR:
      SendMessage (hwndActiveEdit, EM_REPLACESEL, 0,( LONG)(LPSTR)"");
      break;

  case IDM_EDITSELECT:
      SendMessage (hwndActiveEdit, EM_SETSEL, 0, MAKELONG(0, 0xe000));
      break;

  case IDM_EDITUNDO:
      SendMessage (hwndActiveEdit, EM_UNDO, 0, 0L);
      break;

  case IDM_EDITWRAP:
      SendMessage (hwndActive, WM_COMMAND, IDM_EDITWRAP, 1L);
      break;

  case IDM_SEARCHFIND:
      /* Put up the find dialog box */
      Find ();
      break;

  case IDM_SEARCHNEXT:
      /* Find next occurence */
      FindNext ();
      break;

  case IDM_SEARCHPREV:
      /* Find previous occurence */
      FindPrev ();
      break;

  /* The following are window commands - these are handled by the
   * MDI Client.
   */
  case IDM_WINDOWTILE:
      /* Tile MDI windows */
      SendMessage (hwndMDIClient, WM_MDITILE, 0, 0L);
      break;

  case IDM_WINDOWCASCADE:
      /* Cascade MDI windows */
      SendMessage (hwndMDIClient, WM_MDICASCADE, 0, 0L);
      break;

  case IDM_WINDOWICONS:
      /* Auto - arrange MDI icons */
      SendMessage (hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
      break;

  case IDM_WINDOWCLOSEALL:
      /* Abort operation if something is not saved */
      if (!QueryCloseAllChildren())
    break;

      CloseAllChildren();

      /* Show the window since CloseAllChilren() hides the window
       * for fewer repaints.
       */
      ShowWindow( hwndMDIClient, SW_SHOW);

      break;

  default:
     /*
      * This is essential, since there are frame WM_COMMANDS generated
      * by the MDI system for activating child windows via the
      * window menu.
      */
      DefFrameProc(hwnd, hwndMDIClient, WM_COMMAND, wParam, 0L);
    }
}
/****************************************************************************
 *                      *
 *  FUNCTION   : SetWrap ()                *
 *                      *
 *  PURPOSE    : Changes the word wrapping in an edit control. Since this   *
 *     cannot be done by direct means, the function creates a new *
 *     edit control, moves data from the old control to the new   *
 *     control and destroys the original control. Note that the   *
 *     function assumes that the child being modified is currently*
 *     active.                *      *
 *                      *
 ****************************************************************************

VOID NEAR PASCAL SetWrap(hwnd, fWrap)
HWND hwnd;
BOOL fWrap;

{
    LONG    dws;
    HANDLE  hT;
    HANDLE  hTT;
    HWND    hwndOld;
    HWND    hwndNew;
    RECT    rc;

    /* Change word wrap mode */
    SetWindowWord (hwnd, GWW_WORDWRAP, fWrap);

    /* Create the appropriate window style, adding a horizontal scroll
     * facility if wrapping is not present.
     */
    dws = WS_CHILD | WS_VSCROLL | ES_AUTOVSCROLL | ES_MULTILINE;
    if (!fWrap)
  dws |= WS_HSCROLL | ES_AUTOHSCROLL;

    /* Create a new child window */
    hwndNew = CreateWindow ( "edit",
           NULL,
           dws,
           0,
           SW_SHOW,
           0,
           0,
           hwnd,
           ID_EDIT,
           hInst,
           NULL);

    /* Get handle to current edit control */
    hwndOld = GetWindowWord (hwnd, GWW_HWNDEDIT);

    /* Get the data handle of the old control */
    hT = (HANDLE)SendMessage (hwndOld, EM_GETHANDLE, 0, 0L);

    /* Create a dummy data handle and make it the handle to
     * the old edit control( hT still references the text of
     * old control).
     */
    hTT = LocalAlloc (LHND, 0);
    SendMessage (hwndOld, EM_SETHANDLE, hTT, 0L);

    /* Make the new window the window of interest and destroy the
     * old control.
     */
    SetWindowWord (hwnd, GWW_HWNDEDIT, hwndNew);
    hwndActiveEdit = hwndNew;
    DestroyWindow (hwndOld);

    /* Cause the window to be properly sized */
    SendMessage (hwnd, WM_SIZE, 0, 0L);

    /* Free the new window's old data handle and set it to
     * hT (text of old edit control)
     */
    LocalFree ((HANDLE)SendMessage (hwndNew, EM_GETHANDLE, 0, 0L));
    SendMessage (hwndNew, EM_SETHANDLE, hT, 0L);

    ShowWindow (hwndNew, SW_SHOW);

    /* Set focus to the new edit control */
    SetFocus (hwndNew);

}


/****************************************************************************
 *                      *
 *  FUNCTION   : MPError ( hwnd, flags, id, ...)          *
 *                      *
 *  PURPOSE    : Flashes a Message Box to the user. The format string is    *
 *     taken from the STRINGTABLE.            *
 *                      *
 *  RETURNS    : Returns value returned by MessageBox() to the caller.      *
 *                      *
 ****************************************************************************
short FAR CDECL MPError(hwnd, bFlags, id, ...)
HWND hwnd;
WORD bFlags;
WORD id;
{
    char sz[160];
    char szFmt[128];

    LoadString (hInst, id, szFmt, sizeof (szFmt));
    wvsprintf (sz, szFmt, (LPSTR)(&id + 1));
    LoadString (hInst, IDS_APPNAME, szFmt, sizeof (szFmt));
    return MessageBox (hwndFrame, sz, szFmt, bFlags);
}


/****************************************************************************
 *                      *
 *  FUNCTION   : QueryCloseAllChildren()            *
 *                      *
 *  PURPOSE    : Asks the child windows if it is ok to close up app. Nothing*
 *     is destroyed at this point. The z-order is not changed.    *
 *                      *
 *  RETURNS    : TRUE - If all children agree to the query.        *
 *     FALSE- If any one of them disagrees.          *
 *                      *
 ****************************************************************************

BOOL NEAR PASCAL QueryCloseAllChildren()
{
    register HWND hwndT;

    for ( hwndT = GetWindow (hwndMDIClient, GW_CHILD);
    hwndT;
    hwndT = GetWindow (hwndT, GW_HWNDNEXT)       ){

  /* Skip if an icon title window */
  if (GetWindow (hwndT, GW_OWNER))
      continue;

  if (SendMessage (hwndT, WM_QUERYENDSESSION, 0, 0L))
      return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : QueryCloseChild (hwnd)             *
 *                      *
 *  PURPOSE    : If the child MDI is unsaved, allow the user to save, not   *
 *               save, or cancel the close operation.                       *
 *                      *
 *  RETURNS    : TRUE  - if user chooses save or not save, or if the file   *
 *                       has not changed.                                   *
 *     FALSE - otherwise.              *
 *                      *
 ****************************************************************************

BOOL NEAR PASCAL QueryCloseChild(hwnd)
register HWND hwnd;
{
    char   sz [64];
    register int i;

    /* Return OK if edit control has not changed. */
    if (!GetWindowWord (hwnd, GWW_CHANGED))
  return TRUE;

    GetWindowText (hwnd, sz, sizeof(sz));

    /* Ask user whether to save / not save / cancel */
    i = MPError (hwnd,
     MB_YESNOCANCEL|MB_ICONQUESTION,IDS_CLOSESAVE,
     (LPSTR)sz);

    switch (i){
  case IDYES:
      /* User wants file saved */
      SaveFile(hwnd);
      break;

  case IDNO:
      /* User doesn't want file saved */
      break;

  default:
      /* We couldn't do the messagebox, or not ok to close */
      return FALSE;
    }
    return TRUE;
}


MYPAL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\MYPAL\MYPAL.C

/***************************************************************************
 *                     *
 *  PROGRAM  : MyPal.c               *
 *                     *
 *  PURPOSE  : Sets up a bar representation of the current physical     *
 *      palette and displays useful information regarding     *
 *      pixel colors and palette indices.         *
 *                     *
 *  FUNCTIONS  : WinMain() - calls initialization function,       *
 *            processes message loop         *
 *                     *
 *      WndProc() - Window function for app. Processes     *
 *            window messages.           *
 *                     *
 *    ShowColor() - Displays a little box on each side of the    *
 *            caption bar displaying the pixel color at the*
 *            mouse position.           *
 ***************************************************************************/

#include <windows.h>
#include "mypal.h"

HANDLE    hPal;         /* Handle to the application's logical palette */
static WORD  nSizeX;        /* Width of the application window        */
static WORD  nSizeY;        /* Height of the application window        */
NPLOGPALETTE  pLogPal;       /* Pointer to program's logical palette        *
WORD    nXBorder;      /* Width of window border          */
WORD    nXTitle;       /* Width of title bar            */
WORD    nYTitle;       /* Height of title bar            */
BOOL    bCaptureOn;    /* Indicates if mouse capture is on        */
int    iIndex;        /* Last index selected in palette        */
char    szTitlebuf[90];/* Buffer for pixel and palette info. text     */
HDC    hDCGlobal;     /* The Screen DC             */
int    iNumColors;    /* Number of colors supported by device        */
int    iRasterCaps;   /* Raster capabilities            */
int    iPalSize;      /* Size of Physical palette          */
RECT    rClientRect;   /* Client rectangle coordinates          */
DWORD   dwPal[PALETTESIZE];   /* Stores palette entries for later lookup
int    iGlobalXOffset;
int    iGlobalYOffset;
int    iYMiddle;

long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;

/****************************************************************************
 *                      *
 *  FUNCTION   : void ShowColor(HWND hWnd, HDC hDC)          *
 *                      *
 *  PURPOSE    : Displays a little box on each side of the caption bar      *
 *     displaying the pixel color at the mouse position.      *
 *                      *
 ****************************************************************************
void ShowColor (hWnd, hDC)
HWND  hWnd;
HDC   hDC;
{
     HBRUSH  hBrush, hOldBrush;

     hBrush    = CreateSolidBrush ( PALETTEINDEX(iIndex) );
     hOldBrush = SelectObject (hDC,hBrush) ;

     GetWindowRect (hWnd, (LPRECT)&rClientRect);

     PatBlt ( hDC,
        rClientRect.left + nXTitle + nXBorder + 1,
        rClientRect.top + nXBorder,
        nXTitle,
        nYTitle,
        PATCOPY);

     PatBlt(hDC,
      rClientRect.right - ( 3 * nXTitle + nXBorder + 2),
      rClientRect.top + nXBorder,
      nXTitle,
      nYTitle,
      PATCOPY);
     SelectObject (hDC, hOldBrush);
     DeleteObject (hBrush) ;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)          *
 *                      *
 *  PURPOSE    : Creates the app. window and processes the message loop.    *
 *                      *
 ****************************************************************************
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR  lpszCmdLine;
int    nCmdShow;

{
     static char szAppName [] = "MyPal";
     HWND   hWnd;
     WNDCLASS   wndclass;
     MSG   msg ;
     short int   xScreen;
     short int   yScreen;

     if (!hPrevInstance){
   wndclass.style   = CS_HREDRAW | CS_VREDRAW;
   wndclass.lpfnWndProc  = WndProc;
   wndclass.cbClsExtra  = 0;
   wndclass.cbWndExtra  = 0;
   wndclass.hInstance  = hInstance;
   wndclass.hIcon   = LoadIcon(hInstance, szAppName);
   wndclass.hCursor  = LoadCursor (NULL, IDC_ARROW);
   wndclass.hbrBackground = GetStockObject (BLACK_BRUSH);
   wndclass.lpszMenuName  = szAppName;
   wndclass.lpszClassName = szAppName;

   if (!RegisterClass (&wndclass))
       return FALSE ;
     }

     /* Do some global initializations */
     xScreen   = GetSystemMetrics (SM_CXSCREEN);
     yScreen   = GetSystemMetrics (SM_CYSCREEN);
     nXBorder   = GetSystemMetrics (SM_CXFRAME);
     nXTitle   = GetSystemMetrics (SM_CXSIZE);
     nYTitle   = GetSystemMetrics (SM_CYSIZE);
     iIndex   = 0;
     bCaptureOn  = FALSE;

     hDCGlobal   = GetDC (NULL);
     iPalSize   = GetDeviceCaps (hDCGlobal, SIZEPALETTE);
     iRasterCaps = GetDeviceCaps (hDCGlobal, RASTERCAPS);
     iRasterCaps = (iRasterCaps & RC_PALETTE) ? TRUE : FALSE;
     ReleaseDC (NULL,hDCGlobal);

     if (iRasterCaps)
   iNumColors = GetDeviceCaps(hDCGlobal, SIZEPALETTE);
     else
   iNumColors = GetDeviceCaps( hDCGlobal, NUMCOLORS);

     nSizeX = ((xScreen - 2*nXBorder) / PALETTESIZE) * PALETTESIZE;

     /* create the app. window */
     hWnd = CreateWindow (szAppName,
        "My Physical Palette ",
        WS_OVERLAPPEDWINDOW,
        (xScreen-nSizeX) / 2 - nXBorder,
        yScreen - ( 4 * GetSystemMetrics (SM_CYCAPTION)),
        nSizeX + 2 * nXBorder,
        4 * GetSystemMetrics (SM_CYCAPTION),
        NULL,
        NULL,
        hInstance,
        NULL);
     ShowWindow (hWnd, nCmdShow);
     UpdateWindow (hWnd);

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

     return msg.wParam ;
}

/****************************************************************************
 *                        *
 *  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)            *
 *                        *
 *  PURPOSE:  Processes window messages and sets up a 256 bar representation
 *        of the current physical palette. Specifically, in response to:  *
 *                        *
 *     WM_CREATE  -Allocates for and sets up a LOGPALETTE        *
 *           structure, creates a logical palette the same    *
 *           size as the physical palette and obtains a       *
 *           handle to the logical palette.          *
 *                        *
 *     WM_DESTROY -Destroys the logical palette and shuts down app. *
 *                        *
 *     WM_PAINT   -Resizes client area to hold as many vertical     *
 *           color bars as there are physical palette entries.*
 *           Also realises the current logical palette and    *
 *           draws one color bar corresponding to each        *
 *           palette entry              *
 *                        *
 *       WM_RBUTTONDOWN -Captures the mouse and initiates the below       *
 *           process:                *
 *                        *
 *       WM_MOUSEMOVE   -Following a WM_RBUTTONDOWN, if the right mouse   *
 *           key is depressed, displays info about the        *
 *           pixel RGB value and palette index of the mouse   *
 *           coordinates.              *
 *                        *
 *       WM_RBUTTONUP   -Release mouse capture and terminates the above   *
 *           process                *
 *                        *
 *       WM_LBUTTONDOWN -Determines and displays the palette index and    *
 *           RGB value of the bar under the mouse.        *
 *                        *
 *       WM_KEYDOWN     -Allows use of the arrow keys in stepping thro'   *
 *           palette entries.              *
 *                        *
 ****************************************************************************
long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)

HWND   hWnd;
unsigned iMessage;
WORD   wParam;
LONG   lParam;

{
    HDC     hDC;
    PAINTSTRUCT   ps;
    WORD    iLoop;
    WORD    nStart;
    HMENU    hMenu;
    HBRUSH    hBrush;
    HBRUSH    hOldBrush;

    POINT    pt;
    static WORD   nIncr;
    static DWORD  dwColor;
    static DWORD  dwLastColor;
    static int    i, x;

    switch (iMessage){
   case WM_DESTROY:
        /* delete the handle to the logical palette if it has any
         * color entries and quit.
         */
        if (pLogPal->palNumEntries)
      DeleteObject (hPal);
        PostQuitMessage (0) ;
        break ;

   case WM_CREATE:
        /* Allocate enough memory for a logical palette with
         * PALETTESIZE entries and set the size and version fields
         * of the logical palette structure.
         */
        pLogPal = (NPLOGPALETTE) LocalAlloc (LMEM_FIXED,
              (sizeof (LOGPALETTE) +
              (sizeof (PALETTEENTRY) * (PALETTESIZE))));

        pLogPal->palVersion    = 0x300;
        pLogPal->palNumEntries = PALETTESIZE;

        /* fill in intensities for all palette entry colors */
        for (iLoop = 0; iLoop < PALETTESIZE; iLoop++) {
      *((WORD *) (&pLogPal->palPalEntry[iLoop].peRed)) = iLoop;
      pLogPal->palPalEntry[iLoop].peBlue  = 0;
      pLogPal->palPalEntry[iLoop].peFlags = PC_EXPLICIT;
        }

        /*  create a logical color palette according the information
         *  in the LOGPALETTE structure.
         */
        hPal = CreatePalette ((LPLOGPALETTE) pLogPal) ;
        break;

   case WM_GETMINMAXINFO:

        ((LPRGPT)lParam)->iInfo[6] = nXBorder * 2 + PALETTESIZE;
        ((LPRGPT)lParam)->iInfo[7] = nXBorder * 2 + nYTitle*3;

        return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
        break;

   case WM_PAINT:

        /* Divide client width into equal-sized parts, one per palette
         * entry, and re-calculate client width so that it will display
         * exactly as many vertical bars as there are palette entries.
         */
         GetClientRect(hWnd,(LPRECT) &rClientRect);
         nSizeX = (rClientRect.right - rClientRect.left);
         nSizeX = (nSizeX/iNumColors) * iNumColors;

         nSizeY = rClientRect.bottom - rClientRect.top;
         GetWindowRect(hWnd,(LPRECT) &rClientRect);

        /* Adjust window width so that it can display exactly
         * as many vertical bars( of equal width) as there are palette
         * colors.
         */

        SetWindowPos( hWnd,
          (HWND)NULL,
          0,
          0,
          nSizeX + 2*nXBorder,
          rClientRect.bottom - rClientRect.top,
          SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);

        hDC = BeginPaint(hWnd, &ps);

        /* Select the palette into the window device context and
         * make the Palette Manager map the logical palette to the
         * system palette (realize it).
         */
        SelectPalette (hDC, hPal, 1);
        RealizePalette (hDC);

        /* Calculate width of each color bar to be displayed */
        nIncr = nSizeX / iNumColors;

        /* Paint the individual bars separately on the app. window */
        for (nStart = iLoop = 0; iLoop < iNumColors; iLoop++){

      /* Since this app. uses a logical palette, use the
       * PALETTEINDEX macro to specify the palette entry
       * index instead of using an explicit RGB value.
       */
      hBrush       = CreateSolidBrush (PALETTEINDEX (iLoop));
      dwPal[iLoop] = GetNearestColor (hDC, PALETTEINDEX (iLoop) );
      hOldBrush    = SelectObject (hDC,hBrush) ;
      PatBlt (hDC, nStart, 0, nIncr, nSizeY, PATCOPY);
      nStart       += nIncr;
      SelectObject (hDC, hOldBrush);
      DeleteObject (hBrush) ;
        }
        wsprintf (szTitlebuf, "MyPal Colors= %d", iNumColors);
        SetWindowText (hWnd, (LPSTR)szTitlebuf);

        EndPaint(hWnd,&ps);

        break ;

   case WM_MOUSEMOVE:

        if (wParam & MK_RBUTTON) {

      /* Convert mouse position to screen coordinates */
      pt.x = LOWORD(lParam);
      pt.y = HIWORD(lParam);
      ClientToScreen(hWnd,&pt);

      /* Get RGB value (color) of pixel under mouse coordinate */
      dwColor = GetPixel(hDCGlobal, pt.x, pt.y);

      /* If color value already exists in palette lookup table,
       * obtain it's index.
       */
      for (i=0 ; i < iNumColors ; i++)
          if ( dwColor == dwPal[i] )
        break;
      iIndex = i;

      /* If previous color value was not identical to current one,
       * display color boxes on either side of title bar,
       * the R, G, B values and palette index of current color.
       */
      if (dwColor != dwLastColor) {
          wsprintf ( szTitlebuf,
         "MyPal Colors=%d  Index=%d  R=%3u G=%3u B=%3u",
         iNumColors,
         iIndex,
         (WORD)(BYTE) GetRValue (dwColor),
         (WORD)(BYTE) GetGValue (dwColor),
         (WORD)(BYTE) GetBValue (dwColor));
          SetWindowText (hWnd, (LPSTR)szTitlebuf);
          ShowColor (hWnd, hDCGlobal);
          dwLastColor = dwColor;
      }
        }
        break;

   case WM_RBUTTONDOWN:

        /* Determine number of color bar under mouse, thus the index
         * of color in palette.
         */
        x = LOWORD(lParam);
        iIndex = (x / nIncr );

        wsprintf ( szTitlebuf,
       "MyPal Colors=%d  Index=%d  PalSize=%d RasterCaps:%d",
       iNumColors,
       iIndex,
       iPalSize,
       iRasterCaps );

        SetWindowText (hWnd, (LPSTR)szTitlebuf);

        /* Set mouse capture so that subsequent WM_MOUSEMOVEs
         * (with right mouse button depressed) will allow MyPal
         * to display RGB info anywhere on the screen without losing
         * the focus.
         */
        SetCapture (hWnd);
        bCaptureOn = TRUE;
        hDCGlobal = GetDC(NULL);
        if (hPal) {
      SelectPalette (hDCGlobal, hPal, FALSE);
      RealizePalette (hDCGlobal);
        }
        break;

   case WM_RBUTTONUP:
        /* Stops displaying RGB and palette info and releases mouse
         * capture
         */
        ReleaseDC (NULL, hDCGlobal);
        bCaptureOn = FALSE;
        ReleaseCapture ();
        break;

   case WM_MOVE:
        /* If you have a wide column, this adds 1/2 so X is centered */
        iGlobalXOffset  = LOWORD (lParam);
        iGlobalYOffset  = HIWORD (lParam) + nXBorder;
        break;

   case WM_SIZE:
        iYMiddle = (HIWORD (lParam)/2);
        break;

   case WM_LBUTTONDOWN:
   case WM_KEYDOWN:

       if (iMessage == WM_LBUTTONDOWN){
     /* determine which column was hit by the mouse */
     x = LOWORD(lParam);
     iIndex = (x / nIncr );
       }
       else{
     /* Use arrow keys to step thro' the palette entries */
     switch (wParam) {
         case VK_RIGHT:
         case VK_UP:
          /* go to next (higher) palette entry */
          iIndex++;
          break;
         case VK_LEFT:
         case VK_DOWN:
          /* go to previous (lower) palette entry */
          iIndex--;
          break;
         case VK_NEXT:
          iIndex += 10;
          break;
         case VK_PRIOR:
          iIndex -= 10;
          break;
         case VK_HOME:
          /* go to first palette entry */
          iIndex = 0;
          break;
         case VK_END:
          /* go to last palette entry */
          iIndex = iNumColors-1;
          break;
         default:
          return 0L;
          break;
     }
     /* Make sure the palette index is within range else
      * set it to the limiting values and give a warning beep.
      */
     if (iIndex < 0) {
         iIndex = 0;
         MessageBeep(1);
     }
     else{
         if (iIndex > iNumColors-1) {
       iIndex = iNumColors-1;
       MessageBeep(1);
          }
     }

     pt.x = (iIndex * nIncr) +
      iGlobalXOffset   +
      ((nIncr > 1) ? (nIncr / 2) : 1);
     pt.y = iYMiddle + iGlobalYOffset;

     SetCursorPos (pt.x, pt.y);
       }

       if (TRUE == bCaptureOn) {
     MessageBeep(1);
     break;
       }

       /* Select & realize the palette or the colors > 0x7
        * will not match up.
        */
       hDC = GetDC(NULL);
       SelectPalette  (hDC, hPal, 1);
       RealizePalette (hDC) ;

       dwColor = GetNearestColor (hDC, PALETTEINDEX (iIndex));

       wsprintf ( szTitlebuf,
      "MyPal Colors=%d  Index=%d  R=%3u G=%3u B=%3u",
      iNumColors,
      iIndex,
      (WORD)(BYTE)GetRValue (dwColor),
      (WORD)(BYTE)GetGValue (dwColor),
      (WORD)(BYTE)GetBValue (dwColor)
         );

       SetWindowText (hWnd, (LPSTR)szTitlebuf);
       ShowColor (hWnd,hDC);
       ReleaseDC(NULL, hDC);
       break;

   default:
        return DefWindowProc (hWnd, iMessage, wParam, lParam) ;

    }
    return 0L ;
}


OUTPUT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\OUTPUT\OUTPUT.C

/****************************************************************************

    PROGRAM: Output.c

    PURPOSE: Output template for Windows applications

    FUNCTIONS:

  WinMain() - calls initialization function, processes message loop
  InitApplication() - initializes window data and registers window
  InitInstance() - saves instance handle and creates main window
  MainWndProc() - processes messages
  About() - processes messages for "About" dialog box

****************************************************************************/

#include "windows.h"
#include "string.h"
#include "output.h"

HANDLE hInst;

HPEN hDashPen;                                         /* "---" pen handle
HPEN hDotPen;                                          /* "..." pen handle
HBRUSH hOldBrush;                                      /* old brush handle
HBRUSH hRedBrush;                                      /* red brush handle
HBRUSH hGreenBrush;                                    /* green brush handle
HBRUSH hBlueBrush;                                     /* blue brush handle


/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
  if (!InitApplication(hInstance))
      return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "OutputMenu";
    wc.lpszClassName = "OutputWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    HWND            hWnd;

    hInst = hInstance;

    hWnd = CreateWindow(
        "OutputWClass",
        "Output Sample Application",
        WS_OVERLAPPEDWINDOW,
  0,
  0,
  GetSystemMetrics(SM_CXSCREEN),
  GetSystemMetrics(SM_CYSCREEN),
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hWnd)
        return (FALSE);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

  WM_COMMAND    - application menu (About dialog box)
  WM_CREATE     - create window and objects
  WM_PAINT      - update window, draw objects
  WM_DESTROY    - destroy window

    COMMENTS:

  Handles to the objects you will use are obtained when the WM_CREATE
  message is received, and deleted when the WM_DESTROY message is
  received.  The actual drawing is done whenever a WM_PAINT message is
  received.

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout;

    HDC hDC;                          /* display-context variable  */
    PAINTSTRUCT ps;                   /* paint structure           */
    RECT rcTextBox;                   /* rectangle around the text */
    HPEN hOldPen;                     /* old pen handle            */



    switch (message) {
  case WM_COMMAND:
      if (wParam == IDM_ABOUT) {
    lpProcAbout = MakeProcInstance(About, hInst);

    DialogBox(hInst,
        "AboutBox",
        hWnd,
        lpProcAbout);

    FreeProcInstance(lpProcAbout);
    break;
      }
      else
    return (DefWindowProc(hWnd, message, wParam, lParam));

        case WM_CREATE:

            /* Create the brush objects */

            hRedBrush =   CreateSolidBrush(RGB(255,   0,   0));
            hGreenBrush = CreateSolidBrush(RGB(  0, 255,   0));
            hBlueBrush =  CreateSolidBrush(RGB(  0,   0, 255));

            /* Create the "---" pen */

            hDashPen = CreatePen(PS_DASH,                /* style */
                1,                                       /* width */
                RGB(0, 0, 0));                           /* color */

            /* Create the "..." pen */

            hDotPen = CreatePen(2,                       /* style */
                1,                                       /* width */
                RGB(0, 0, 0));                           /* color */
            break;

        case WM_PAINT:
            {
    TEXTMETRIC textmetric;
    int nDrawX;
    int nDrawY;
    char szText[300];

    /* Set up a display context to begin painting */

                hDC = BeginPaint (hWnd, &ps);

                /* Get the size characteristics of the current font.  */
                /* This information will be used for determining the  */
                /* vertical spacing of text on the screen.            */

                GetTextMetrics (hDC, &textmetric);

                /* Initialize drawing position to 1/4 inch from the top  */
                /* and from the left of the top, left corner of the      */
                /* client area of the main windows.                      */

                nDrawX = GetDeviceCaps (hDC, LOGPIXELSX) / 4;   /* 1/4 inch *
                nDrawY = GetDeviceCaps (hDC, LOGPIXELSY) / 4;   /* 1/4 inch *

                /* Send characters to the screen.  After displaying each   */
                /* line of text, advance the vertical position for the     */
                /* next line of text.  The pixel distance between the top  */
                /* of each line of text is equal to the standard height of */
                /* the font characters (tmHeight), plus the standard       */
                /* amount of spacing (tmExternalLeading) between adjacent  */
                /* lines.                                                  */

                strcpy (szText, "These characters are being painted using ");
                TextOut (hDC, nDrawX, nDrawY, szText, strlen (szText));
                nDrawY += textmetric.tmExternalLeading + textmetric.tmHeight;

                strcpy (szText, "the TextOut() function, which is fast and ")
                TextOut (hDC, nDrawX, nDrawY, szText, strlen (szText));
                nDrawY += textmetric.tmExternalLeading + textmetric.tmHeight;

                strcpy (szText, "allows programmer control of placement and "
                TextOut (hDC, nDrawX, nDrawY, szText, strlen (szText));
                nDrawY += textmetric.tmExternalLeading + textmetric.tmHeight;

                strcpy (szText, "formatting details.  However, TextOut() ");
                TextOut (hDC, nDrawX, nDrawY, szText, strlen (szText));
                nDrawY += textmetric.tmExternalLeading + textmetric.tmHeight;

                strcpy (szText, "does not provide any automatic formatting.")
                TextOut (hDC, nDrawX, nDrawY, szText, strlen (szText));
                nDrawY += textmetric.tmExternalLeading + textmetric.tmHeight;

                /* Put text in a 5-inch by 1-inch rectangle and display it. *
                /* First define the size of the rectangle around the text   *

                nDrawY += GetDeviceCaps (hDC, LOGPIXELSY) / 4;  /* 1/4 inch *
                SetRect (
                      &rcTextBox
                    , nDrawX
                    , nDrawY
                    , nDrawX + (5 * GetDeviceCaps (hDC, LOGPIXELSX)) /* 5" */
                    , nDrawY + (1 * GetDeviceCaps (hDC, LOGPIXELSY)) /* 1" */
                );

                /* Draw the text within the bounds of the above rectangle */

                strcpy (szText, "This text is being displayed with a single "
                            "call to DrawText().  DrawText() isn't as fast "
                            "as TextOut(), and it is somewhat more "
                            "constrained, but it provides numerous optional "
                            "formatting features, such as the centering and "
                            "line breaking used in this example.");
                DrawText (
                      hDC
                    , szText
                    , strlen (szText)
                    , &rcTextBox
                    , DT_CENTER | DT_EXTERNALLEADING | DT_NOCLIP
                                                | DT_NOPREFIX | DT_WORDBREAK
                );

                /*  Paint the next object immediately below the bottom of   *
                /*  the above rectangle in which the text was drawn.        *

                nDrawY = rcTextBox.bottom;

                /* The (x,y) pixel coordinates of the objects about to be   *
                /* drawn are below, and to the right of, the current        *
                /* coordinate (nDrawX,nDrawY).                              *

                /* Draw a red rectangle.. */

                hOldBrush = SelectObject(hDC, hRedBrush);
                Rectangle (
                      hDC
                    , nDrawX
                    , nDrawY
                    , nDrawX + 50
                    , nDrawY + 30
                );

                /* Draw a green ellipse */

                SelectObject(hDC, hGreenBrush);
                Ellipse (
                      hDC
                    , nDrawX + 150
                    , nDrawY
                    , nDrawX + 150 + 50
                    , nDrawY + 30
                );

                /* Draw a blue pie shape */

                SelectObject(hDC, hBlueBrush);
                Pie (
                      hDC
                    , nDrawX + 300
                    , nDrawY
                    , nDrawX + 300 + 50
                    , nDrawY + 50
                    , nDrawX + 300 + 50
                    , nDrawY
                    , nDrawX + 300 + 50
                    , nDrawY + 50
                );

                nDrawY += 50;

                /* Restore the old brush */

                SelectObject(hDC, hOldBrush);

                /* Select a "---" pen, save the old value */

                nDrawY += GetDeviceCaps (hDC, LOGPIXELSY) / 4;  /* 1/4 inch *
                hOldPen = SelectObject(hDC, hDashPen);

                /* Move to a specified point */

                MoveTo(hDC, nDrawX, nDrawY);

                /* Draw a line */

                LineTo(hDC, nDrawX + 350, nDrawY);

                /* Select a "..." pen */

                SelectObject(hDC, hDotPen);

                /* Draw an arc connecting the line */

                Arc (
                      hDC
                    , nDrawX
                    , nDrawY - 20
                    , nDrawX + 350
                    , nDrawY + 20
                    , nDrawX
                    , nDrawY
                    , nDrawX + 350
                    , nDrawY
                );

                /* Restore the old pen */

                SelectObject(hDC, hOldPen);

                /* Tell Windows you are done painting */

                EndPaint (hWnd,  &ps);
            }
            break;

  case WM_DESTROY:
            DeleteObject(hRedBrush);
            DeleteObject(hGreenBrush);
            DeleteObject(hBlueBrush);
            DeleteObject(hDashPen);
            DeleteObject(hDotPen);
      PostQuitMessage(0);
      break;

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


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

  WM_INITDIALOG - initialize dialog box
  WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}


OWNCOMBO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\OWNCOMBO\OWNCOMBO.C

/***************************************************************************
 *                     *
 *  PROGRAM  : OwnCombo.c               *
 *                     *
 *  PURPOSE  : Illustrates the use of functions and messages for     *
 *      combo boxes and owner-draw control styles.       *
 *                     *
 *  FUNCTIONS  : WinMain                - Creates the app. window and     *
 *             enters the message loop.     *
 *                     *
 *      OwnComboInit           - Registers the main window class *
 *                     *
 *      About                  - Dialog function for the About   *
 *             dialog.         *
 *                     *
 *      OwnComboWndProc        - Window function for app. It     *
 *             handles the menu selections     *
 *             and processes the other window  *
 *             messages.         *
 *                     *
 *                DrawEntireItem         - Handles the drawing of a list   *
 *                                         list box or combo box item.     *
 *                     *
 *                HandleSelectionState   - Handles the selecting/deselect- *
 *                                         ing of a list box or combo box  *
 *                                         item.                           *
 *                     *
 *                HandleFocusState       - Handles the getting/losing of   *
 *                                         the input focus by a list box   *
 *                     *
 *      ListBoxExample         - Dialog function for the     *
 *             owner-draw list box example.    *
 *                     *
 *      ComboBoxExample        - Dialog function for the text    *
 *             combo dialog.       *
 *                     *
 *      OwnerComboBoxExample   - Dialog fubction for the drop-   *
 *             down-list combobox with     *
 *             ownerdraw.         *
 *                     *
 ***************************************************************************/
#include "windows.h"
#include "owncombo.h"

HANDLE  hInst;

/****************************************************************************
 *                      *
 *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)          *
 *                      *
 *  PURPOSE    : Creates the app. window and enters the message loop.      *
 *                      *
 ****************************************************************************
int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)

HANDLE hInstance, hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    HWND  hWnd;
    MSG   msg;

    if (!hPrevInstance)
  if (!OwnComboInit (hInstance))
      return (NULL);

    hInst = hInstance;

    /* Create the app. window */
    hWnd = CreateWindow ("owncombo",
       "Owner-draw & Combo Box Example",
       WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
       CW_USEDEFAULT,
       (HWND) NULL,
       NULL,
       hInstance,
       (LPSTR) NULL);

    if (!hWnd)
  return (NULL);

    ShowWindow (hWnd, nCmdShow);

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

    return(msg.wParam);
}


/****************************************************************************
 *                      *
 *  FUNCTION   : OwnComboInit (hInstance)            *
 *                      *
 *  PURPOSE    : Registers the main window class.          *
 *                      *
 *  RETURNS    : TRUE  - if RegisterClass () succeeds.          *
 *     FALSE - if RegisterClass () fails.          *
 *                      *
 ****************************************************************************
BOOL NEAR PASCAL OwnComboInit (hInstance)

HANDLE hInstance;
{
    HANDLE     hMemory;
    PWNDCLASS  pWndClass;
    BOOL       bSuccess;

    /* Allocate for and fill class structure. */
    hMemory = LocalAlloc (LPTR, sizeof (WNDCLASS));
    pWndClass = (PWNDCLASS) LocalLock (hMemory);

    pWndClass->style       = NULL;
    pWndClass->lpfnWndProc   = OwnComboWndProc;
    pWndClass->hInstance     = hInstance;
    pWndClass->hIcon       = LoadIcon (hInstance, "owncombo");
    pWndClass->hCursor       = LoadCursor (NULL, IDC_ARROW);
    pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
    pWndClass->lpszMenuName  = (LPSTR) "OwnComboMenu",
    pWndClass->lpszClassName = (LPSTR) "owncombo";

    bSuccess = RegisterClass (pWndClass);
    LocalUnlock (hMemory);
    LocalFree (hMemory);

    return (bSuccess);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : About (hDlg,message, wParam, lParam)          *
 *                      *
 *  PURPOSE    : Dialog function for the About... dialog.        *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL About (hDlg, message, wParam, lParam)

HWND   hDlg;
unsigned message;
WORD   wParam;
LONG   lParam;

{
    switch (message){
  case WM_INITDIALOG:
      return(TRUE);

  case WM_COMMAND:
      if (wParam == IDOK){
    EndDialog (hDlg,NULL);
    return(FALSE);
      }
      break;

  default:
      break;
    }
  return(FALSE);
}


/****************************************************************************
 *                      *
 *  FUNCTION   : OwnComboWndProc(hWnd, message, wParam, lParam)       *
 *                      *
 *  PURPOSE    : Window function for the app. It handles menu selections    *
 *     and processes window WM_ messages.          *
 *                      *
 ****************************************************************************
long FAR PASCAL OwnComboWndProc (hWnd, message, wParam, lParam)

HWND   hWnd;
unsigned message;
WORD   wParam;
LONG   lParam;

{
    FARPROC       lpProc;
    HMENU       hMenu;
    LPDRAWITEMSTRUCT dis;
    RECT       rc;

    switch (message){
  case WM_COMMAND:
      switch (wParam){
    case IDM_EXIT:
        DestroyWindow (hWnd);
        break;

    case IDM_ABOUT:
        /* Bring up the about box */
        lpProc = MakeProcInstance (About, hInst);
        DialogBox (hInst,
             "AboutBox",
             hWnd,
             lpProc);

        FreeProcInstance (lpProc);
        break;

    case IDM_LISTBOX:
        /* Bring up the list box example */
        lpProc = MakeProcInstance (ListBoxExample, hInst);
        DialogBox (hInst,
             "ListBoxDialog",
             hWnd,
             lpProc);
        FreeProcInstance (lpProc);
        break;

    case IDM_MULTILISTBOX:
        /* Bring up the multiple selection list box example */
        lpProc = MakeProcInstance (ListBoxExample, hInst);
        DialogBox (hInst,
             "MultiListBoxDialog",
             hWnd,
             lpProc);
        FreeProcInstance (lpProc);
        break;

    case IDM_COMBOBOX:
        /* Bring up the combo box example */
        lpProc = MakeProcInstance (ComboBoxExample, hInst);
        DialogBox (hInst,
             "ComboBoxDialog",
             hWnd,
             lpProc);
        FreeProcInstance (lpProc);
        break;

    case IDM_OWNERCOMBOBOX:
        /* Bring up the owner-draw dropdown list box example */
        lpProc = MakeProcInstance (OwnerComboBoxExample, hInst);
        DialogBox (hInst,
             "OwnerComboBoxDialog",
             hWnd,
             lpProc);
        FreeProcInstance (lpProc);
        break;
      }
      break;

  case WM_DESTROY:
      PostQuitMessage (0);
      break;

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

/****************************************************************************
 *                                                                          *
 *  FUNCTION   : HandleSelectionState(LPDRAWITEMSTRUCT, int)                *
 *                                                                          *
 *  PURPOSE    : Handles a change in an item selection state. If an item is *
 *               selected, a black rectangular frame is drawn around that   *
 *               item; if an item is de-selected, the frame is removed.     *
 *                                                                          *
 *  COMMENT    : The black selection frame is slightly larger than the gray *
 *               focus frame so they won't paint over each other.           *
 *                                                                          *
 ****************************************************************************
void FAR PASCAL HandleSelectionState(lpdis, inflate)
  LPDRAWITEMSTRUCT  lpdis;
  int      inflate;
{
  RECT  rc;
  HBRUSH  hbr;

  /* Resize rectangle to place selection frame outside of the focus
   * frame and the item.
   */
  CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
  InflateRect ((LPRECT)&rc, inflate, inflate);

  if (lpdis->itemState & ODS_SELECTED)
  {
    /* selecting item -- paint a black frame */
    hbr = GetStockObject(BLACK_BRUSH);
  }
  else
  {
    /* de-selecting item -- remove frame */
    hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  }
  FrameRect(lpdis->hDC, (LPRECT)&rc, hbr);
  DeleteObject (hbr);
}

/****************************************************************************
 *                                                                          *
 *  FUNCTION   : HandleFocusState(LPDRAWITEMSTRUCT, int)                    *
 *                                                                          *
 *  PURPOSE    : Handle a change in item focus state. If an item gains the  *
 *               input focus, a gray rectangular frame is drawn around that *
 *               item; if an item loses the input focus, the gray frame is  *
 *               removed.                                                   *
 *                                                                          *
 *  COMMENT    : The gray focus frame is slightly smaller than the black    *
 *               selection frame so they won't paint over each other.       *
 *                                                                          *
 ****************************************************************************
void FAR PASCAL HandleFocusState(lpdis, inflate)
  LPDRAWITEMSTRUCT  lpdis;
  int      inflate;
{
  RECT  rc;
  HBRUSH  hbr;

  /* Resize rectangle to place focus frame between the selection
   * frame and the item.
   */
  CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
  InflateRect ((LPRECT)&rc, inflate, inflate);

  if (lpdis->itemState & ODS_FOCUS)
  {
    /* gaining input focus -- paint a gray frame */
    hbr = GetStockObject(GRAY_BRUSH);
  }
  else
  {
    /* losing input focus -- remove (paint over) frame */
    hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  }
  FrameRect(lpdis->hDC, (LPRECT)&rc, hbr);
  DeleteObject (hbr);
}

/****************************************************************************
 *                                                                          *
 *  FUNCTION   : DrawEntireItem(LPDRAWITEMSTRUCT, int)                      *
 *                                                                          *
 *  PURPOSE    : Draws an item and frames it with a selection frame and/or  *
 *               a focus frame when appropriate.                            *
 *                                                                          *
 ****************************************************************************
void FAR PASCAL DrawEntireItem(lpdis, inflate)
  LPDRAWITEMSTRUCT  lpdis;
  int      inflate;
{
  RECT  rc;
  HBRUSH  hbr;

  /* Resize rectangle to leave space for frames */
  CopyRect ((LPRECT)&rc, (LPRECT)&lpdis->rcItem);
  InflateRect ((LPRECT)&rc, inflate, inflate);

  /* Create a brush using the value in the item data field (this value
   * was initialized when we added the item to the list/combo box using
   * LB_ADDSTRING/CB_ADDSTRING) and draw the color in the list/combo box.
   */
  hbr = CreateSolidBrush (lpdis->itemData);
  FillRect (lpdis->hDC, (LPRECT)&rc, hbr);
  DeleteObject (hbr);

  /* Draw or erase appropriate frames */
  HandleSelectionState(lpdis, inflate + 4);
  HandleFocusState(lpdis, inflate + 2);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : ListBoxExample (hDlg, message, wParam, lParam)       *
 *                      *
 *  PURPOSE    : Dialog function for the owner-draw list box example.      *
 *     It sets up the example dialog with the owner-draw list box,*
 *     adds the colors to the list box, and handles setting the   *
 *     selection and focus for the items.                         *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL ListBoxExample (hDlg, message, wParam, lParam)

HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;

{
    LPDRAWITEMSTRUCT  lpdis;
    LPMEASUREITEMSTRUCT lpmis;

    /* Vars for WM_DRAWITEM */
    RECT    rc;
    HBRUSH    hbr;

    switch (message){
  case WM_COMMAND:
      switch (wParam){
    case IDOK:
       EndDialog (hDlg, NULL);
       return (TRUE);
       break;

    /* Clicking any of these buttons adds the corresponding color
     * to the list box. The application-supplied data is the RGB
     * value for the color to be drawn in the listbox.
     */
    case ID_BLACK:
        SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
         LB_ADDSTRING,
         0,
         RGB (0,0,0));
        return(TRUE);
        break;
    case ID_RED:
        SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
         LB_ADDSTRING,
         0,
         RGB (255,0,0));
        return(TRUE);
        break;

    case ID_BLUE:
        SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
         LB_ADDSTRING,
         0,
         RGB (0,0,255));
        return(TRUE);
        break;

    case ID_GREEN:
        SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
         LB_ADDSTRING,
         0,
         RGB (0,255,0));
        return(TRUE);
        break;

    default:
        return(FALSE);
        break;
      }

  case WM_DRAWITEM:
      /* Get pointer to the DRAWITEMSTRUCT */
      lpdis = (LPDRAWITEMSTRUCT)lParam;

      if (lpdis->itemID == -1)
      {
    /* We have a request to draw an item in the list box, yet there
     * are no list box items. This is sent when the user TABS into
     * an empty list box or an empty list box gets the focus. We
     * have to indicate (somehow) that this owner-draw list box has
     * the focus. We do it in response to this message. Note that
     * lpdis->itemData field would be invalid in this instance so
     * we can't allow it to fall into our standard routines.
     */
    HandleFocusState(lpdis, -5);
      }
      else
      {
    switch (lpdis->itemAction)
    {
      case ODA_DRAWENTIRE:
        DrawEntireItem(lpdis, -7);
        break;

      case ODA_SELECT:
        HandleSelectionState(lpdis, -3);
        break;

      case ODA_FOCUS:
        HandleFocusState(lpdis, -5);
        break;
    }
      }

      /* Return TRUE meaning that we processed this message. */
      return(TRUE);
      break;

  case WM_MEASUREITEM:
      lpmis = (LPMEASUREITEMSTRUCT)lParam;

      /* All the items are the same height since the list box style is
       * LBS_OWNERDRAWFIXED
       */
      lpmis->itemHeight = 30;
      break;

  case WM_CLOSE:
      EndDialog(hDlg, NULL);
      return(TRUE);
      break;

  default:
      return(FALSE);
    }

    return(TRUE);
}

/****************************************************************************
 *                      *
 *  FUNCTION   : ComboBoxExample(hWnd, message, wParam, lParam)       *
 *                      *
 *  PURPOSE    : Dialog function for the text combo dialog. The push buttons*
 *     send various messages to the combo box and the edit control*
 *     when selected. They allow the user to vary data sent with  *
 *     each message.                *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL ComboBoxExample(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{

    HWND hWndCombo;         /* Handle to the combo box control */
             /* in the dialog box window        */
    HWND hWndCheckBox;         /* Handle to the Auto Check Box    */
    char strSingleEditLine[255];     /* Single line edit control input  */
    int  wIndex, wCount;

    /* Get handles to the Combo box and the Check box */
    hWndCombo    = GetDlgItem(hDlg, ID_COMBOBOX);
    hWndCheckBox  = GetDlgItem(hDlg, ID_STEPSBOX);

    switch (message){
  case WM_COMMAND:
      switch (wParam){
    case IDOK:
        EndDialog (hDlg,NULL);
        return(TRUE);

    case ID_UNSLBUTTON:
        /* Selecting this button unselects any selection in the
         * combo box.
         */
        SetDlgItemText (hDlg, ID_TEXT1, "");
        SetDlgItemText (hDlg, ID_TEXT2, "");
        wIndex = (WORD) SendMessage( hWndCombo, CB_GETCURSEL, NULL, 0L);
        if (wIndex == CB_ERR)
      MessageBox (hDlg, (LPSTR)"No Selection", NULL, MB_OK);
        else
      SendMessage (hWndCombo, CB_SETCURSEL, -1, 0L);
        SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
        break;

    case ID_NUMSELBUTTON:
        /* An integer value is taken from the edit control and an
         * attempt is made to select a combo box entry having this
         * index.
         */
        SetDlgItemText (hDlg, ID_TEXT1, "");
        SetDlgItemText (hDlg, ID_TEXT2, "");
        wCount = (WORD) SendMessage (hWndCombo, CB_GETCOUNT, 0, 0L);
        wIndex = (int) GetDlgItemInt (hDlg, ID_SINGLEEDIT, NULL, TRUE);
        if (wIndex >= wCount)
      MessageBox (hDlg, (LPSTR)"Bad Selection", NULL, MB_OK);
        else
      SendMessage(hWndCombo, CB_SETCURSEL, wIndex, 0L);
        SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
        break;

    case ID_TXTSELBUTTON:
        /* A text string is taken from the edit control and an
         * attempt is made to select a combo box entry having the
         * string as a prefix.
         */
        SetDlgItemText (hDlg, ID_TEXT1, "");
        SetDlgItemText (hDlg, ID_TEXT2, "");
        GetDlgItemText (hDlg, ID_SINGLEEDIT,
         (LPSTR)strSingleEditLine, 255);
        wIndex = (WORD) SendMessage (hWndCombo,
            CB_SELECTSTRING,
            -1,
            (LONG)(LPSTR)strSingleEditLine);
        if (wIndex == CB_ERR)
          MessageBox (hDlg, (LPSTR)"Bad Selection", NULL, MB_OK);
        SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
        break;

    case ID_FNDSELBUTTON:
        /* Searches for the text specified in the list of combo
         * entries and returns the index (in combo box) of the
         * first match. The index is displayed in the "Text1"
         * field of the dialog.
         */
        SetDlgItemText (hDlg, ID_TEXT1, "");
        SetDlgItemText (hDlg, ID_TEXT2, "");
        GetDlgItemText (hDlg,
            ID_SINGLEEDIT,
            (LPSTR)strSingleEditLine,
            255);
        wIndex = (WORD)SendMessage (hWndCombo,
                 CB_FINDSTRING,-1,
                 (LONG)(LPSTR)strSingleEditLine);
        if (wIndex == CB_ERR)
      MessageBox (hDlg, (LPSTR)"Bad Selection", NULL, MB_OK);
        else
      SetDlgItemInt (hDlg, ID_TEXT1, wIndex, FALSE);
        SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
        break;

    case ID_CLRBUTTON:
        /* Clears the combo box of all it's entries */
        SetDlgItemText (hDlg, ID_TEXT1, "");
        SetDlgItemText (hDlg, ID_TEXT2, "");
        wCount = (WORD) SendMessage (hWndCombo, CB_GETCOUNT, 0, 0L);
        if (!wCount)
      MessageBox (hDlg, (LPSTR)"Already clear", NULL, MB_OK);
        else{
      SetDlgItemInt (hDlg, ID_TEXT1, wCount, TRUE);
      SetDlgItemText (hDlg, ID_TEXT2, "Items cleared");
      SendMessage (hWndCombo,CB_RESETCONTENT, 0, 0L);
        }
        SetFocus (GetDlgItem (hDlg,ID_SINGLEEDIT));
        break;

    case ID_ADDBUTTON:
        /* Takes the string specified in the edit control and
         * adds it to the combo box.
         */
        SetDlgItemText (hDlg, ID_TEXT1, "");
        SetDlgItemText (hDlg, ID_TEXT2, "");
        GetDlgItemText (hDlg, ID_SINGLEEDIT, strSingleEditLine, 255);
        SendMessage (hWndCombo,
         CB_ADDSTRING,
         0,
         (LONG)(LPSTR) strSingleEditLine);
        SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
        break;

    case ID_DELETEBUTTON:
        /* Delete the currently selected item from the combo box. */
        SetDlgItemText (hDlg, ID_TEXT1, "");
        SetDlgItemText (hDlg, ID_TEXT2, "");
        wIndex = (WORD) SendMessage (hWndCombo, CB_GETCURSEL, 0, 0L);
        if (SendMessage (hWndCombo, CB_DELETESTRING, wIndex, 0L) == CB_ERR)
      MessageBox (hDlg, (LPSTR)"No Selection", NULL, MB_OK);
        else{
      SetDlgItemText (hDlg, ID_TEXT1, "deleted index #");
      SetDlgItemInt  (hDlg, ID_TEXT2, wIndex, TRUE);
        }
        SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
        break;

    case ID_CBDIRBUTTON:
        /* Appends a directory listing of the current directory
         * to the combo box entries.
         */
        SetDlgItemText (hDlg, ID_TEXT1, "");
        SetDlgItemText (hDlg, ID_TEXT2, "");
        wIndex = (WORD)SendMessage (hWndCombo,
                 CB_DIR,
                 0x10|0x4000,
                 (LONG)(LPSTR)"*.*");
        SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
        break;


    case ID_CPYBUTTON:
        /* Copies the currently selected item in the combo box to
         * the edit control.
         */
        SetDlgItemText (hDlg, ID_TEXT1, "");
        SetDlgItemText (hDlg, ID_TEXT2, "");
        wIndex = (WORD) SendMessage (hWndCombo, CB_GETCURSEL, 0, 0L);
        if (wIndex == CB_ERR)
      MessageBox(hDlg, (LPSTR)"No Selection", NULL, MB_OK);
        else{
      wCount = SendMessage (hWndCombo, CB_GETLBTEXTLEN, wIndex, 0L);
      SendMessage (hWndCombo,
             CB_GETLBTEXT,
             wIndex,
             (LONG)(LPSTR)strSingleEditLine);
      SetDlgItemText(hDlg, ID_SINGLEEDIT,
               (LPSTR)strSingleEditLine);
      SetDlgItemText(hDlg, ID_TEXT1, "copied index #");
      SetDlgItemInt(hDlg, ID_TEXT2, wIndex, TRUE);
        }
        SetFocus (GetDlgItem (hDlg, ID_SINGLEEDIT));
        break;

    /* When the combo notification box is checked, a message box
     * is flashed showing what notification codes the combo box is
     * returning to the app. in response to the messages sent by
     * the buttons.
     */
    case ID_COMBOBOX:
        if (SendMessage (hWndCheckBox, BM_GETCHECK, 0, 0L)){
      switch (HIWORD(lParam)){
          case (WORD)CBN_ERRSPACE:
            MessageBox (hDlg, (LPSTR)"CB Out of Space",
           "CB MSG", MB_OK);
            break;

          case CBN_SELCHANGE:
            MessageBox (hDlg, (LPSTR)"CB Sel Change",
           "CB MSG", MB_OK);
            break;

          case CBN_DBLCLK:
            MessageBox(hDlg, (LPSTR)"CB Double Click",
           "CB MSG", MB_OK);
            break;

          case CBN_SETFOCUS:
            SetDlgItemText(hDlg, ID_TEXT1, "CB SetFocus");
            break;

          case CBN_KILLFOCUS:
            SetDlgItemText(hDlg, ID_TEXT1, "CB KillFocus");
            break;
      }
        }
        break;

    default:
        return(FALSE);
      }
      break;

  case WM_CLOSE:
      EndDialog(hDlg, NULL);
      return(TRUE);
      break;

  default:
      return(FALSE);
    }
    return(TRUE);
}


/****************************************************************************
 *                      *
 *  FUNCTION   : OwnerComboBoxExample(hWnd, message, wParam, lParam)      *
 *                      *
 *  PURPOSE    : Dialog function for the dropdown list combo box with      *
 *     owner-draw.                *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL OwnerComboBoxExample (hDlg, message, wParam, lParam)

HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    LPDRAWITEMSTRUCT  lpdis;
    LPMEASUREITEMSTRUCT lpmis;

    /* Variables for WM_DRAWITEM */
    RECT    rc;
    HBRUSH    hbr;

    switch (message){
  case WM_COMMAND:
      switch (wParam){
    case IDOK:
       EndDialog (hDlg, NULL);
       return(TRUE);
       break;

    /* Clicking any of these buttons adds the corresponding color
     * to the combo box. The application-supplied data is the RGB
     * value for the color to be drawn in the listbox.
     */
    case ID_BLACK:
       SendMessage (GetDlgItem(hDlg, ID_LISTBOX),
        CB_ADDSTRING,
        0,
        RGB (0,0,0));
       return(TRUE);
       break;

    case ID_RED:
       SendMessage (GetDlgItem (hDlg, ID_LISTBOX),
        CB_ADDSTRING,
        0,
        RGB (255,0,0));
       return(TRUE);
       break;

    case ID_BLUE:
       SendMessage (GetDlgItem(hDlg, ID_LISTBOX),
        CB_ADDSTRING,
        0,
        RGB (0,0,255));
       return(TRUE);
       break;

    case ID_GREEN:
       SendMessage (GetDlgItem(hDlg, ID_LISTBOX),
        CB_ADDSTRING,
        0,
        RGB (0,255,0));
       return(TRUE);
       break;

    default:
       return(TRUE);
       break;
      }

  case WM_DRAWITEM:
      /* Get pointer to the DRAWITEMSTRUCT */
      lpdis = (LPDRAWITEMSTRUCT)lParam;

      if (lpdis->itemID == -1){
    /* We have a request to draw an item in the combo box, yet there
     * are no combo box items. This is sent when the user TABS into
     * an empty combo box or an empty combo box gets the focus. We
     * have to indicate (somehow) that this owner-draw combo box has
     * the focus. We do it in response to this message. Note that
     * lpdis->itemData field would be invalid in this instance so
     * we can't allow it to fall into our standard routines.
     */
    HandleFocusState(lpdis, -2);
      }
      else
      {
    switch (lpdis->itemAction)
    {
      case ODA_DRAWENTIRE:
        DrawEntireItem(lpdis, -4);
        break;

      case ODA_SELECT:
        HandleSelectionState(lpdis, 0);
        break;

      case ODA_FOCUS:
        HandleFocusState(lpdis, -2);
        break;
    }
      }

      /* Return TRUE meaning that we processed this message. */
      return(TRUE);
      break;

  case WM_MEASUREITEM:
      lpmis = (LPMEASUREITEMSTRUCT)lParam;

      /* All the items are the same height since the combo box is
       * CBS_OWNERDRAWFIXED
       */
      if (lpmis->itemID == -1){
    /* If -1 for item, then we are setting the height of the
     * always visible static item part of the dropdown combo box.
     */
    lpmis->itemHeight = 25;
    return(TRUE);
      }
      lpmis->itemHeight = 30;
      break;

  case WM_CLOSE:
      EndDialog(hDlg, NULL);
      return(TRUE);
      break;

  default:
      return(FALSE);
    }
    return(TRUE);
}


PRINT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SHOWDIB\PRINT.C

/****************************************************************************
 *                         *
 *  MODULE  : Print.c                   *
 *                         *
 *  DESCRIPTION : Routines used for printing.               *
 *                         *
 *  FUNCTIONS  : GetPrinterDC()   - Gets default printer from WIN.INI and
 *             creates a DC for it.           *
 *                         *
 *      InitPrinting()   - Initializes print job.           *
 *                         *
 *      TermPrinting()   - Terminates print job.           *
 *                         *
 *      PrintDlgProc()   - Dialog function for the "Cancel Printing" *
 *             dialog.               *
 *                         *
 *      AbortProc()     - Peeks at message queue for messages from  *
 *             the print dialog.             *
 *                         *
 ****************************************************************************

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

FARPROC  lpfnAbortProc    = NULL;
FARPROC  lpfnPrintDlgProc = NULL;
HWND   hWndParent    = NULL;
HWND   hDlgPrint    = NULL;
BOOL   bError;
BOOL   bUserAbort;


BOOL FAR PASCAL AbortProc (HDC, short);
BOOL FAR PASCAL PrintDlgProc (HWND, unsigned, WORD, DWORD);

#pragma alloc_text(_PRINT, AbortProc, PrintDlgProc)

/****************************************************************************
 *                      *
 *  FUNCTION   : GetPrinterDC()               *
 *                      *
 *  PURPOSE    : Read WIN.INI for default printer and create a DC for it.   *
 *                      *
 *  RETURNS    : A handle to the DC if successful or NULL otherwise.      *
 *                      *
 ****************************************************************************
HDC PASCAL GetPrinterDC()
{
    static char szPrinter [80];
    char    *szDevice, *szDriver, *szOutput;

    GetProfileString ("windows", "device", "", szPrinter, sizeof(szPrinter));

    if ((szDevice = strtok (szPrinter, "," )) &&
  (szDriver = strtok (NULL,      ", ")) &&
  (szOutput = strtok (NULL,      ", ")))

  return CreateDC (szDriver, szDevice, szOutput, NULL) ;

    return NULL;
}
/****************************************************************************
 *                      *
 *  FUNCTION   : InitPrinting(HDC hDC, HWND hWnd, HANDLE hInst, LPSTR msg)  *
 *                      *
 *  PURPOSE    : Makes preliminary driver calls to set up print job.      *
 *                      *
 *  RETURNS    : TRUE  - if successful.             *
 *     FALSE - otherwise.              *
 *                      *
 ****************************************************************************
BOOL PASCAL InitPrinting(HDC hDC, HWND hWnd, HANDLE hInst, LPSTR msg)
{

    bError     = FALSE;     /* no errors yet */
    bUserAbort = FALSE;     /* user hasn't aborted */

    hWndParent = hWnd;      /* save for Enable at Term time */

    lpfnPrintDlgProc = MakeProcInstance (PrintDlgProc, hInst);
    lpfnAbortProc    = MakeProcInstance (AbortProc, hInst);

    hDlgPrint = CreateDialog (hInst, "PRTDLG", hWndParent, lpfnPrintDlgProc);

    if (!hDlgPrint)
  return FALSE;

    SetWindowText (hDlgPrint, msg);
    EnableWindow (hWndParent, FALSE);       /* disable parent */

    if ((Escape (hDC, SETABORTPROC, 0, (LPSTR)lpfnAbortProc, NULL) > 0) &&
  (Escape (hDC, STARTDOC, lstrlen(msg), msg, NULL) > 0))
  bError = FALSE;
    else
  bError = TRUE;

    /* might want to call the abort proc here to allow the user to
     * abort just before printing begins */
    return TRUE;
}
/****************************************************************************
 *                      *
 *  FUNCTION   :  TermPrinting(HDC hDC)             *
 *                      *
 *  PURPOSE    :  Terminates print job.             *
 *                      *
 ****************************************************************************
void PASCAL TermPrinting(HDC hDC)
{
    if (!bError)
  Escape(hDC, ENDDOC, 0, NULL, NULL);

    if (bUserAbort)
  Escape (hDC, ABORTDOC, 0, NULL, NULL) ;
    else {
  EnableWindow(hWndParent, TRUE);
  DestroyWindow(hDlgPrint);
    }

    FreeProcInstance(lpfnAbortProc);
    FreeProcInstance(lpfnPrintDlgProc);
}
/****************************************************************************
 *                      *
 *  FUNCTION   :PrintDlgProc (HWND, unsigned , WORD , DWORD )        *
 *                      *
 *  PURPOSE    :Dialog function for the "Cancel Printing" dialog. It sets   *
 *    the abort flag if the user presses <Cancel>.        *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL PrintDlgProc (HWND hDlg, unsigned iMessage, WORD wParam, DWOR
{
    switch (iMessage) {
    case WM_INITDIALOG:

      EnableMenuItem (GetSystemMenu (hDlg, FALSE), SC_CLOSE, MF_GRAYED);
      break;

    case WM_COMMAND:
      bUserAbort = TRUE;
      EnableWindow (hWndParent, TRUE);
      DestroyWindow (hDlg);
      hDlgPrint = 0;
      break;

    default:
      return FALSE;
    }
    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   :AbortProc (HDC hPrnDC, short nCode)          *
 *                      *
 *  PURPOSE    :Checks message queue for messages from the "Cancel Printing"*
 *    dialog. If it sees a message, (this will be from a print    *
 *    cancel command), it terminates.           *
 *                      *
 *  RETURNS    :Inverse of Abort flag              *
 *                      *
 ****************************************************************************
BOOL FAR PASCAL AbortProc (HDC hPrnDC, short nCode)
{
    MSG   msg;

    while (!bUserAbort && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
  if (!hDlgPrint || !IsDialogMessage(hDlgPrint, &msg)) {
      TranslateMessage (&msg);
      DispatchMessage (&msg);
  }
    }
    return !bUserAbort;
}


PRNTFILE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\PRNTFILE\PRNTFILE.C

/****************************************************************************

    PROGRAM: PrntFile.c

    PURPOSE: Loads, saves, and edits text files

    FUNCTIONS:

        WinMain() - calls initialization function, processes message loop
        InitApplication() - initializes window data and registers window
        InitInstance() - saves instance handle and creates main window
        MainWndProc() - processes messages
        About() - processes messages for "About" dialog box
        SaveAsDlg() - save file under different name
        OpenDlg() - let user select a file, and open it.
        UpdateListBox() - Update the list box of OpenDlg
        ChangeDefExt() - Change the default extension
        SeparateFile() - Separate filename and pathname
        AddExt() - Add default extension
        CheckFileName() - Check for wildcards, add extension if needed
        SaveFile() - Save current file
        QuerySaveFile() - Called when some action might lose current contents
        SetNewBuffer() - Set new buffer for edit window

****************************************************************************/

#include "windows.h"
#include "prntfile.h"

HANDLE hInst;

HANDLE hAccTable;                                /* handle to accelerator tab
HWND hEditWnd;                                      /* handle to edit window
HWND hwnd;                                       /* handle to main window */

/* Additional includes needed for the fstat() function */

#include <sys\types.h>
#include <sys\stat.h>

char FileName[128];
char PathName[128];
char OpenName[128];
char DefPath[128];
char DefSpec[13] = "*.*";
char DefExt[] = ".txt";
char str[255];

HANDLE hEditBuffer;                       /* handle to editing buffer      */
HANDLE hOldBuffer;                        /* old buffer handle        */
HANDLE hHourGlass;                        /* handle to hourglass cursor
HANDLE hSaveCursor;                       /* current cursor handle      */
int hFile;                                /* file handle              */
int count;                                /* number of chars read or written
PSTR pBuffer;                             /* address of read/write buffer
OFSTRUCT OfStruct;                        /* information from OpenFile()
struct stat FileStatus;                   /* information from fstat()      */
BOOL bChanges = FALSE;                    /* TRUE if the file is changed
BOOL bSaveEnabled = FALSE;                /* TRUE if text in the edit buffer
PSTR pEditBuffer;                         /* address of the edit buffer
RECT Rect;                                /* dimension of the client window

char Untitled[] =                         /* default window title      */
     "Edit File - (untitled)";

/* Printer variables  */

HDC hPr;                            /* handle for printer device context
int LineSpace;                      /* spacing between lines          */
int LinesPerPage;                   /* lines per page                 */
int CurrentLine;                    /* current line                   */
int LineLength;                     /* line length                    */
DWORD dwLines;                      /* number of lines to print       */
DWORD dwIndex;                      /* index into lines to print      */
char pLine[128];                    /* buffer to store lines before printing
TEXTMETRIC TextMetric;              /* information about character size
BOOL bAbort;                        /* FALSE if user cancels printing      */
HWND hAbortDlgWnd;
FARPROC lpAbortDlg, lpAbortProc;

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;

    if (!hPrevInstance)
        if (!InitApplication(hInstance))
            return (FALSE);

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    while (GetMessage(&msg, NULL, NULL, NULL)) {

    /* Only translate message if it is not an accelerator message */

        if (!TranslateAccelerator(hwnd, hAccTable, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "PrntFileMenu";
    wc.lpszClassName = "PrntFileWClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle and creates main window

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    RECT            Rect;

    hInst = hInstance;

    hAccTable = LoadAccelerators(hInst, "PrntFileAcc");

    hwnd = CreateWindow(
        "PrntFileWClass",
        "PrntFile Sample Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hwnd)
        return (FALSE);

    GetClientRect(hwnd, (LPRECT) &Rect);

    /* Create a child window */

    hEditWnd = CreateWindow("Edit",
        NULL,
        WS_CHILD | WS_VISIBLE |
        ES_MULTILINE |
        WS_VSCROLL | WS_HSCROLL |
        ES_AUTOHSCROLL | ES_AUTOVSCROLL,
        0,
        0,
        (Rect.right-Rect.left),
        (Rect.bottom-Rect.top),
        hwnd,
        IDC_EDIT,                          /* Child control i.d. */
        hInst,
        NULL);

    if (!hEditWnd) {
        DestroyWindow(hwnd);
        return (NULL);
    }

    /* Get an hourglass cursor to use during file transfers */

    hHourGlass = LoadCursor(NULL, IDC_WAIT);

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages

    MESSAGES:

        WM_COMMAND    - application menu (About dialog box)
        WM_DESTROY    - destroy window
        WM_SIZE       - window size has changed
        WM_QUERYENDSESSION - willing to end session?
        WM_ENDSESSION - end Windows session
        WM_CLOSE      - close the window
        WM_SIZE       - window resized

    COMMENTS:

        Adds printing capability to the EDITFILE program.  Printing request
        is sent as an IDM_PRINT message.

        Before the printing operation begins, a modeless dialog box is
        created to allow the user to abort the printing operation.  This
        dialog box remains active until the print job is completed, or the
        user cancels the print operation.

****************************************************************************/

long FAR PASCAL MainWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout, lpOpenDlg, lpSaveAsDlg;

    int Success;                            /* return value from SaveAsDlg()
    int IOStatus;          /* result of file i/o      */
    int nPageSize;          /* vert. resolution of printer device */


    switch (message) {
        case WM_COMMAND:
            switch (wParam) {
                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
                    FreeProcInstance(lpProcAbout);
                    break;

                case IDM_NEW:

                    /* If current file has been modified, query user about
                     * saving it.
                     */

                    if (!QuerySaveFile(hWnd))
                        return (NULL);

                    /* bChanges is set to FALSE to indicate there have been
                     * no changes since the last file save.
                     */

                    bChanges = FALSE;
                    FileName[0] = 0;

                    /* Update the edit buffer */

                    SetNewBuffer(hWnd, NULL, Untitled);
                    break;

                case IDM_OPEN:
                    if (!QuerySaveFile(hWnd))
                        return (NULL);

                    lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);

                    /* Open the file and get its handle */

                    hFile = DialogBox(hInst, "Open", hWnd, lpOpenDlg);
                    FreeProcInstance(lpOpenDlg);
                    if (!hFile)
                        return (NULL);

                    /* Allocate edit buffer to the size of the file + 1 */

                    hEditBuffer =
                        LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,
          (WORD)FileStatus.st_size+1);

                    if (!hEditBuffer) {
                        MessageBox(hWnd, "Not enough memory.",
                            NULL, MB_OK | MB_ICONHAND);
                        return (NULL);
                    }
                    hSaveCursor = SetCursor(hHourGlass);
                    pEditBuffer = LocalLock(hEditBuffer);

                    IOStatus = read(hFile, pEditBuffer, FileStatus.st_size);
                    close(hFile);

                    /* # bytes read must equal file size */

                    if (IOStatus != (int)FileStatus.st_size) {

                        sprintf(str, "Error reading %s.", FileName);
                        SetCursor(hSaveCursor);      /* Remove the hourglass
                        MessageBox(hWnd, str, NULL, MB_OK | MB_ICONEXCLAMATIO
                    }

                    LocalUnlock(hEditBuffer);

                    /* Set up a new buffer and window title */

                    sprintf(str, "PrntFile - %s", FileName);
                    SetNewBuffer(hWnd, hEditBuffer, str);
                    SetCursor(hSaveCursor);            /* restore the cursor
                    break;

                case IDM_SAVE:

                    /* If there is no filename, use the saveas command to get
                     * one.  Otherwise, save the file using the current
                     * filename.
                     */

                    if (!FileName[0])
                        goto saveas;
                    if (bChanges)
                        SaveFile(hWnd);
                    break;

                case IDM_SAVEAS:
saveas:
                    lpSaveAsDlg = MakeProcInstance(SaveAsDlg, hInst);

                    /* Call the SaveAsDlg() function to get the new filename

                    Success = DialogBox(hInst, "SaveAs", hWnd, lpSaveAsDlg);
                    FreeProcInstance(lpSaveAsDlg);

                    /* If successful, update the window title, save the file

                    if (Success == IDOK) {
                        sprintf(str, "PrntFile - %s", FileName);
                        SetWindowText(hWnd, str);
                        SaveFile(hWnd);
                    }
                    break;                                  /* User canceled
                case IDM_PRINT:
                    hSaveCursor = SetCursor(hHourGlass);
                    hPr = GetPrinterDC();
                    if (!hPr) {
                        sprintf(str, "Cannot print %s", FileName);
                        MessageBox(hWnd, str, NULL, MB_OK | MB_ICONHAND);
                        return (NULL);
                    }

                    lpAbortDlg =  MakeProcInstance(AbortDlg, hInst);
                    lpAbortProc = MakeProcInstance(AbortProc, hInst);

                    /* Define the abort function */

                    Escape(hPr, SETABORTPROC, NULL,
                        (LPSTR) (long) lpAbortProc,
                        (LPSTR) NULL);

                    if (Escape(hPr, STARTDOC, 4, "PrntFile text",
                            (LPSTR) NULL) < 0) {
                        MessageBox(hWnd, "Unable to start print job",
                            NULL, MB_OK | MB_ICONHAND);
                        FreeProcInstance(lpAbortDlg);
                        FreeProcInstance(lpAbortProc);
                        DeleteDC(hPr);
                    }

                    bAbort = FALSE; /* Clears the abort flag  */

                    /* Create the Abort dialog box (modeless) */

                    hAbortDlgWnd = CreateDialog(hInst, "AbortDlg",
                        hWnd, lpAbortDlg);

                    if (!hAbortDlgWnd) {
                        SetCursor(hSaveCursor);      /* Remove the hourglass
                        MessageBox(hWnd, "NULL Abort window handle",
                            NULL, MB_OK | MB_ICONHAND);
                        return (FALSE);
                    }

                    /* Now show Abort dialog */

                    ShowWindow (hAbortDlgWnd, SW_NORMAL);

                    /* Disable the main window to avoid reentrancy problems *

                    EnableWindow(hWnd, FALSE);
                    SetCursor(hSaveCursor);      /* Remove the hourglass */

                    /* Since you may have more than one line, you need to
                     * compute the spacing between lines.  You can do that by
                     * retrieving the height of the characters you are printi
                     * and advancing their height plus the recommended extern
                     * leading height.
                     */

                    GetTextMetrics(hPr, &TextMetric);
                    LineSpace = TextMetric.tmHeight +
                        TextMetric.tmExternalLeading;

                    /* Since you may have more lines than can fit on one
                     * page, you need to compute the number of lines you can
                     * print per page.  You can do that by retrieving the
         * dimensions of the page and dividing the height
                     * by the line spacing.
                     */

        nPageSize = GetDeviceCaps (hPr, VERTRES);
        LinesPerPage = nPageSize / LineSpace - 1;


                    /* You can output only one line at a time, so you need a
                     * count of the number of lines to print.  You can retrie
                     * the count sending the EM_GETLINECOUNT message to the e
                     * control.
                     */

                    dwLines = SendMessage(hEditWnd, EM_GETLINECOUNT, 0, 0L);

                    /* Keep track of the current line on the current page */

                    CurrentLine = 1;

                    /* One way to output one line at a time is to retrieve
                     * one line at a time from the edit control and write it
                     * using the TextOut function.  For each line you need to
                     * advance one line space.  Also, you need to check for t
                     * end of the page and start a new page if necessary.
                     */

                    for (dwIndex = IOStatus = 0; dwIndex < dwLines; dwIndex++
                        pLine[0] = 128;               /* Maximum buffer size
                        pLine[1] = 0;
                        LineLength = SendMessage(hEditWnd, EM_GETLINE,
                            (WORD)dwIndex, (LONG)((LPSTR)pLine));
                        TextOut(hPr, 0, CurrentLine*LineSpace,
                            (LPSTR)pLine, LineLength);
                        if (++CurrentLine > LinesPerPage ) {
                            CurrentLine = 1;
                            IOStatus = Escape(hPr, NEWFRAME, 0, 0L, 0L);
                            if (IOStatus<0 || bAbort)
                                break;
                        }
                    }

                    if (IOStatus >= 0 && !bAbort) {
                        Escape(hPr, NEWFRAME, 0, 0L, 0L);
                        Escape(hPr, ENDDOC, 0, 0L, 0L);
                    }
                    EnableWindow(hWnd, TRUE);

                    /* Destroy the Abort dialog box */

                    DestroyWindow(hAbortDlgWnd);
                    FreeProcInstance(lpAbortDlg);
                    FreeProcInstance(lpAbortProc);
                    DeleteDC(hPr);
                    break;


                /* edit menu commands */

                case IDM_UNDO:
                case IDM_CUT:
                case IDM_COPY:
                case IDM_PASTE:
                case IDM_CLEAR:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "PrntFile Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;

                case IDM_EXIT:
                    QuerySaveFile(hWnd);
                    DestroyWindow(hWnd);
                    break;

                case IDC_EDIT:
                    if (HIWORD (lParam) == EN_ERRSPACE) {
                        MessageBox (
                              GetFocus ()
                            , "Out of memory."
                            , "PrntFile Sample Application"
                            , MB_ICONHAND | MB_OK
                        );
                    }
                    break;

            }
            break;

        case WM_SETFOCUS:
            SetFocus (hEditWnd);
            break;

        case WM_SIZE:
            MoveWindow(hEditWnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
            break;

        case WM_QUERYENDSESSION:             /* message: to end the session?
            return (QuerySaveFile(hWnd));

        case WM_CLOSE:                       /* message: close the window
            if (QuerySaveFile(hWnd))
                DestroyWindow(hWnd);
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

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

/****************************************************************************

    FUNCTION: SaveAsDlg(HWND, unsigned, WORD, LONG)

    PURPOSE: Allows user to change name to save file to

    COMMENTS:

        This will initialize the window class if it is the first time this
        application is run.  It then creates the window, and processes the
        message loop until a PostQuitMessage is received.  It exits the
        application by returning the value passed by the PostQuitMessage.

****************************************************************************/

int FAR PASCAL SaveAsDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    char TempName[128];

    switch (message) {
        case WM_INITDIALOG:

            /* If no filename is entered, don't allow the user to save to it

            if (!FileName[0])
                bSaveEnabled = FALSE;
            else {
                bSaveEnabled = TRUE;

                /* Process the path to fit within the IDC_PATH field */

                DlgDirList(hDlg, DefPath, NULL, IDC_PATH, 0x4010);

                /* Send the current filename to the edit control */

                SetDlgItemText(hDlg, IDC_EDIT, FileName);

                /* Accept all characters in the edit control */

                SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL, 0,
                    MAKELONG(0, 0x7fff));
            }

            /* Enable or disable the save control depending on whether the
             * filename exists.
             */

            EnableWindow(GetDlgItem(hDlg, IDOK), bSaveEnabled);

            /* Set the focus to the edit control within the dialog box */

            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE);                 /* FALSE since Focus was changed

        case WM_COMMAND:
            switch (wParam) {
                case IDC_EDIT:

                    /* If there was previously no filename in the edit
                     * control, then the save control must be enabled as soon
                     * a character is entered.
                     */

                    if (HIWORD(lParam) == EN_CHANGE && !bSaveEnabled)
                    EnableWindow(GetDlgItem(hDlg, IDOK), bSaveEnabled = TRUE)
                    return (TRUE);

                case IDOK:

                   /* Get the filename from the edit control */

                    GetDlgItemText(hDlg, IDC_EDIT, TempName, 128);

                    /* If there are no wildcards, then separate the name into
                     * path and name.  If a path was specified, replace the
                     * default path with the new path.
                     */

                    if (CheckFileName(hDlg, FileName, TempName)) {
                        SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,
                            (LPSTR) FileName);
                        if (str[0])
                            strcpy(DefPath, str);

                        /* Tell the caller a filename was selected */

                        EndDialog(hDlg, IDOK);
                    }
                    return (TRUE);

                case IDCANCEL:

                    /* Tell the caller the user canceled the SaveAs function

                    EndDialog(hDlg, IDCANCEL);
                    return (TRUE);
            }
            break;

    }
    return (FALSE);
}

/****************************************************************************

    FUNCTION: OpenDlg(HWND, unsigned, WORD, LONG)

    PURPOSE: Let user select a file, and open it.

****************************************************************************/

HANDLE FAR PASCAL OpenDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    WORD index;
    PSTR pTptr;
    HANDLE hFile;

    switch (message) {
        case WM_COMMAND:
            switch (wParam) {

                case IDC_LISTBOX:
                    switch (HIWORD(lParam)) {

                        case LBN_SELCHANGE:
                            /* If item is a directory name, append "*.*" */
          if (DlgDirSelect(hDlg, str, IDC_LISTBOX)) {
                                strcat(str, DefSpec);

          }
                            SetDlgItemText(hDlg, IDC_EDIT, str);
                            SendDlgItemMessage(hDlg,
                                IDC_EDIT,
                                EM_SETSEL,
                                NULL,
                                MAKELONG(0, 0x7fff));


                            break;

                        case LBN_DBLCLK:
                            goto openfile;
                    }
                    return (TRUE);

                case IDOK:
openfile:
                    GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);
                    if (strchr(OpenName, '*') || strchr(OpenName, '?')) {
                        SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,
                            (LPSTR) OpenName);
                        if (str[0])
                            strcpy(DefPath, str);
                        ChangeDefExt(DefExt, DefSpec);
                        UpdateListBox(hDlg);
                        return (TRUE);
                    }

                    if (!OpenName[0]) {
                        MessageBox(hDlg, "No filename specified.",
                            NULL, MB_OK | MB_ICONHAND);
                        return (TRUE);
                    }

                    AddExt(OpenName, DefExt);

                    /* Open the file */

                    if ((hFile = OpenFile(OpenName, (LPOFSTRUCT) &OfStruct,
                            OF_READ)) == -1) {
                        sprintf(str, "Error %d opening %s.",
                            OfStruct.nErrCode, OpenName);
                        MessageBox(hDlg, str, NULL,
                            MB_OK | MB_ICONHAND);
                    }
                    else {

                        /* Make sure there's enough room for the file */

                        fstat(hFile, &FileStatus);

                        if (FileStatus.st_size > MAXFILESIZE) {
                            sprintf(str,
                    "Not enough memory to load %s.\n%s exceeds %ld bytes.",
                                OpenName, OpenName, MAXFILESIZE);
                            MessageBox(hDlg, str, NULL,
                                MB_OK | MB_ICONHAND);
                            return (TRUE);
                        }

                        /* File is opened and there is enough room so return
                         * the handle to the caller.
                         */

                        strcpy(FileName, OpenName);
                        EndDialog(hDlg, hFile);
                        return (TRUE);
                    }
                    return (TRUE);

                case IDCANCEL:
       /* strcpy(DefPath, str);
        ChangeDefExt(DefExt, DefSpec);*/
                    EndDialog(hDlg, NULL);
                    return (TRUE);
            }
            break;

        case WM_INITDIALOG:                        /* message: initialize
            UpdateListBox(hDlg);
            SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
            SendDlgItemMessage(hDlg,               /* dialog handle      */
                IDC_EDIT,                          /* where to send message
                EM_SETSEL,                         /* select characters
                NULL,                              /* additional information
                MAKELONG(0, 0x7fff));              /* entire contents      */
            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE); /* Indicates the focus is set to a control */
    }
    return FALSE;
}

/****************************************************************************

    FUNCTION: UpdateListBox(HWND);

    PURPOSE: Update the list box of OpenDlg

****************************************************************************/

void UpdateListBox(hDlg)
HWND hDlg;
{
    strcpy(str, DefPath);
    strcat(str, DefSpec);
    DlgDirList(hDlg, str, IDC_LISTBOX, IDC_PATH, 0x4010);

    /* To ensure that the listing is made for a subdir. of
     * current drive dir...
     */
    if (!strchr (DefPath, ':'))
  DlgDirList(hDlg, DefSpec, IDC_LISTBOX, IDC_PATH, 0x4010);

    /* Remove the '..' character from path if it exists, since this
     * will make DlgDirList move us up an additional level in the tree
     * when UpdateListBox() is called again.
     */
    if (strstr (DefPath, ".."))
  DefPath[0] = '\0';
    SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
}

/****************************************************************************

    FUNCTION: ChangeDefExt(PSTR, PSTR);

    PURPOSE: Change the default extension

****************************************************************************/

void ChangeDefExt(Ext, Name)
PSTR Ext, Name;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr)
        if (!strchr(pTptr, '*') && !strchr(pTptr, '?'))
            strcpy(Ext, pTptr);
}

/****************************************************************************

    FUNCTION: SeparateFile(HWND, LPSTR, LPSTR, LPSTR)

    PURPOSE: Separate filename and pathname

****************************************************************************/

void SeparateFile(hDlg, lpDestPath, lpDestFileName, lpSrcFileName)
HWND hDlg;
LPSTR lpDestPath, lpDestFileName, lpSrcFileName;
{
    LPSTR lpTmp;
    char  cTmp;

    lpTmp = lpSrcFileName + (long) lstrlen(lpSrcFileName);
    while (*lpTmp != ':' && *lpTmp != '\\' && lpTmp > lpSrcFileName)
        lpTmp = AnsiPrev(lpSrcFileName, lpTmp);
    if (*lpTmp != ':' && *lpTmp != '\\') {
        lstrcpy(lpDestFileName, lpSrcFileName);
        lpDestPath[0] = 0;
        return;
    }
    lstrcpy(lpDestFileName, lpTmp + 1);
    cTmp = *(lpTmp + 1);
    lstrcpy(lpDestPath, lpSrcFileName);
     *(lpTmp + 1) = cTmp;
    lpDestPath[(lpTmp - lpSrcFileName) + 1] = 0;
}

/****************************************************************************

    FUNCTION: AddExt(PSTR, PSTR);

    PURPOSE: Add default extension

/***************************************************************************/

void AddExt(Name, Ext)
PSTR Name, Ext;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr != '.')
        strcat(Name, Ext);
}

/****************************************************************************

    FUNCTION: CheckFileName(HWND, PSTR, PSTR)

    PURPOSE: Check for wildcards, add extension if needed

    COMMENTS:

        Make sure you have a filename and that it does not contain any
        wildcards.  If needed, add the default extension.  This function is
        called whenever your application wants to save a file.

****************************************************************************/

BOOL CheckFileName(hWnd, pDest, pSrc)
HWND hWnd;
PSTR pDest, pSrc;
{
    PSTR pTmp;

    if (!pSrc[0])
        return (FALSE);               /* Indicates no filename was specified

    pTmp = pSrc;
    while (*pTmp) {                     /* Searches the string for wildcards
        switch (*pTmp++) {
            case '*':
            case '?':
                MessageBox(hWnd, "Wildcards not allowed.",
                    NULL, MB_OK | MB_ICONEXCLAMATION);
                return (FALSE);
        }
    }

    AddExt(pSrc, DefExt);            /* Adds the default extension if needed

    if (OpenFile(pSrc, (LPOFSTRUCT) &OfStruct, OF_EXIST) >= 0) {
        sprintf(str, "Replace existing %s?", pSrc);
        if (MessageBox(hWnd, str, "PrntFile",
                MB_OKCANCEL | MB_ICONEXCLAMATION) == IDCANCEL)
            return (FALSE);
    }
    strcpy(pDest, pSrc);
    return (TRUE);
}

/****************************************************************************

    FUNCTION: SaveFile(HWND)

    PURPOSE: Save current file

    COMMENTS:

        This saves the current contents of the Edit buffer, and changes
        bChanges to indicate that the buffer has not been changed since the
        last save.

        Before the edit buffer is sent, you must get its handle and lock it
        to get its address.  Once the file is written, you must unlock the
        buffer.  This allows Windows to move the buffer when not in immediate
        use.

****************************************************************************/

BOOL SaveFile(hWnd)
HWND hWnd;
{
    BOOL bSuccess;
    int IOStatus;                                  /* result of a file write

    if ((hFile = OpenFile(FileName, &OfStruct,
        OF_PROMPT | OF_CANCEL | OF_CREATE)) < 0) {

        /* If the file can't be saved */

        sprintf(str, "Cannot write to %s.", FileName);
        MessageBox(hWnd, str, NULL, MB_OK | MB_ICONHAND);
        return (FALSE);
    }


    hEditBuffer = SendMessage(hEditWnd, EM_GETHANDLE, 0, 0L);
    pEditBuffer = LocalLock(hEditBuffer);

    /* Set the cursor to an hourglass during the file transfer */

    hSaveCursor = SetCursor(hHourGlass);
    IOStatus = write(hFile, pEditBuffer, strlen(pEditBuffer));
    close(hFile);
    SetCursor(hSaveCursor);
    if (IOStatus != strlen(pEditBuffer)) {
        sprintf(str, "Error writing to %s.", FileName);
        MessageBox(hWnd, str,
            NULL, MB_OK | MB_ICONHAND);
        bSuccess = FALSE;
    }
    else {
        bSuccess = TRUE;                /* Indicates the file was saved
        bChanges = FALSE;               /* Indicates changes have been saved
    }

    LocalUnlock(hEditBuffer);
    return (bSuccess);
}

/****************************************************************************

    FUNCTION: QuerySaveFile(HWND);

    PURPOSE: Called when some action might lose current contents

    COMMENTS:

        This function is called whenever we are about to take an action that
        would lose the current contents of the edit buffer.

****************************************************************************/

BOOL QuerySaveFile(hWnd)
HWND hWnd;
{
    int Response;
    FARPROC lpSaveAsDlg;

    if (bChanges) {
        sprintf(str, "Save current changes: %s", FileName);
        Response = MessageBox(hWnd, str,
            "PrntFile",  MB_YESNOCANCEL | MB_ICONHAND);
        if (Response == IDYES) {
check_name:

            /* Make sure there is a filename to save to */

            if (!FileName[0]) {
                lpSaveAsDlg = MakeProcInstance(SaveAsDlg, hInst);
                Response = DialogBox(hInst, "SaveAs",
                    hWnd, lpSaveAsDlg);
                FreeProcInstance(lpSaveAsDlg);
                if (Response == IDOK)
                    goto check_name;
                else
                    return (FALSE);
            }
            SaveFile(hWnd);
        }
        else if (Response == IDCANCEL)
            return (FALSE);
    }
    else
        return (TRUE);
}

/****************************************************************************

    FUNCTION: SetNewBuffer(HWND, HANDLE, PSTR)

    PURPOSE: Set new buffer for edit window

    COMMENTS:

        Point the edit window to the new buffer, update the window title, and
        redraw the edit window.  If hNewBuffer is NULL, then create an empty
        1K buffer, and return its handle.

****************************************************************************/

void SetNewBuffer(hWnd, hNewBuffer, Title)
HWND hWnd;
HANDLE hNewBuffer;
PSTR Title;
{
    HANDLE hOldBuffer;

    hOldBuffer = SendMessage(hEditWnd, EM_GETHANDLE, 0, 0L);
    LocalFree(hOldBuffer);
    if (!hNewBuffer)                    /* Allocates a buffer if none exists
        hNewBuffer = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, 1);

    SendMessage(hEditWnd, EM_SETHANDLE, hNewBuffer, 0L); /* Updates the buffe
                  and displays new buffer */
    SetWindowText(hWnd, Title);
    SetFocus(hEditWnd);
    bChanges = FALSE;
}


/****************************************************************************

    FUNCTION: GetPrinterDC()

    PURPOSE:  Get hDc for current device on current output port according to
              info in WIN.INI.

    COMMENTS:

        Searches WIN.INI for information about what printer is connected, and
        if found, creates a DC for the printer.

        returns
            hDC > 0 if success
            hDC = 0 if failure

****************************************************************************/

HANDLE GetPrinterDC()
{
    char pPrintInfo[80];
    LPSTR lpTemp;
    LPSTR lpPrintType;
    LPSTR lpPrintDriver;
    LPSTR lpPrintPort;

    if (!GetProfileString("windows", "Device", (LPSTR)"", pPrintInfo, 80))
        return (NULL);
    lpTemp = lpPrintType = pPrintInfo;
    lpPrintDriver = lpPrintPort = 0;
    while (*lpTemp) {
        if (*lpTemp == ',') {
            *lpTemp++ = 0;
            while (*lpTemp == ' ')
                lpTemp = AnsiNext(lpTemp);
            if (!lpPrintDriver)
                lpPrintDriver = lpTemp;
            else {
                lpPrintPort = lpTemp;
                break;
            }
        }
        else
            lpTemp = AnsiNext(lpTemp);
    }

    return (CreateDC(lpPrintDriver, lpPrintType, lpPrintPort, (LPSTR) NULL));
}

/****************************************************************************

    FUNCTION: AbortProc()

    PURPOSE:  Processes messages for the Abort Dialog box

****************************************************************************/

int FAR PASCAL AbortProc(hPr, Code)
HDC hPr;                            /* for multiple printer display contexts
int Code;                           /* printing status                */
{
    MSG msg;

    /* Process messages intended for the abort dialog box */

    while (!bAbort && PeekMessage(&msg, NULL, NULL, NULL, TRUE))
        if (!IsDialogMessage(hAbortDlgWnd, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

    /* bAbort is TRUE (return is FALSE) if the user has aborted */

    return (!bAbort);
}

/****************************************************************************

    FUNCTION: AbortDlg(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for printer abort dialog box

    MESSAGES:

        WM_INITDIALOG - initialize dialog box
        WM_COMMAND    - Input received

    COMMENTS

        This dialog box is created while the program is printing, and allows
        the user to cancel the printing process.

****************************************************************************/

int FAR PASCAL AbortDlg(hDlg, msg, wParam, lParam)
HWND hDlg;
unsigned msg;
WORD wParam;
LONG lParam;
{
    switch(msg) {

        /* Watch for Cancel button, RETURN key, ESCAPE key, or SPACE BAR */

        case WM_COMMAND:
            return (bAbort = TRUE);

        case WM_INITDIALOG:

            /* Set the focus to the Cancel box of the dialog */

            SetFocus(GetDlgItem(hDlg, IDCANCEL));
            SetDlgItemText(hDlg, IDC_FILENAME, FileName);
            return (TRUE);
        }
    return (FALSE);
}


/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

        WM_INITDIALOG - initialize dialog box
        WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:
            return (TRUE);

        case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
                EndDialog(hDlg, TRUE);
                return (TRUE);
            }
            return (TRUE);
    }
    return (FALSE);
}


RAINBOW.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\RAINBOW\RAINBOW.C

/*
 * RAINBOW -- Example Dialog Editor custom control
 *
 */

#include <windows.h>
#include <custcntl.h>
#include "rainbow.h"

/* global static variables */
HANDLE    hLibData;
HANDLE    hLibInstance;
LPFNSTRTOID    lpfnVerId;
LPFNIDTOSTR    lpfnIdStr;

/* string for property lists */
#define  IDFNLO          "lpfnIdFnLo"
#define  IDFNHI          "lpfnIdFnHi"

#define  RAINBOWCLASS      "Rainbow"

/* general rainbow definitions */
#define  ID              GetWindowWord( hWnd, GWW_ID )
#define  PARENT          GetWindowWord( hWnd, GWW_HWNDPARENT )
#define  INSTANCE          GetWindowWord( hWnd, GWW_HINSTANCE )

/* rainbow specific definitions */
#define  RAINBOW_EXTRA      12

#define  RANGE            GetWindowWord( hWnd, 0 )
#define  TABLE            GetWindowWord( hWnd, 2 )
#define  WIDTH            GetWindowWord( hWnd, 4 )
#define  HEIGHT          GetWindowWord( hWnd, 6 )
#define  CHOICE          GetWindowWord( hWnd, 8 )
#define  CAPTURE          GetWindowWord( hWnd, 10 )

#define  SET_RANGE(x)      SetWindowWord( hWnd, 0, x )
#define  SET_TABLE(x)      SetWindowWord( hWnd, 2, x )
#define  SET_WIDTH(x)      SetWindowWord( hWnd, 4, x )
#define  SET_HEIGHT(x)      SetWindowWord( hWnd, 6, x )
#define  SET_CHOICE(x)      SetWindowWord( hWnd, 8, x )
#define  SET_CAPTURE(x)      SetWindowWord( hWnd, 10, x )

/* caret related definitions */
#define  CARET_XPOS        ((CHOICE*WIDTH)+3)
#define  CARET_YPOS        (3)
#define  CARET_WIDTH        (WIDTH-6)
#define  CARET_HEIGHT      (HEIGHT-6)

/* selector related definitions */
#define  SELECTOR_XPOS      ((CHOICE*WIDTH)+1)
#define  SELECTOR_YPOS      (1)
#define  SELECTOR_WIDTH      (WIDTH-2)
#define  SELECTOR_HEIGHT    (HEIGHT-2)

/* undocumented internal function definitions */
int FAR PASCAL    lstrlen( LPSTR );
int FAR PASCAL    lstrcmp( LPSTR, LPSTR );
LPSTR FAR PASCAL  lstrcpy( LPSTR, LPSTR );
LPSTR FAR PASCAL  lstrcat( LPSTR, LPSTR );

/* internal rainbow function prototypes */
BOOL FAR PASCAL   RainbowDlgFn( HWND, WORD, WORD, LONG );
LONG FAR PASCAL   RainbowWndFn( HWND, WORD, WORD, LONG );
void static      DrawSelector( HWND, HDC );

/*♀*/

/*
 * LibMain( hInstance, wDataSegment, wHeapSize, lpszCmdLine ) : WORD
 *
 *    hInstance      library instance handle
 *    wDataSegment   library data segment
 *    wHeapSize      default heap size
 *    lpszCmdLine    command line arguments
 *
 * LibMain is called by LibEntry, which is called by Windows when
 * the DLL is loaded.  The LibEntry routine is provided
 * in the LIBENTRY.OBJ in the SDK Link Libraries disk.  (The source
 * LIBENTRY.ASM is also provided.)
 *
 * LibEntry initializes the DLL's heap, if a HEAPSIZE value is
 * specified in the DLL's DEF file.  Then LibEntry calls
 * LibMain.  The LibMain function below satisfies that call.
 *
 * LibMain performs all the initialization necessary to use the
 * rainbow user control.  Included in this initialization is the
 * registration of the Rainbow window class.
 *
*/

int FAR PASCAL LibMain(
   HANDLE      hInstance,
   WORD        wDataSegment,
   WORD        wHeapSize,
   LPSTR       lpszCmdLine )
{
  HANDLE      hClassStruct;
  LPWNDCLASS    lpClassStruct;

  /* register rainbow window if necessary */
  if ( hLibInstance == NULL ) {

    /* allocate memory for class structure */
    hClassStruct = GlobalAlloc( GHND, (DWORD)sizeof(WNDCLASS) );
    if ( hClassStruct ) {

      /* lock it down */
      lpClassStruct = (LPWNDCLASS)GlobalLock( hClassStruct );
      if ( lpClassStruct ) {

        /* define class attributes */
        lpClassStruct->lpszClassName =   (LPSTR)RAINBOWCLASS;
        lpClassStruct->hCursor =      LoadCursor( NULL, IDC_ARROW );
        lpClassStruct->lpszMenuName =    (LPSTR)NULL;
        lpClassStruct->style =        CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_GLO
        lpClassStruct->lpfnWndProc =    RainbowWndFn;
        lpClassStruct->hInstance =      hInstance;
        lpClassStruct->hIcon =        NULL;
        lpClassStruct->cbWndExtra =    RAINBOW_EXTRA;
        lpClassStruct->hbrBackground =  (HBRUSH)(COLOR_WINDOW + 1 );

        /* register rainbow window class */
        hLibInstance = ( RegisterClass(lpClassStruct) ) ? hInstance : NULL;

        /* unlock structure */
        GlobalUnlock( hClassStruct );

      }

      /* release class structure */
      GlobalFree( hClassStruct );

    }

  }

  /* return result 1 = success; 0 = fail */
  return( hLibInstance? 1:0 );
}

/*♀*/


/****************************************************************************
    FUNCTION:  WEP(int)

    PURPOSE:  Performs cleanup tasks when the DLL is unloaded.  WEP() is
              called automatically by Windows when the DLL is unloaded
              (no remaining tasks still have the DLL loaded).  It is
              strongly recommended that a DLL have a WEP() function,
              even if it does nothing but return, as in this example.

*****************************************************************************
VOID FAR PASCAL WEP (bSystemExit)
int  bSystemExit;
{
    return;
}


/*
 * RainbowInfo() : HANDLE
 *
 * This function returns a handle to a global block of memory that
 * contains various information about the kinds of controls the library
 * is capable of supporting.  This data block can, for example, be used
 * by the dialog editor when determining the capabilities of a particular
 * control library.
 *
 * Note that this handle becomes the property of the caller once this
 * function returns.  This implies that the caller must call GlobalFree
 * once it is finished with the data.
 *
 */

HANDLE FAR PASCAL RainbowInfo()
{
  HANDLE    hCtlInfo;
  LPCTLINFO  lpCtlInfo;

  /* allocate space for information structure */
  hCtlInfo = GlobalAlloc( GHND, (DWORD)sizeof(CTLINFO) );
  if ( hCtlInfo ) {

    /* attempt to lock it down */
    lpCtlInfo = (LPCTLINFO)GlobalLock( hCtlInfo );
    if ( lpCtlInfo ) {

      /* define the fixed portion of the structure */
      lpCtlInfo->wVersion = 100;
      lpCtlInfo->wCtlTypes = 1;
      lstrcpy( lpCtlInfo->szClass, RAINBOWCLASS );
      lstrcpy( lpCtlInfo->szTitle, "Sample User Control" );

      /* define the variable portion of the structure */
      lpCtlInfo->Type[0].wWidth = 33;
      lpCtlInfo->Type[0].wHeight = 20;
      lpCtlInfo->Type[0].dwStyle = WS_CHILD;
      lstrcpy( lpCtlInfo->Type[0].szDescr, "Rainbow" );

      /* unlock it */
      GlobalUnlock( hCtlInfo );

    } else {
      GlobalFree( hCtlInfo );
      hCtlInfo = NULL;
    }

  }

  /* return result */
  return( hCtlInfo );

}

/*♀*/

/*
 * RainbowStyle( hWnd, hCtlStyle, lpfnVeriyId, lpfnGetIdStr ) : BOOL;
 *
 *    hWnd           handle to parent window
 *    hCtlStyle      handle to control style
 *    lpfnVerifyId   pointer to the VerifyId function from Dialog editor
 *    lpfnGetIdStr   pointer to the GetIdStr functionn from Dialog editor
 *
 * This function enables the user to edit the style of a particular
 * control provided.  The current control style information is passed
 * in using a handle to a control style data structure.
 *
 * This function returns this same handle (referencing updated
 * information) if the dialog box is normally closed.  A value of
 * NULL is returned if the user cancelled the operation.
 *
 */

BOOL FAR PASCAL RainbowStyle(
  HWND        hWnd,
  HANDLE      hCtlStyle,
  LPFNSTRTOID       lpfnVerifyId,
  LPFNIDTOSTR  lpfnGetIdStr )
{
  FARPROC    lpDlgFn;
  HANDLE    hNewCtlStyle;

  /* initialization */
  hLibData = hCtlStyle;
  lpfnVerId = lpfnVerifyId;
  lpfnIdStr = lpfnGetIdStr;

  /* display dialog box */
  lpDlgFn = MakeProcInstance( (FARPROC)RainbowDlgFn, hLibInstance );
  hNewCtlStyle = ( DialogBox(hLibInstance,"RainbowStyle",hWnd,lpDlgFn) ) ? hL
  FreeProcInstance( lpDlgFn );

  /* return updated data block */
  return( hNewCtlStyle );

}

/*♀*/

/*
 * RainbowFlags( wFlags, lpszString, wMaxString ) : WORD;
 *
 *    wFlags         class style flags
 *    lpszString     class style string
 *    wMaxString     maximum size of class style string
 *
 * This function translates the class style flags provided into a
 * corresponding text string for output to an RC file.  The general
 * windows flags (contained in the low byte) are not interpreted,
 * only those in the high byte.
 *
 * The value returned by this function is the library instance
 * handle when sucessful, and NULL otherwise.
 *
 */

WORD FAR PASCAL RainbowFlags(
  WORD        wFlags,
  LPSTR       lpszString,
  WORD        wMaxString )
{
  lpszString[0] = NULL;
  return( 0 );
}

/*♀*/

/*
 * RainbowWndFn( hWnd, wMsg, wParam, lParam ) : LONG
 *
 *    hWnd          handle to rainbow window
 *    wMsg          message number
 *    wParam        single word parameter
 *    lParam        double word parameter
 *
 * This function is responsible for processing all the messages
 * which relate to the rainbow control window.  Note how the
 * code is written to avoid potential problems when re-entrancy
 * ocurrs - this involves the use of extra bytes associated with
 * the window data structure.
 *
 * The LONG value returned by this function is either a value
 * returned by the internal handling of the message or by the
 * default window procedure.
 *
 */

LONG FAR PASCAL RainbowWndFn( hWnd, wMsg, wParam, lParam )
  HWND      hWnd;
  WORD      wMsg;
  WORD      wParam;
  LONG      lParam;
{
  /* local variables */
  LONG      lResult;          /* temporary result variable */

  /* initialization */
  lResult = TRUE;

  /* process message */
  switch( wMsg )
    {
  case WM_GETDLGCODE : /* capture all key strokes */
    lParam = DLGC_WANTARROWS;
    break;
  case WM_CREATE : /* create pallette window */

    {
      /* temporary variables */
      HANDLE    hrgbList;        /* handle to rgb list */
      LONG FAR *  lprgbEntry;        /* pointer to rgb list */

      /* allocate space for rgb color list */
      hrgbList = GlobalAlloc( GMEM_MOVEABLE, sizeof(LONG)*16L );
      if ( hrgbList ) {

         /*
         * Define initial rgb color & value list - note that
         * eight default colors are selected with the values
         * matching each of the colors.
         */

        lprgbEntry = (LONG FAR *)GlobalLock( hrgbList );
        lprgbEntry[0] = RGB( 0x00, 0x00, 0x00 );
        lprgbEntry[1] = RGB( 0x00, 0x00, 0xFF );
        lprgbEntry[2] = RGB( 0x00, 0xFF, 0x00 );
        lprgbEntry[3] = RGB( 0xFF, 0x00, 0x00 );
        lprgbEntry[4] = RGB( 0x00, 0xFF, 0xFF );
        lprgbEntry[5] = RGB( 0xFF, 0xFF, 0x00 );
        lprgbEntry[6] = RGB( 0xFF, 0x00, 0xFF );
        lprgbEntry[7] = RGB( 0xFF, 0xFF, 0xFF );
        lprgbEntry[8] = RGB( 0x00, 0x00, 0x00 );
        lprgbEntry[9] = RGB( 0x00, 0x00, 0xFF );
        lprgbEntry[10] = RGB( 0x00, 0xFF, 0x00 );
        lprgbEntry[11] = RGB( 0xFF, 0x00, 0x00 );
        lprgbEntry[12] = RGB( 0x00, 0xFF, 0xFF );
        lprgbEntry[13] = RGB( 0xFF, 0xFF, 0x00 );
        lprgbEntry[14] = RGB( 0xFF, 0x00, 0xFF );
        lprgbEntry[15] = RGB( 0xFF, 0xFF, 0xFF );
        GlobalUnlock( hrgbList );

        /* define instance variables */
        SET_RANGE( 8 );
        SET_TABLE( hrgbList );
        SET_WIDTH( ((LPCREATESTRUCT)lParam)->cx / 8 );
        SET_HEIGHT( ((LPCREATESTRUCT)lParam)->cy );
        SET_CHOICE( 0 );
        SET_CAPTURE( FALSE );

      } else
        DestroyWindow( hWnd );

    }

    break;
  case WM_SIZE : /* window being resized */

    /* redefine width & height instance variables */
    SET_WIDTH( LOWORD(lParam) / 8 );
    SET_HEIGHT( HIWORD(lParam) );

    break;
  case WM_PAINT : /* paint control window */

    {
      PAINTSTRUCT    Ps;          /* paint structure */
      WORD        wEntry;        /* current color entry */
      HANDLE      hBrush;        /* handle to new brush */
      HANDLE      hOldBrush;      /* handle to old brush */
      LONG FAR *    lprgbEntry;      /* pointer to rgb list */

      /* start paint operation */
      BeginPaint( hWnd, (LPPAINTSTRUCT)&Ps );

      /* iteratively paint each color patch */
      lprgbEntry = (LONG FAR *)GlobalLock( TABLE );
      for ( wEntry=0; wEntry<RANGE; wEntry++ ) {

        /* create solid brush for patch & select */
        hBrush = CreateSolidBrush( lprgbEntry[wEntry] );
        hOldBrush = SelectObject( Ps.hdc, hBrush );

        /* draw rectangle with brush fill */
        Rectangle(
          Ps.hdc,
          wEntry*WIDTH,
          0,
          (wEntry*WIDTH)+WIDTH,
          HEIGHT
        );

        /* unselect brush and delete */
        SelectObject( Ps.hdc, hOldBrush );
        DeleteObject( hBrush );

      }
      GlobalUnlock( TABLE );

      /* End paint operation */
      EndPaint( hWnd, (LPPAINTSTRUCT)&Ps );
    }

    break;
  case WM_KEYDOWN : /* key being pressed */

    {
      /* local variables */
      HDC        hDC;          /* display context handle */
      LONG FAR *    lprgbEntry;      /* pointer to rgb list */

      /* retrieve display context & unmark current selection */
      hDC = GetDC( hWnd );
      DrawSelector( hWnd, hDC );

      /* process virtual key codes */
      switch( wParam )
        {
      case VK_HOME : /* home key */
        SET_CHOICE( 0 );
        break;
      case VK_UP : /* up cursor key */
      case VK_LEFT : /* left cursor key */
        SET_CHOICE( (CHOICE > 0) ? CHOICE-1 : RANGE-1 );
        break;
      case VK_DOWN : /* down cursor key */
      case VK_RIGHT : /* right cursor key */
      case VK_SPACE : /* space bar - move right */
        SET_CHOICE( (CHOICE < RANGE-1) ? CHOICE+1 : 0 );
        break;
      case VK_END : /* end key */
        SET_CHOICE( RANGE-1 );
        break;
      default : /* some other key */
        lResult = FALSE;
        break;
      }

      /* mark new selection & release display context */
      DrawSelector( hWnd, hDC );
      ReleaseDC( hWnd, hDC );

      /* move caret to new position */
      SetCaretPos( CARET_XPOS, CARET_YPOS );

      /* notify parent of new selection */
      lprgbEntry = (LONG FAR *)GlobalLock( TABLE );
      SendMessage(PARENT,WM_COMMAND,ID,lprgbEntry[RANGE+CHOICE]);
      GlobalUnlock( TABLE );

    }

    break;
  case WM_SETFOCUS : /* get focus - display caret */
    /* create caret & display */
    CreateCaret( hWnd, NULL, CARET_WIDTH, CARET_HEIGHT );
    SetCaretPos( CARET_XPOS, CARET_YPOS );
    ShowCaret( hWnd );
    break;

  case WM_LBUTTONDOWN : /* left button depressed - fall through */

    {
      /* local variables */
      HDC        hDC;          /* display context handle */
      LONG FAR *    lprgbEntry;      /* pointer to rgb list */

      /* retrieve display context */
      hDC = GetDC ( hWnd );

      /* unmark old selection & mark new one */
      DrawSelector( hWnd, hDC );
      SET_CHOICE( LOWORD(lParam)/WIDTH );
      DrawSelector( hWnd, hDC );

      /* release display context & move caret */
      ReleaseDC( hWnd, hDC );

      /* capture focus & move caret */
      SetFocus(hWnd);
      SetCaretPos( CARET_XPOS, CARET_YPOS );

      /* notify parent of new selection */
      lprgbEntry = (LONG FAR *)GlobalLock( TABLE );
      SendMessage(PARENT,WM_COMMAND,ID,lprgbEntry[RANGE+CHOICE]);
      GlobalUnlock( TABLE );

      /* activate capture */
      SetCapture( hWnd );
      SET_CAPTURE( TRUE );

    }

    break;
  case WM_MOUSEMOVE : /* mouse being moved */

    /* track mouse only if capture on */
    if ( CAPTURE ) {

      /* local variables */
      HDC        hDC;          /* display context handle */
      WORD        wNewChoice;      /* new mouse selection */
      LONG FAR *    lprgbEntry;      /* pointer to rgb list */

      /* calculate new selection */
      wNewChoice = ( LOWORD(lParam) <= 0 ) ?
        0 :
        ( LOWORD(lParam)/WIDTH >= RANGE ) ?
          RANGE - 1 :
          LOWORD(lParam) / WIDTH;

      /* update display if different */
      if ( wNewChoice != CHOICE ) {

        /* retrieve display context */
        hDC = GetDC ( hWnd );

        /* unmark old selection & mark new one */
        DrawSelector( hWnd, hDC );
        SET_CHOICE( wNewChoice );
        DrawSelector( hWnd, hDC );

        /* release display context & move caret */
        ReleaseDC( hWnd, hDC );
        SetCaretPos( CARET_XPOS, CARET_YPOS );

        /* notify parent of new selection */
        lprgbEntry = (LONG FAR *)GlobalLock( TABLE );
        SendMessage(PARENT,WM_COMMAND,ID,lprgbEntry[RANGE+CHOICE]);
        GlobalUnlock( TABLE );

      }

    }

    break;
  case WM_LBUTTONUP : /* left button released */

    /* release capture if active */
    if ( CAPTURE ) {
      SET_CAPTURE( FALSE );
      ReleaseCapture();
    }

    break;
  case WM_KILLFOCUS : /* kill focus - hide caret */
    DestroyCaret();
    break;
  case RM_SETSEL : /* select a color entry */
    {
      LONG FAR *    lprgbEntry;

      /* update selection & redraw rainbow */
      SET_CHOICE( (wParam >= RANGE) ? 0 : wParam );
      InvalidateRect( hWnd, NULL, TRUE );

      /* notify parent of change in color */
      lprgbEntry = (LONG FAR *)GlobalLock( TABLE );
      SendMessage( PARENT, WM_COMMAND, ID, lprgbEntry[RANGE+CHOICE] );
      GlobalUnlock( TABLE );

      /* return new choice */
      lResult = CHOICE;

    }
    break;
  case RM_GETSEL : /* retrieve selected color */
    {
      LONG FAR *    lprgbEntry;

      /* return selected entry */
      lResult = CHOICE;

      /* define selected color */
      lprgbEntry = (LONG FAR *)GlobalLock( TABLE );
      *(LONG FAR *)lParam = lprgbEntry[RANGE+CHOICE];
      GlobalUnlock( TABLE );

    }
    break;
  case RM_SETCOLORS : /* define rainbow color table */
    {
      WORD      wEntry;
      HANDLE    hrgbList;
      RECT      rectClient;
      LONG FAR *  lprgbEntry;

      /* release previous table from memory */
      GlobalFree( TABLE );

      hrgbList = GlobalAlloc(  GMEM_MOVEABLE,  sizeof(LONG)*wParam*2L);
      if ( hrgbList ) {

        /* define initial rgb colors & values */
        lprgbEntry = (LONG FAR *)GlobalLock( hrgbList );
        for ( wEntry=0; wEntry < wParam; wEntry++ ) {
          lprgbEntry[wEntry] = ((LONG FAR*)lParam)[wEntry];
          lprgbEntry[wParam+wEntry] = ((LONG FAR*)lParam)[wParam+wEntry];
        }
        GlobalUnlock( hrgbList );

        /* retrieve current window dimensions */
        GetClientRect( hWnd, &rectClient );

        /* re-define instance variables */
        SET_RANGE( wParam );
        SET_TABLE( hrgbList );
        SET_WIDTH( (rectClient.right-rectClient.left)/wParam );
        SET_HEIGHT( rectClient.bottom-rectClient.top );
        SET_CHOICE( 0 );

        /* update window & notify parent of new selection */
        InvalidateRect( hWnd, NULL, TRUE );
        SendMessage( PARENT, WM_COMMAND, ID, lprgbEntry[RANGE+CHOICE] );

        /* normal return */
        lResult = wParam;

      } else
        lResult = -1L;

    }
    break;
  case RM_GETCOLORS : /* retrieve rainbow color table */
    {
      WORD      wEntry;
      LONG FAR *  lprgbEntry;

      /* retrieve number of colors */
      lResult = RANGE;

      /* retrieve rgb color list */
      lprgbEntry = (LONG FAR *)GlobalLock( TABLE );
      for ( wEntry=0; (wEntry < RANGE)&&(wEntry < wParam); wEntry++ ) {
        ((LONG FAR *)lParam)[wEntry] = lprgbEntry[wEntry];
        ((LONG FAR *)lParam)[RANGE+wEntry] = lprgbEntry[RANGE+wEntry];
      }
      GlobalUnlock( TABLE );

    }
    break;
  case WM_DESTROY : /* window being destroyed */
    GlobalFree( TABLE );
    break;
  default : /* default window message processing */
    lResult = DefWindowProc( hWnd, wMsg, wParam, lParam );
    break;
  }

  /* return final result */
  return( lResult );

}

/*♀*/

/*
 * RainbowDlgFn( hDlg, wMessage, wParam, lParam ) : BOOL;
 *
 *    hDlg           dialog box handle
 *    wMessage       current window message
 *    wParam         word parameter
 *    lParam         long parameter
 *
 * This function is responsible for processing all the messages that
 * relate to the style dialog box.  This function transfers data
 * between itself and the RainbowStyle using a global data handle.
 *
 * If the user presses the OK button, this data handle is used to pass
 * back a new style data block.  It is left to the calling routine to
 * delete this new block.
 *
 */

BOOL FAR PASCAL RainbowDlgFn(
  HWND        hDlg,
  WORD        wMessage,
  WORD        wParam,
  LONG        lParam )
{
  BOOL      bResult;

  /* initialization */
  bResult = TRUE;

  /* process message */
  switch( wMessage )
    {
  case WM_INITDIALOG :
    {
      HANDLE    hCtlStyle;
      LPCTLSTYLE  lpCtlStyle;
      char      szId[  20 ];  /* temp. string to hold id */

      /* disable Ok button & save dialog data handle */
      hCtlStyle = hLibData;
      EnableWindow( GetDlgItem(hDlg,IDOK), FALSE );

      /* retrieve & display style parameters */
      if ( hCtlStyle ) {

        /* add handle to property list */
        SetProp( hDlg, MAKEINTRESOURCE(1), hCtlStyle );

        /* update dialog box fields */
        lpCtlStyle = (LPCTLSTYLE)GlobalLock( hCtlStyle );
        SetDlgItemText( hDlg, IDTEXT, lpCtlStyle->szTitle );

        /* Kanhom Ng 2/7/89
         * Set the id value string correctly.
         * Save the pointer to the verify id function from dialog editor
         */
        if ( lpfnIdStr )
        {
          (*lpfnIdStr)(lpCtlStyle->wId, (LPSTR)szId, sizeof( szId ) );
          SetDlgItemText( hDlg, IDVALUE, szId );
        }
        else
        {
          EnableWindow( GetDlgItem( hDlg, IDVALUE ), FALSE );
        }
        lstrcpy( lpCtlStyle->szClass, RAINBOWCLASS );
        SetProp( hDlg, IDFNHI, HIWORD( (DWORD)lpfnVerId ) );
        SetProp( hDlg, IDFNLO, LOWORD( (DWORD)lpfnVerId ) );

        GlobalUnlock( hCtlStyle );

      } else
        EndDialog( hDlg, FALSE );

    }
    break;
  case WM_COMMAND :

    /* process sub-message */
    switch( wParam )
      {
    case IDCANCEL : /* cancel dialog box */
      RemoveProp( hDlg, MAKEINTRESOURCE(1) );
      RemoveProp( hDlg, IDFNLO );
      RemoveProp( hDlg, IDFNHI );
      EndDialog( hDlg, FALSE );
      break;
    case IDOK : /* save dialog changes */
      {
        HANDLE    hCtlStyle;
        LPCTLSTYLE  lpCtlStyle;
        LPFNSTRTOID    lpfnId;      /* pointer to the verify id function from
        char      szId[ 20 ];    /* temp. string to hold the id */

        hCtlStyle = GetProp( hDlg, MAKEINTRESOURCE(1) );

        /* update structure contents */
        lpCtlStyle = (LPCTLSTYLE)GlobalLock( hCtlStyle );

        szId[ 0 ] = NULL;
        GetDlgItemText( hDlg, IDVALUE, szId, sizeof(szId) );
        lpfnId = (LPFNSTRTOID)MAKELONG( GetProp( hDlg, IDFNLO ), GetProp( hDl
        if ( lpfnId )
        {
          DWORD    dwResult; /* result ofthe verifyId function */

          dwResult = (*lpfnId)( (LPSTR)szId );
          if ( !(BOOL)dwResult )
          {
            /* Wrong id */
            GlobalUnlock( hCtlStyle );
            break;
          }

          lpCtlStyle->wId = HIWORD( dwResult );
        }

        GetDlgItemText( hDlg, IDTEXT, lpCtlStyle->szTitle, sizeof(lpCtlStyle-
        GlobalUnlock( hCtlStyle );

        RemoveProp( hDlg, MAKEINTRESOURCE(1) );
        RemoveProp( hDlg, IDFNLO );
        RemoveProp( hDlg, IDFNHI );

        /* end dialog box */
        hLibData = hCtlStyle;
        EndDialog( hDlg, TRUE );

      }
      break;
    case IDTEXT : /* control text */
    case IDVALUE : /* control id */

      /* enable or disable Ok button */
      if ( HIWORD(lParam) == EN_CHANGE )
        EnableWindow(
          GetDlgItem(hDlg,IDOK),
          (SendMessage(GetDlgItem(hDlg,IDTEXT),WM_GETTEXTLENGTH,0,0L) &&
           SendMessage(GetDlgItem(hDlg,IDVALUE),WM_GETTEXTLENGTH,0,0L)) ? TRU
        );

      break;
    default : /* something else */
      bResult = FALSE;
      break;
    }

    break;
  default :
    bResult = FALSE;
    break;
  }

  /* return final result */
  return( bResult );

}

/*♀*/

/*
 * DrawSelector( hWnd, hDC ) : void;
 *
 *    hWnd      window handle
 *    hDC      handle to display context
 *
 *  This function is responsible for drawing the selector
 * which surrounds the active color patch.  This drawing
 * process involves the use of the R2_NOT operator to
 * simplify the drawing & re-drawing process.
 *
 */

void static DrawSelector( hWnd, hDC )
  HWND      hWnd;
  HDC      hDC;
{
  /* local variables */
  HANDLE    hOldPen;          /* old pen */
  WORD      wOldROP2;        /* old raster op code */
  WORD      wOldBkMode;        /* old background mode */

  /* setup display context */
  wOldROP2 = SetROP2( hDC, R2_NOT );
  wOldBkMode = SetBkMode( hDC, TRANSPARENT );

  hOldPen = SelectObject( hDC, CreatePen(0,1,RGB(0,0,0)) );

  /* draw selector rectangle */
  Rectangle(
    hDC,
    SELECTOR_XPOS,
    SELECTOR_YPOS,
    SELECTOR_XPOS+SELECTOR_WIDTH,
    SELECTOR_YPOS+SELECTOR_HEIGHT
  );

  DeleteObject( SelectObject(hDC,hOldPen) );

  /* restore display context */
  SetBkMode( hDC, wOldBkMode );
  SetROP2( hDC, wOldROP2 );

}


SELECT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SELECT\SELECT.C

/****************************************************************************

    PROGRAM: Select.c

    PURPOSE: Contains library routines for selecting a region

    FUNCTIONS:

  StartSelection(HWND, POINT, LPRECT, int) - begin selection area
  UpdateSelection(HWND, POINT, LPRECT, int) - update selection area
  EndSelection(POINT, LPRECT) - end selection area
  ClearSelection(HWND, LPRECT, int) - clear selection area

*****************************************************************************

#include "windows.h"
#include "select.h"

/****************************************************************************
   FUNCTION: LibMain(HANDLE, WORD, WORD, LPSTR)

   PURPOSE:  Is called by LibEntry.  LibEntry is called by Windows when
             the DLL is loaded.  The LibEntry routine is provided in
             the LIBENTRY.OBJ in the SDK Link Libraries disk.  (The
             source LIBENTRY.ASM is also provided.)

             LibEntry initializes the DLL's heap, if a HEAPSIZE value is
             specified in the DLL's DEF file.  Then LibEntry calls
             LibMain.  The LibMain function below satisfies that call.

             The LibMain function should perform additional initialization
             tasks required by the DLL.  In this example, no initialization
             tasks are required.  LibMain should return a value of 1 if
             the initialization is successful.

*****************************************************************************
int FAR PASCAL LibMain(hModule, wDataSeg, cbHeapSize, lpszCmdLine)
HANDLE  hModule;
WORD    wDataSeg;
WORD    cbHeapSize;
LPSTR   lpszCmdLine;
{
    return 1;
}


/****************************************************************************
    FUNCTION:  WEP(int)

    PURPOSE:  Performs cleanup tasks when the DLL is unloaded.  WEP() is
              called automatically by Windows when the DLL is unloaded (no
              remaining tasks still have the DLL loaded).  It is strongly
              recommended that a DLL have a WEP() function, even if it does
              nothing but returns success (1), as in this example.

*****************************************************************************
int FAR PASCAL WEP (bSystemExit)
int  bSystemExit;
{
    return(1);
}


/****************************************************************************

    FUNCTION: StartSelection(HWND, POINT, LPRECT, int)

    PURPOSE: Begin selection of region

****************************************************************************/

int FAR PASCAL StartSelection(hWnd, ptCurrent, lpSelectRect, fFlags)
HWND hWnd;
POINT ptCurrent;
LPRECT lpSelectRect;
int fFlags;
{
    if (lpSelectRect->left != lpSelectRect->right ||
      lpSelectRect->top != lpSelectRect->bottom)
  ClearSelection(hWnd, lpSelectRect, fFlags);

    lpSelectRect->right = ptCurrent.x;
    lpSelectRect->bottom = ptCurrent.y;

    /* If you are extending the box, then invert the current rectangle */

    if ((fFlags & SL_SPECIAL) == SL_EXTEND)
  ClearSelection(hWnd, lpSelectRect, fFlags);

    /* Otherwise, set origin to current location */

    else {
  lpSelectRect->left = ptCurrent.x;
  lpSelectRect->top = ptCurrent.y;
    }
    SetCapture(hWnd);
}

/****************************************************************************

    FUNCTION: UpdateSelection(HWND, POINT, LPRECT, int) - update selection ar

    PURPOSE: Update selection

****************************************************************************/

int FAR PASCAL UpdateSelection(hWnd, ptCurrent, lpSelectRect, fFlags)
HWND hWnd;
POINT ptCurrent;
LPRECT lpSelectRect;
int fFlags;
{
    HDC hDC;
    short OldROP;

    hDC = GetDC(hWnd);

    switch (fFlags & SL_TYPE) {

  case SL_BOX:
      OldROP = SetROP2(hDC, R2_NOTXORPEN);
      MoveTo(hDC, lpSelectRect->left, lpSelectRect->top);
      LineTo(hDC, lpSelectRect->right, lpSelectRect->top);
      LineTo(hDC, lpSelectRect->right, lpSelectRect->bottom);
      LineTo(hDC, lpSelectRect->left, lpSelectRect->bottom);
      LineTo(hDC, lpSelectRect->left, lpSelectRect->top);
      LineTo(hDC, ptCurrent.x, lpSelectRect->top);
      LineTo(hDC, ptCurrent.x, ptCurrent.y);
      LineTo(hDC, lpSelectRect->left, ptCurrent.y);
      LineTo(hDC, lpSelectRect->left, lpSelectRect->top);
      SetROP2(hDC, OldROP);
      break;

  case SL_BLOCK:
      PatBlt(hDC,
    lpSelectRect->left,
    lpSelectRect->bottom,
    lpSelectRect->right - lpSelectRect->left,
    ptCurrent.y - lpSelectRect->bottom,
    DSTINVERT);
      PatBlt(hDC,
    lpSelectRect->right,
    lpSelectRect->top,
    ptCurrent.x - lpSelectRect->right,
    ptCurrent.y - lpSelectRect->top,
    DSTINVERT);
      break;
    }
    lpSelectRect->right = ptCurrent.x;
    lpSelectRect->bottom = ptCurrent.y;
    ReleaseDC(hWnd, hDC);
}

/****************************************************************************

    FUNCTION: EndSelection(POINT, LPRECT)

    PURPOSE: End selection of region, release capture of mouse movement

****************************************************************************/

int FAR PASCAL EndSelection(ptCurrent, lpSelectRect)
POINT ptCurrent;
LPRECT lpSelectRect;
{
    lpSelectRect->right = ptCurrent.x;
    lpSelectRect->bottom = ptCurrent.y;
    ReleaseCapture();
}

/****************************************************************************

    FUNCTION: ClearSelection(HWND, LPRECT, int) - clear selection area

    PURPOSE: Clear the current selection

****************************************************************************/

int FAR PASCAL ClearSelection(hWnd, lpSelectRect, fFlags)
HWND hWnd;
LPRECT lpSelectRect;
int fFlags;
{
    HDC hDC;
    short OldROP;

    hDC = GetDC(hWnd);
    switch (fFlags & SL_TYPE) {

  case SL_BOX:
      OldROP = SetROP2(hDC, R2_NOTXORPEN);
      MoveTo(hDC, lpSelectRect->left, lpSelectRect->top);
      LineTo(hDC, lpSelectRect->right, lpSelectRect->top);
      LineTo(hDC, lpSelectRect->right, lpSelectRect->bottom);
      LineTo(hDC, lpSelectRect->left, lpSelectRect->bottom);
      LineTo(hDC, lpSelectRect->left, lpSelectRect->top);
      SetROP2(hDC, OldROP);
      break;

  case SL_BLOCK:
      PatBlt(hDC,
    lpSelectRect->left,
    lpSelectRect->top,
    lpSelectRect->right - lpSelectRect->left,
    lpSelectRect->bottom - lpSelectRect->top,
    DSTINVERT);
      break;
    }
    ReleaseDC(hWnd, hDC);
}


SERVDATA.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\DDE\SERVDATA.C

/****************************************************************************

    MODULE: SERVDATA.C

    PURPOSE: Maintains conversation information.


****************************************************************************/

#include "windows.h"

#include "dde.h"
#include "server.h"
#include <string.h>

typedef struct CONV
{
    HWND hwndServerDDE;
    HWND hwndClientDDE;
    BOOL bInClientRequestedTerminate;
};

typedef struct ADVISE
{
    HWND  hwndServerDDE;
    HWND  hwndClientDDE;
    int         nItem;
    ATOM        atomItem;
    BOOL        bAckRequest;
    BOOL        bDeferUpdate;
    BOOL        bAwaitingAck;
    HANDLE      hData;
};

struct CONV Conv[CONV_MAX_COUNT];
static int nConvCount = 0;
static struct ADVISE Advise[ADVISE_MAX_COUNT];
static int nAdviseCount = 0;

struct ADVISE * NEAR FindAdvise(HWND, int);
struct CONV *  NEAR FindConv(HWND);


/****************************************************************************

    FUNCTION: AddAdvise

    PURPOSE:  Register a new hot or warm link to a specified client, for
        a specified server application item (1, 2, or 3).

****************************************************************************/
BOOL AddAdvise(hwndServerDDE, hDDEAdviseOptions, atomItem, nItem)
    HWND   hwndServerDDE;
    HANDLE hDDEAdviseOptions;
    ATOM   atomItem;
    int    nItem;
{
    struct ADVISE     * pAdvise;
    DDEADVISE FAR     * lpDDEAdviseOptions;
    int     nAdviseIndex;

    if (nAdviseCount >= ADVISE_MAX_COUNT)
    {
  MessageBox(hwndMain,
            "Maximum advisories exceeded",
            "Server",
            MB_ICONEXCLAMATION | MB_OK);
        return (FALSE);
    }
    if ((lpDDEAdviseOptions
          = (DDEADVISE FAR *)GlobalLock(hDDEAdviseOptions)) == NULL)
        return (FALSE);

    for (pAdvise = Advise, nAdviseIndex = 0;
   nAdviseIndex < nAdviseCount;
   pAdvise++, nAdviseIndex++)
    {
  if (pAdvise->hwndServerDDE == hwndServerDDE
      && pAdvise->nItem == nItem)
  {
      MessageBox(hwndMain,
    "Advisory (paste link) already established",
    "Server",
    MB_ICONEXCLAMATION | MB_OK);
      GlobalUnlock(hDDEAdviseOptions);
      return (FALSE);
  }
    }

    pAdvise = Advise + nAdviseCount++;

    pAdvise->hwndServerDDE = hwndServerDDE;
    pAdvise->hwndClientDDE = GetHwndClientDDE(hwndServerDDE);
    pAdvise->nItem = nItem;
    pAdvise->atomItem = atomItem;
    pAdvise->bAckRequest = lpDDEAdviseOptions->fAckReq;
    pAdvise->bDeferUpdate = lpDDEAdviseOptions->fDeferUpd;
    pAdvise->bAwaitingAck = FALSE;

    GlobalUnlock(hDDEAdviseOptions);
    return (TRUE);
}



/****************************************************************************

    FUNCTION: AddConv

    PURPOSE:  Register a new conversation with a client window

****************************************************************************/
BOOL AddConv(hwndServerDDE, hwndClientDDE)
    HWND  hwndServerDDE;
    HWND  hwndClientDDE;
{
    struct CONV * pConv;

    if (nConvCount >= CONV_MAX_COUNT)
    {
        return (FALSE);
    }

    if (FindConv(hwndServerDDE) != NULL)
    {
  return (FALSE); /* conversation already added */
    }

    pConv = Conv + nConvCount++;
    pConv->hwndServerDDE = hwndServerDDE;
    pConv->hwndClientDDE = hwndClientDDE;
    pConv->bInClientRequestedTerminate = FALSE;
    return (TRUE);
}



/***********************************************************************

    FUNCTION:  AtLeastOneConvActive

    PURPOSE:   Used during termination of application, to
         determine whether any conversations are still active
         while the conversations are being terminated.

***********************************************************************/
BOOL AtLeastOneConvActive()
{
    return (nConvCount? TRUE: FALSE);
}



/****************************************************************************

    FUNCTION: CheckOutSentData

    PURPOSE:  Set Awaiting Ack state to true for specified item.

****************************************************************************/
void CheckOutSentData(hwndServerDDE, nItem, atomItem, hData)
    HWND    hwndServerDDE;
    int     nItem;
    ATOM    atomItem;
    HANDLE  hData;
{
    struct ADVISE * pAdvise;

    if (!(pAdvise = FindAdvise(hwndServerDDE, nItem)))
        return;
    pAdvise->bAwaitingAck = TRUE;
    pAdvise->atomItem = atomItem;
    pAdvise->hData = hData;
    return;
}



/****************************************************************************

    FUNCTION: DoEditCopy

    PURPOSE:  Copy selected data to clipboard in two formats:
        CF_TEXT and (registered) "Link" format.

****************************************************************************/
void DoEditCopy(nItem)
    int   nItem;
{

    /* Format string and set clipboard data here */
    HANDLE  hTextData;
    HANDLE  hConvData;
    char  szItemValue[ITEM_VALUE_MAX_SIZE+1];
    LPSTR  lpTextData, lpConvData;

    if (!GetDlgItemText(hwndMain, nItem, szItemValue, ITEM_VALUE_MAX_SIZE))
  strcpy(szItemValue, " ");

    /* Copy item value in CF_TEXT format to global memory object */

    if (!(hTextData
    = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD)lstrlen(szItemValue)+1))
  return;
    if (!(lpTextData = GlobalLock(hTextData)))
    {
  GlobalFree(hTextData);
  return;
    }
    lstrcpy(lpTextData, szItemValue);
    GlobalUnlock(hTextData);

    /* Copy item value in "Link" format to global memory object */

    if (!(hConvData
    = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
      (DWORD)APP_MAX_SIZE+TOPIC_MAX_SIZE+ITEM_NAME_MAX_SIZE+4)))
       return;
    if (!(lpConvData = GlobalLock(hConvData)))
    {
       GlobalFree(hConvData);
       return;
    }

    /* Compose paste link string, each sub-string is null terminated */
    /* Format is <app> <null> <topic> <null> <item> <null> <null>    */
    lstrcpy(lpConvData, "Server");
    lpConvData = lpConvData + lstrlen(lpConvData) + 1;  /* '+1' adds null */
    lstrcpy(lpConvData, szDocName);   /* topic */
    lpConvData += (lstrlen(lpConvData) + 1);
    lstrcpy(lpConvData, "item#");
    lpConvData[4] = '1' + nItem - 1;
    *(lpConvData + lstrlen(lpConvData) + 1) = 0;  /* final null */

    GlobalUnlock(hConvData);

    if (OpenClipboard(hwndMain))
    {
       EmptyClipboard();

       SetClipboardData(CF_TEXT, hTextData);
       SetClipboardData(cfLink, hConvData);

       CloseClipboard();
    }
    else
    {
       GlobalFree(hTextData);
       GlobalFree(hConvData);
    }

    return;
}



/****************************************************************************

    FUNCTION: FindAdvise

    PURPOSE:  Find advisory data for a specific conversation item.

****************************************************************************/
struct ADVISE * NEAR FindAdvise(hwndServerDDE, nItem)
    HWND hwndServerDDE;
    int  nItem;
{
    struct ADVISE * pAdvise;
    int             nAdviseIndex;

    for (nAdviseIndex = 0, pAdvise = Advise;
         nAdviseIndex < nAdviseCount;
         nAdviseIndex++, pAdvise++)
    {
  if (pAdvise->hwndServerDDE == hwndServerDDE
            && pAdvise->nItem == nItem)
        {
            return (pAdvise);
        }
    }
    return (NULL);
}





/****************************************************************************

    FUNCTION: FindConv

    PURPOSE:  Find the conversation for a specified server DDE window.

****************************************************************************/
struct CONV * NEAR FindConv(hwndServerDDE)
    HWND  hwndServerDDE;
{
    struct CONV * pConv;
    int     nConvIndex;

    for (nConvIndex = 0, pConv = Conv;
   nConvIndex < nConvCount;
   nConvIndex++, pConv++)
    {
  if (pConv->hwndServerDDE == hwndServerDDE)
      return (pConv);
    }
    return (NULL);
}



/****************************************************************************

    FUNCTION: GetAdviseData

    PURPOSE:  Get advisory data for a specified conversation item.

****************************************************************************/
BOOL GetAdviseData(hwndServerDDE, nItem, szItemName, szItemValue,
                   pbDeferUpdate, pbAckRequest)
    HWND   hwndServerDDE;
    int    nItem;
    char * szItemName;
    char * szItemValue;
    BOOL * pbDeferUpdate;
    BOOL * pbAckRequest;
{
    struct ADVISE * pAdvise;

    if (!(pAdvise = FindAdvise(hwndServerDDE, nItem)))
        return (FALSE);
    strcpy(szItemName, "Item#");
    szItemName[4] = pAdvise->nItem==1? '1': pAdvise->nItem==2? '2': '3';
    *pbDeferUpdate = pAdvise->bDeferUpdate;
    *pbAckRequest = pAdvise->bAckRequest;
    if (!GetDlgItemText(hwndMain, nItem, szItemValue, ITEM_VALUE_MAX_SIZE))
        strcpy(szItemValue," ");

    return (TRUE);
}



/****************************************************************************

    FUNCTION: GetHwndClientDDE

    PURPOSE:  Get the hwnd of the client in conversation with a specified
        server DDE window.

****************************************************************************/
HWND GetHwndClientDDE(hwndServerDDE)
    HWND  hwndServerDDE;
{
    struct CONV * pConv;

    if (!(pConv = FindConv(hwndServerDDE)))
  return (NULL);
    return (pConv->hwndClientDDE);
}



/****************************************************************************

    FUNCTION: GetNextAdvise

    PURPOSE:  Find a client that needs to be notified that a value of
        a specified item (a hot or warm link item) has changed.
        Since a hot or warm link to the item may have been established
        for multiple conversations (multiple clients), this function
        is set up to step through the list of such conversations.
        Start the list by passing a NULL hwndClientDDE.  To get the
        next conversation in the list, pass the previous client returned
        by this function.

****************************************************************************/
HWND GetNextAdvise(hwndServerDDE, nItem)
    HWND hwndServerDDE;
    int  nItem;
{
    struct ADVISE * pAdvise;
    int             nAdviseIndex;

    if (hwndServerDDE)
    {
        for (nAdviseIndex = 0, pAdvise = Advise;
             nAdviseIndex < nAdviseCount;
             nAdviseIndex++, pAdvise++)
        {
      if (pAdvise->hwndServerDDE == hwndServerDDE
                && pAdvise->nItem == nItem)
            {
                pAdvise++;
                break;
            }
        }
        if (nAdviseIndex >= nAdviseCount)
            return (NULL);
    }
    else
    {
        pAdvise = Advise;
        nAdviseIndex = 0;
    }
    for ( ; nAdviseIndex < nAdviseCount; nAdviseIndex++, pAdvise++)
    {
        if (pAdvise->nItem == nItem)
        {
      return (pAdvise->hwndServerDDE);
        }
    }
    return (NULL);
}



/****************************************************************************

    FUNCTION: GetNextConv

    PURPOSE:  Get next client in list of conversations.  To get the
        first hwndServerDDE in the conversation list, pass in a NULL
        value for hwndServerDDE.

****************************************************************************/
HWND GetNextConv(hwndServerDDE)
    HWND hwndServerDDE;
{
    struct CONV * pConv;
    int     nConvIndex;

    if (hwndServerDDE)
    {
  for (nConvIndex = 0, pConv = Conv;
       nConvIndex < nConvCount;
       nConvIndex++, pConv++)
        {
      if (pConv->hwndServerDDE == hwndServerDDE)
            {
    if (++nConvIndex < nConvCount)
        return (++pConv)->hwndServerDDE;
                else
                    return (NULL);
            }
        }
        return (NULL);
    }
    if (nConvCount > 0)
  return (Conv[0].hwndServerDDE);
    else
        return (NULL);
}



/****************************************************************************

    FUNCTION: GlobalFreeSentData

    PURPOSE:  A global memory object (hData) was sent in a WM_DDE_DATA
        message, but the client never used it.  So, the server is
        responsible for freeing the object.

****************************************************************************/
void GlobalFreeSentData(hwndServerDDE, nItem)
    HWND  hwndServerDDE;
    int   nItem;
{
    struct ADVISE * pAdvise;

    if (!(pAdvise = FindAdvise(hwndServerDDE, nItem)))
        return;
    pAdvise->bAwaitingAck = FALSE;
    GlobalDeleteAtom(pAdvise->atomItem);
    GlobalFree(pAdvise->hData);
    return;
}



/****************************************************************************

    FUNCTION: IsConvInTerminateState

    PURPOSE:  Terminate whether conversation with specified client is
        in process of being terminated.

****************************************************************************/
BOOL IsConvInTerminateState(hwndServerDDE)
    HWND  hwndServerDDE;
{
    struct CONV * pConv;

    if (pConv = FindConv(hwndServerDDE))
  return (pConv->bInClientRequestedTerminate);
    else
        return (FALSE);
}


/****************************************************************************

    FUNCTION: RemoveAdvise

    PURPOSE:  Cancel a hot or warm link for a specified conversation item.
        If a 0 value is specified for nItem, then all hot/warm links
              for the specified client are removed.

****************************************************************************/
BOOL RemoveAdvise(hwndServerDDE, nItem)
    HWND  hwndServerDDE;
    int   nItem;
{
    struct ADVISE * pAdvise;
    int             nAdviseIndex;
    int             nRemoveCount;

    nRemoveCount = 0;
    for (nAdviseIndex = 0, pAdvise = Advise;
         nAdviseIndex < nAdviseCount;
         nAdviseIndex++, pAdvise++)
    {
        if (nRemoveCount)
        {
            *(pAdvise-nRemoveCount) = *pAdvise;
        }
  if (pAdvise->hwndServerDDE == hwndServerDDE
            && (!nItem || pAdvise->nItem == nItem))
        {
            nRemoveCount++;
        }

    }
    if (nRemoveCount)
    {
        nAdviseCount -= nRemoveCount;
        return (TRUE);
    }
    else
    {
        return (FALSE);
    }
}



/****************************************************************************

    FUNCTION: RemoveConv

    PURPOSE:  Remove conversation from conversation list, and remove
        all hot/warm links associated with that conversation
        from the advisory list.

****************************************************************************/
void RemoveConv(hwndServerDDE)
    HWND hwndServerDDE;
{
    struct CONV   * pConv;
    int       nConvIndex;
    struct ADVISE * pAdvise;
    struct ADVISE * pAdviseShift;
    int             nAdviseIndex;
    int             nAdviseDecrement;

    for (nConvIndex = 0, pConv = Conv;
   nConvIndex < nConvCount;
   nConvIndex++, pConv++)
    {
  if (pConv->hwndServerDDE == hwndServerDDE)
            break;
    }
    nConvCount--;
    while (nConvIndex < nConvCount)
    {
  *pConv = *(pConv+1);
  nConvIndex++;
  pConv++;
    }

    /* Remove each hot/warm link */

    pAdviseShift = Advise;
    nAdviseDecrement = 0;
    for (nAdviseIndex = 0, pAdvise = Advise;
         nAdviseIndex < nAdviseCount;
         nAdviseIndex++, pAdvise++)
    {
  if (pAdvise->hwndServerDDE == hwndServerDDE)
        {
            nAdviseDecrement++;
            if (pAdvise->bAwaitingAck)
            { /* Destroy objects perhaps not destroyed by client */
    GlobalDeleteAtom(pAdvise->atomItem);
                GlobalFree(pAdvise->hData);
            }
        }
        else
        {
            *(pAdviseShift++) = *pAdvise;
        }
    }
    nAdviseCount -= nAdviseDecrement;
    return;
}



/****************************************************************************

    FUNCTION: SetConvInTerminateState

    PURPOSE:  Set conversations's terminate state to TRUE.

****************************************************************************/
void SetConvInTerminateState(hwndServerDDE)
    HWND  hwndServerDDE;
{
    struct CONV * pConv;

    if (pConv = FindConv(hwndServerDDE))
  pConv->bInClientRequestedTerminate = TRUE;
    return;
}


SERVDDE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\DDE\SERVDDE.C

/****************************************************************************

    MODULE: SERVDDE.C

    PURPOSE: Processes incoming and outgoing DDE messages


****************************************************************************/

#include "windows.h"

#include "dde.h"
#include "server.h"
#include <string.h>

#define DEFAULT_ACK_TIME_OUT_MILLISEC 10000
static int nAckTimeOut;

static BOOL   bTerminating = FALSE;

int  NEAR GetDocIndexGivenName(char*);
int  NEAR GetItemNumber(char*);




/****************************************************************************

    FUNCTION: DDEWndProc

    PURPOSE:  Handles all DDE messages received by the server application.

****************************************************************************/
long FAR PASCAL DDEWndProc(hwnd, message, wParam, lParam)
    HWND      hwnd;
    unsigned  message;
    WORD      wParam;
    LONG      lParam;
{
    switch (message)
    {

        case WM_DDE_ACK:
            ServerAcknowledge(hwnd, (HWND)wParam, lParam);
      return (0L);

  case WM_TIMER:   /* time out on waiting for ACK in response */
       /* to WM_DDE_DATA sent by this server      */

      ServerAcknowledge(hwnd, (HWND)wParam, 0L); /* simulates NACK */
      return (0L);

        case WM_DDE_ADVISE:
            ServerAdvise(hwnd, (HWND)wParam, lParam);
      return (0L);

        case WM_DDE_POKE:
            ServerPoke(hwnd, (HWND)wParam, lParam);
      return (0L);

        case WM_DDE_TERMINATE:
            ServerTerminate(hwnd, (HWND)wParam);
      return (0L);

        case WM_DDE_UNADVISE:
            ServerUnadvise(hwnd, (HWND)wParam, lParam);
      return (0L);

        case WM_DDE_REQUEST:
            ServerRequest(hwnd, (HWND)wParam, lParam);
      return (0L);

  case WM_DDE_EXECUTE:
      ServerExecute(hwnd, (HWND)wParam, (HANDLE)HIWORD(lParam));
      return (0L);

  default:
        return (DefWindowProc(hwnd, message, wParam, lParam));
    }
}



/****************************************************************************

    FUNCTION: GetItemNumber

    PURPOSE:  Get server control i.d. (1, 2, or 3) given item name.

****************************************************************************/
int NEAR GetItemNumber(szItem)
    char * szItem;
{
    int nItem;

    if (!strcmpi(szItem, "ITEM1"))
        nItem = 1;
    else if (!strcmpi(szItem, "ITEM2"))
        nItem = 2;
    else if (!strcmpi(szItem, "ITEM3"))
        nItem = 3;
    else
        nItem = 0;
    return (nItem);
}



/****************************************************************************

    FUNCTION: InitAckTimeOut

    PURPOSE:  Get DDE timeout value from win.ini.  Value is in milliseconds.

****************************************************************************/
void InitAckTimeOut(void)
{

   /* Finds value in win.ini section corresponding to application name */

   nAckTimeOut = GetPrivateProfileInt("Server",
             "DdeTimeOut",
             DEFAULT_ACK_TIME_OUT_MILLISEC,
                               "server.ini");
   return;
}



/****************************************************************************

    FUNCTION: SendData

    PURPOSE:  Send data to client.

****************************************************************************/
void SendData(hwndServerDDE, hwndClientDDE, szItemName, szItemValue,
                   bDeferUpdate, bAckRequest)
    HWND  hwndServerDDE;
    HWND  hwndClientDDE;
    char * szItemName;
    char * szItemValue;
    BOOL   bDeferUpdate;
    BOOL   bAckRequest;
{
    ATOM          atomItem;
    HANDLE        hData;
    DDEDATA FAR * lpData;
    int           nItem;

    if (bDeferUpdate)
    {
        atomItem = GlobalAddAtom((LPSTR)szItemName);
  /* notify client with null data since advise was set up for */
  /* deferred update              */
  if (!PostMessage(hwndClientDDE,
                WM_DDE_DATA,
    hwndServerDDE,
    MAKELONG(0, atomItem)))
        {
            GlobalDeleteAtom(atomItem);
        }
        return;
    }

    /* Allocate size of DDE data header, plus the data:  a string,  */
    /* <CR> <LR> <NULL>.  The byte for the string null terminator */
    /* is counted by DDEDATA.Value[1].           */

    if (!(hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,
            (LONG)sizeof(DDEDATA) +lstrlen(szItemValue) + 2)))
        return;
    if (!(lpData = (DDEDATA FAR*)GlobalLock(hData)))
    {
  GlobalFree(hData);
        return;
    }

    lpData->fAckReq = bAckRequest;
    lpData->cfFormat = CF_TEXT;
    lstrcpy((LPSTR)lpData->Value, (LPSTR)szItemValue);
    /* each line of CF_TEXT data is terminated by CR/LF */
    lstrcat((LPSTR)lpData->Value, (LPSTR)"\r\n");
    GlobalUnlock(hData);
    atomItem = GlobalAddAtom((LPSTR)szItemName);
    if (!PostMessage(hwndClientDDE,
            WM_DDE_DATA,
      hwndServerDDE,
            MAKELONG(hData, atomItem)))
    {
        GlobalFree(hData);
        GlobalDeleteAtom(atomItem);
  return;
    }
    if (bAckRequest)
    {
  SetTimer(hwndServerDDE, hwndClientDDE, nAckTimeOut, NULL);
  nItem = GetItemNumber(szItemName);
  /* hData is to be deleted if not read by client for some reason */
  CheckOutSentData(hwndServerDDE, nItem, atomItem, hData);
    }
    return;
}



/****************************************************************************

    FUNCTION: SendTerminate

    PURPOSE:  Post terminate message and indicate that conversation is
        in process ot being terminated.

****************************************************************************/
void SendTerminate(hwndServerDDE, hwndClientDDE)
    HWND  hwndServerDDE;
    HWND  hwndClientDDE;
{
    SetConvInTerminateState(hwndServerDDE);
    PostMessage(hwndClientDDE, WM_DDE_TERMINATE, hwndServerDDE, 0L);
    return;
}



/****************************************************************************

    FUNCTION: ServerAcknowledge

    PURPOSE:  Called when server application receives ACK or NACK, or
        when server receives time out waiting for response to
        WM_DDE_DATA.

****************************************************************************/
void ServerAcknowledge(hwndServerDDE, hwndClientDDE, lParam)
    HWND  hwndServerDDE;
    HWND  hwndClientDDE;
    LONG  lParam;
{
    char szItemName[ITEM_NAME_MAX_SIZE+1];
    int  nItem;

    KillTimer(hwndServerDDE, hwndClientDDE);

    if (!(LOWORD(lParam) & 0x8000))
    {
        GlobalGetAtomName(HIWORD(lParam), szItemName, ITEM_NAME_MAX_SIZE);
        nItem = GetItemNumber(szItemName);
  GlobalFreeSentData(hwndServerDDE, nItem);
  MessageBox(hwndMain,
            "DDE send data failed",
            "Server",
            MB_ICONEXCLAMATION | MB_OK);
    }
    if (HIWORD(lParam))    /* 0 if time-out, so don't try to delete */
  GlobalDeleteAtom(HIWORD(lParam));
    return;
}



/****************************************************************************

    FUNCTION: ServerAdvise

    PURPOSE:  Called when server application receives WM_DDE_ADVISE message.

****************************************************************************/
void ServerAdvise(hwndServerDDE, hwndClientDDE, lParam)
    HWND  hwndServerDDE;
    HWND  hwndClientDDE;
    LONG  lParam;
{
    HANDLE          hDDEAdviseOptions;
    DDEADVISE FAR * lpDDEAdviseOptions;
    ATOM            atomItem;
    char            szItem[ITEM_NAME_MAX_SIZE+1];
    int             nItem;

    hDDEAdviseOptions = LOWORD(lParam);
    atomItem = HIWORD(lParam);

    GlobalGetAtomName(atomItem, szItem, ITEM_NAME_MAX_SIZE);

    if (!(nItem = GetItemNumber(szItem))
  || !AddAdvise(hwndServerDDE, hDDEAdviseOptions, atomItem, nItem))
    {
  PostMessage(hwndClientDDE,
            WM_DDE_ACK,
      hwndServerDDE,
            MAKELONG(0, atomItem)); /* negative acknowledgement */
        return;
    }
    PostMessage(hwndClientDDE,
        WM_DDE_ACK,
  hwndServerDDE,
        MAKELONG(0x8000, atomItem)); /* positive acknowledgement */
    return;
}



/****************************************************************************

    FUNCTION: ServerExecute

    PURPOSE:  Called when server application receives WM_DDE_EXECUTE message.

****************************************************************************/
void ServerExecute(hwndServerDDE, hwndClientDDE, hCommand)
    HWND    hwndServerDDE;
    HWND    hwndClientDDE;
    HANDLE  hCommand;
{
    LPSTR   lpstrCommand;
    char    szExecuteString[EXECUTE_STRING_MAX_SIZE+1];

    if (!(lpstrCommand = GlobalLock(hCommand)))
    {
  PostMessage(hwndClientDDE,
            WM_DDE_ACK,
      hwndServerDDE,
      MAKELONG(0, hCommand)); /* negative acknowledgement */
        return;
    }
    if (lstrlen(lpstrCommand) > EXECUTE_STRING_MAX_SIZE)
  lpstrCommand[EXECUTE_STRING_MAX_SIZE] = 0;
    lstrcpy(szExecuteString, lpstrCommand);
    GlobalUnlock(hCommand);
    PostMessage(hwndClientDDE,
  WM_DDE_ACK,
  hwndServerDDE,
  MAKELONG(0x8000, hCommand)); /* positive acknowledgement */

    MessageBox(hwndMain,
  szExecuteString,
  "Server Received Execute Command",
  MB_OK);
    return;
}




/****************************************************************************

    FUNCTION: ServerInitiate

    PURPOSE:  Called when server application receives WM_DDE_INITIATE message

****************************************************************************/
void ServerInitiate(hwndClientDDE, lParam)
    HWND  hwndClientDDE;
    LONG  lParam;
{
    HWND  hwndServerDDE;
    ATOM  atomApplicationRcvd;
    ATOM  atomTopicRcvd;
    ATOM  atomApplicationReturn;
    ATOM  atomTopicReturn;
    char  szApplication[APP_MAX_SIZE+1];
    char  szTopic[TOPIC_MAX_SIZE+1];

    if (!(hwndServerDDE = CreateWindow(
      "ServerDDEWndClass",
      "ServerDDE",
      WS_CHILD,  /* not visible */
      0, 0, 0, 0, /* no position or dimensions */
      hwndMain,  /* parent */
      NULL,  /* no menu */
      hInst,
      NULL)))
    {
  return;
    }

    if (atomApplicationRcvd = LOWORD(lParam))
        GlobalGetAtomName(atomApplicationRcvd, szApplication, APP_MAX_SIZE);
    if (atomApplicationRcvd && strcmpi(szApplication,"SERVER"))
    { /* if application was specified but it wasn't "server" */
        return;
    }
    if (atomTopicRcvd = HIWORD(lParam))
    {
        GlobalGetAtomName(atomTopicRcvd, szTopic, TOPIC_MAX_SIZE);
        if (strcmpi(szTopic, szDocName))
            return;
    }
    if (AddConv(hwndServerDDE, hwndClientDDE))
    {
        atomApplicationReturn = GlobalAddAtom("SERVER");
        atomTopicReturn = GlobalAddAtom(szDocName);
  if (!SendMessage(hwndClientDDE,
                WM_DDE_ACK,
    hwndServerDDE,
                MAKELONG(atomApplicationReturn, atomTopicReturn)))
        {
            GlobalDeleteAtom(atomApplicationReturn);
            GlobalDeleteAtom(atomTopicReturn);
        }
    }
    return;
}



/****************************************************************************

    FUNCTION: ServerPoke

    PURPOSE:  Called when server application receives WM_DDE_POKE message.

****************************************************************************/
void ServerPoke(hwndServerDDE, hwndClientDDE, lParam)
    HWND  hwndServerDDE;
    HWND  hwndClientDDE;
    LONG  lParam;
{
    HANDLE        hPokeData;
    DDEPOKE FAR * lpPokeData;
    ATOM          atomItem;
    int           nItem;
    char          szItemName[ITEM_NAME_MAX_SIZE+1];
    char          szItemValue[ITEM_VALUE_MAX_SIZE+1];
    BOOL          bRelease;
    char        * pcCarriageReturn;


    hPokeData = LOWORD(lParam);
    atomItem = HIWORD(lParam);

    GlobalGetAtomName(atomItem, szItemName, ITEM_NAME_MAX_SIZE);
    if (!(lpPokeData = (DDEPOKE FAR *)GlobalLock(hPokeData))
        || lpPokeData->cfFormat != CF_TEXT
        || !(nItem = GetItemNumber(szItemName)))
    {
  PostMessage(hwndClientDDE,
           WM_DDE_ACK,
     hwndServerDDE,
           MAKELONG(0, atomItem)); /* negative acknowledgement */
  return;
    }

    lstrcpy(szItemValue, lpPokeData->Value);
    if (pcCarriageReturn = strchr(szItemValue, '\r'))
        *pcCarriageReturn = 0;  /* remove CR/LF */
    SetDlgItemText(hwndMain, nItem, szItemValue);
    MaybeAdviseData(nItem);

    /* Save value of fRelease, since pointer may be invalidated by */
    /*  GlobalUnlock()              */
    bRelease = lpPokeData->fRelease;
    GlobalUnlock(hPokeData);

    if (bRelease)
    {
        GlobalFree(hPokeData);
    }

    /* Since we are re-using the item atom, we should not delete it */
    /* if PostMessage fails:  the client should delete the atom     */
    /* when it gets a time-out on the expected ACK.        */
    PostMessage(hwndClientDDE,
  WM_DDE_ACK,
  hwndServerDDE,
  MAKELONG(0x8000, atomItem));  /* positive acknowledgement */
    return;
}



/****************************************************************************

    FUNCTION: ServerRequest

    PURPOSE:  Called when server application receives WM_DDE_REQUEST message.

****************************************************************************/
void ServerRequest(hwndServerDDE, hwndClientDDE, lParam)
    HWND  hwndServerDDE;
    HWND  hwndClientDDE;
    LONG  lParam;
{
    char szItem[ITEM_NAME_MAX_SIZE+1];
    char szItemValue[ITEM_VALUE_MAX_SIZE+1];
    int  nItem;

    GlobalGetAtomName(HIWORD(lParam), szItem, ITEM_NAME_MAX_SIZE);
    if (!(nItem = GetItemNumber(szItem))
  || (LOWORD(lParam) != CF_TEXT)) /* this app supports only CF_TEXT */
    {
  PostMessage(hwndClientDDE,
            WM_DDE_ACK,
      hwndServerDDE,
            MAKELONG(0, HIWORD(lParam))); /* NACK */
        return;
    }
    if (!GetDlgItemText(hwndMain, nItem, szItemValue, ITEM_VALUE_MAX_SIZE))
    {
  strcpy(szItemValue," ");
    }
    /* send now, don't defer, and don't ask for ACK */
    SendData(hwndServerDDE, hwndClientDDE, szItem, szItemValue, FALSE, FALSE)
    GlobalDeleteAtom(HIWORD(lParam));
    return;
}


/****************************************************************************

    FUNCTION: ServerTerminate

    PURPOSE:  Called when server application receives WM_DDE_TERMINATE messag

****************************************************************************/
void ServerTerminate(hwndServerDDE, hwndClientDDE)
    HWND  hwndServerDDE;
    HWND  hwndClientDDE;
{

    if (!IsConvInTerminateState(hwndClientDDE))
    { /* Client has requested terminate: respond with terminate */
  PostMessage(hwndClientDDE, WM_DDE_TERMINATE, hwndServerDDE, 0L);
    }

    RemoveConv(hwndServerDDE);
    DestroyWindow(hwndServerDDE);
    return;
}



/****************************************************************************

    FUNCTION: ServerUnadvise

    PURPOSE:  Called when server application receives WM_DDE_UNADIVSE message

****************************************************************************/
void ServerUnadvise(hwndServerDDE, hwndClientDDE, lParam)
    HWND  hwndServerDDE;
    HWND  hwndClientDDE;
    LONG  lParam;
{
    char szItem[ITEM_NAME_MAX_SIZE+1];
    int  nItem;
    BOOL bSuccess;

    if (HIWORD(lParam))
    {
        GlobalGetAtomName(HIWORD(lParam), szItem, ITEM_NAME_MAX_SIZE);
        nItem = GetItemNumber(szItem);
  bSuccess = RemoveAdvise(hwndServerDDE, nItem);
    }
    else
    {   /* HIWORD(lParam)==0 means remove all advises */
  bSuccess = RemoveAdvise(hwndServerDDE, 0);
    }
    if (bSuccess)
    {
  PostMessage(hwndClientDDE,
            WM_DDE_ACK,
      hwndServerDDE,
            MAKELONG(0x8000, HIWORD(lParam))); /* positive ack */
    }
    else
    {
  PostMessage(hwndClientDDE,
            WM_DDE_ACK,
      hwndServerDDE,
            MAKELONG(0, HIWORD(lParam))); /* negative ack */
    }
    return;
}

/****************************************************************************

    FUNCTION: TerminateConversations

    PURPOSE:  Processes WM_DESTROY message, terminates all conversations.

****************************************************************************/
void TerminateConversations()
{
   HWND  hwndServerDDE;
   LONG  lTimeOut;
   MSG   msg;


   /* Terminate each active conversation */
   hwndServerDDE = NULL;
   while (hwndServerDDE = GetNextConv(hwndServerDDE))
   {
  SendTerminate(hwndServerDDE, GetHwndClientDDE(hwndServerDDE));
   }

   /* Wait for all conversations to terminate OR for time out */
   lTimeOut = GetTickCount() + (LONG)nAckTimeOut;
   while (PeekMessage(&msg, NULL, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE))
   {
         DispatchMessage (&msg);
   if (msg.message == WM_DDE_TERMINATE)
   {
       if (!AtLeastOneConvActive())
     break;
   }
         if (GetTickCount() > lTimeOut)
             break;
   }

   return;
}


SERVER.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\DDE\SERVER.C

/***************************************************************************

    PROGRAM: SERVER

    PURPOSE: Illustrates server side of DDE conversation

    MODULES:

        SERVER.C    Window and dialog procedures.
  SERVDATA.C  Maintains conversation information.
        SERVDDE.C   Processes incoming and outgoing DDE messages.

****************************************************************************/

#include "windows.h"
#include "dde.h"
#include "server.h"
#include "servres.h"
#include <string.h>
#include <stdlib.h>



static int     xDelta;
static int     yDelta;

long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
BOOL InitApplication(HANDLE);
void InitAddedInstance(HANDLE, HANDLE);
BOOL InitInstance(HANDLE, int);
void MaybeAdviseData(int);
BOOL FAR PASCAL AboutDlgProc(HWND, unsigned, WORD, LONG);


/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE:  Calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    MSG msg;
    HANDLE hAccel;

    if (!hPrevInstance)
    {
  if (!InitApplication(hInstance))
      return (FALSE);
    }
    else
    {
        InitAddedInstance(hInstance, hPrevInstance);
    }

    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    hAccel = LoadAccelerators(hInstance, "ServerAcc");

    while (GetMessage(&msg, NULL, NULL, NULL))
    {
  if (!TranslateAccelerator(hwndMain, hAccel, &msg))
  {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
  }

    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: InitApplication(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    nDoc = 1;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "ServerMenu";
    wc.lpszClassName = "ServerWClass";

    if (!RegisterClass(&wc))
  return (FALSE);

    wc.style = NULL;
    wc.lpfnWndProc = DDEWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = NULL;
    wc.hCursor = NULL;
    wc.hbrBackground = NULL;
    wc.lpszMenuName =  NULL;
    wc.lpszClassName = "ServerDDEWndClass";

    return (RegisterClass(&wc));
}


/****************************************************************************

    FUNCTION: InitAddedInstance

    PURPOSE:  Increment document number

****************************************************************************/
void InitAddedInstance(hInstance, hPrevInstance)
    HANDLE  hInstance;
    HANDLE  hPrevInstance;
{
    GetInstanceData(hPrevInstance, (NPSTR)&nDoc, sizeof(int));
    nDoc++;
    return;
}



/****************************************************************************

    FUNCTION:  InitInstance(HANDLE, int)

    PURPOSE:  Saves instance handle, creates main window, and creates
        3 child edit controls with id's 1, 2, and 3.

****************************************************************************/

BOOL InitInstance(hInstance, nCmdShow)
    HANDLE          hInstance;
    int             nCmdShow;
{
    char        szNumber[4];
    char        szCaption[20];
    HDC         hDC;
    PAINTSTRUCT ps;
    TEXTMETRIC  tm;
    int         nItem;
    int         nHorzRes, nVertRes;

    InitAckTimeOut(); /* in module SERVDDE */

    hInst = hInstance;

    strcpy(szDocName, "FILE");
    itoa(nDoc, szNumber, 10);
    strcat(szDocName, szNumber);
    strcpy(szCaption, "Server -- ");
    strcat(szCaption, szDocName);

    hwndMain = CreateWindow(
        "ServerWClass",
        szCaption,
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (!hwndMain)
        return (FALSE);

    hDC = GetDC(hwndMain);
    GetTextMetrics(hDC, (LPTEXTMETRIC)&tm);
    xDelta = tm.tmAveCharWidth;
    yDelta = tm.tmHeight + tm.tmExternalLeading;
    nHorzRes = GetDeviceCaps(hDC, HORZRES);
    nVertRes = GetDeviceCaps(hDC, VERTRES);
    ReleaseDC(hwndMain, hDC);

    MoveWindow(hwndMain,
  nHorzRes/2 + xDelta*(nDoc+5),
        ((nDoc-1)&1)*nVertRes/2 + yDelta*nDoc,
        xDelta*30,
  yDelta*12,
        FALSE);

    for (nItem = 1; nItem < 4; nItem++)
    {
        CreateWindow("edit", NULL,
      WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | WS_TABSTOP,
            9*xDelta, (2*nItem-1)*yDelta, 12*xDelta, (yDelta*3)/2,
      hwndMain, nItem, hInst, NULL);
    }

    if (!(cfLink = RegisterClipboardFormat("Link")))
  return (FALSE);

    ShowWindow(hwndMain, nCmdShow);
    UpdateWindow(hwndMain);


    return (TRUE);

}

/****************************************************************************

    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for server

****************************************************************************/

long FAR PASCAL MainWndProc(hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    HDC  hDC;
    PAINTSTRUCT ps;
    HWND hctlItem;
    int  nItem;
    char szItemName[8];
    FARPROC lpAboutDlgProc;


    switch (message)
    {
        case WM_SETFOCUS:
            SetFocus(GetDlgItem(hwnd,1));
            break;

        case WM_PAINT:
      hDC = BeginPaint(hwnd, &ps);
            strcpy(szItemName, "Item1:");
            for (nItem = 1; nItem < 4; nItem++)
            {
    /* display labels for the edit controls */
                TextOut(hDC, xDelta, (2*nItem-1)*yDelta, szItemName, 6);
                szItemName[4]++;
            }
      EndPaint(hwnd, &ps);
            break;

        case WM_COMMAND:
            switch (wParam)
            {
               case IDM_COPY:
       hctlItem = GetFocus();
       for (nItem = 1; nItem <= 3; nItem++)
       {
           if (hctlItem == GetDlgItem(hwnd, nItem))
           {
         DoEditCopy(nItem);
         break;
           }
       }
       break;

         case ID_TAB:
         case ID_SHIFT_TAB:
       if (IsChild(hwndMain, GetFocus()))
       {
           nItem = GetWindowWord(GetFocus(), GWW_ID);
           if (wParam == ID_TAB)
           {
         if (nItem++ == 3)
             nItem = 1;
           }
           else
           {
         if (nItem-- == 1)
             nItem = 3;
           }
       }
       else
       {
           nItem = 1;
       }
       SetFocus(GetDlgItem(hwndMain, nItem));
       break;

         case 1:
               case 2:
               case 3:
                  if (HIWORD(lParam)==EN_KILLFOCUS)
                  {
                     hctlItem = GetDlgItem(hwnd, wParam);
                     if (SendMessage(hctlItem, EM_GETMODIFY, 0, 0L))
                     {
      MaybeAdviseData(wParam);
                        SendMessage(hctlItem, EM_SETMODIFY, 0, 0L);
                     }
                  }
                  break;

    case IDM_ABOUT:
        lpAboutDlgProc = MakeProcInstance(AboutDlgProc, hInst);
        DialogBox(hInst,
      "About",
      hwndMain,
      lpAboutDlgProc);
        FreeProcInstance(lpAboutDlgProc);
        break;
      }
            break;

        case WM_DDE_INITIATE:
            ServerInitiate((HWND)wParam, lParam);
            break;

        case WM_DESTROY:

            /* Terminate all DDE conversations before destroying
               client window */
      TerminateConversations();
            PostQuitMessage(0);
            break;

        default:
            return (DefWindowProc(hwnd, message, wParam, lParam));
    }
    return (0L);
}



/****************************************************************************

    FUNCTION: MaybeAdviseData

    PURPOSE:  Send data to all clients for which a hot or warm link
        has been established for the specified item.

****************************************************************************/
void MaybeAdviseData(nItem)
    int   nItem;
{
    HWND hwndServerDDE;
    char szItemName[ITEM_NAME_MAX_SIZE+1];
    char szItemValue[ITEM_VALUE_MAX_SIZE+1];
    BOOL bDeferUpdate;
    BOOL bAckRequest;

    hwndServerDDE = NULL;

    while (1)
    {
  if (hwndServerDDE = GetNextAdvise(hwndServerDDE, nItem))
        {
      GetAdviseData(hwndServerDDE,
                nItem,
                szItemName,
                szItemValue,
                &bDeferUpdate,
                &bAckRequest);

      SendData(hwndServerDDE,
    GetHwndClientDDE(hwndServerDDE),
                szItemName,
                szItemValue,
                bDeferUpdate,
                bAckRequest);
        }
        else return;
    }
}


/****************************************************************************

    FUNCTION: AboutDlgProc(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

****************************************************************************/

BOOL FAR PASCAL AboutDlgProc(hDlg, message, wParam, lParam)
    HWND hDlg;
    unsigned message;
    WORD wParam;
    LONG lParam;
{
    switch (message) {
  case WM_INITDIALOG:
      return (TRUE);

  case WM_COMMAND:
      if (wParam == IDOK || wParam == IDCANCEL) {
    EndDialog(hDlg, TRUE);
    return (TRUE);
      }
      break;
    }
    return (FALSE);
}


SHOWDIB.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SHOWDIB\SHOWDIB.C

/****************************************************************************
 *                         *
 *  PROGRAM  : ShowDIB.c                   *
 *                         *
 *  PURPOSE  : Application to illustrate the use of the GDI           *
 *      DIB (Device Independent Bitmap) and Palette manager         *
 *      functions.                   *
 *                         *
 *  FUNCTIONS  : WinMain ()     -  Creates the app. window and enters *
 *              the message loop.           *
 *                         *
 *      WndProc()     -  Processes app. window messages.    *
 *                         *
 *      MenuCommand()    -  Processes menu commands.         *
 *                         *
 *      FreeDIB()     -  Frees currently active objects.    *
 *                         *
 *      InitDIB()     -  Reads DIB from a file and loads it.*
 *                         *
 ****************************************************************************

#include <windows.h>
#include <io.h>
#include <stdio.h>
#include "showdib.h"

DIBPARAMS      DIBParams;       /* params for the SETSCALING escape */
char         achFileName[128] = "";
DWORD          dwOffset;
NPLOGPALETTE   pLogPal;
HPALETTE       hpalSave = NULL;
HANDLE         hInst ;
RECT         rcClip;
extern         WORD _WinFlags;
static         HCURSOR hcurSave;

BOOL  fPalColors  = FALSE;        /* TRUE if the current DIB's color table
              /* contains palette indexes not rgb values */
WORD  nAnimating  = 0;        /* Palette animation count     */
WORD  UpdateCount = 0;

BOOL  bMemoryDIB    = FALSE; /* Load Entire DIB into memory in CF_DIB format
BOOL  bUpdateColors = TRUE;  /* Directly update screen colors          */
BOOL  bDIBToDevice  = FALSE; /* Use SetDIBitsToDevice() to BLT data.
BOOL  bNoUgly       = FALSE; /* Make window black on a WM_PALETTEISCHANGING
BOOL  bLegitDraw    = FALSE; /* We have a valid bitmap to draw         */

char  szBitmapExt[] = "*.BMP; *.DIB; *.RLE";     /* possible file extensions
WORD  wTransparent  = TRANSPARENT;       /* Mode of DC         */
char  szAppName[]   = "ShowDIB" ;       /* App. name          */

HPALETTE hpalCurrent   = NULL;         /* Handle to current palette         *
HANDLE   hdibCurrent   = NULL;         /* Handle to current memory DIB
HBITMAP  hbmCurrent    = NULL;         /* Handle to current memory BITMAP
HANDLE   hbiCurrent    = NULL;         /* Handle to current bitmap info struc
HWND   hWndApp;           /* Handle to app. window          */

/* Styles of app. window */
DWORD         dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
       WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME;

void PrintDIB (HWND hWnd, HDC hDC, int x, int y, int dx, int dy);
/****************************************************************************
 *                      *
 *  FUNCTION   : WinMain(HANDLE, HANDLE, LPSTR, int)          *
 *                      *
 *  PURPOSE    : Creates the app. window and enters the message loop.      *
 *                      *
 ****************************************************************************
int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)

HANDLE hInstance, hPrevInstance ;
LPSTR  lpszCmdLine ;
int    nCmdShow ;
{
     HWND   hWnd ;
     WNDCLASS   wndclass ;
     MSG   msg ;
     short   xScreen, yScreen ;
     char   ach[40];

     hInst = hInstance ;

     /* default to MEMORY DIB's if XWindows */
     bMemoryDIB = WinFlags & WF_PMODE;

     /* Initialize clip rectangle */
     SetRectEmpty(&rcClip);

     if (!hPrevInstance) {
   wndclass.style   = CS_DBLCLKS;
   wndclass.lpfnWndProc  = WndProc ;
   wndclass.cbClsExtra  = 0 ;
   wndclass.cbWndExtra  = 0 ;
   wndclass.hInstance  = hInstance ;
   wndclass.hIcon   = LoadIcon(hInst, "SHOWICON");
   wndclass.hCursor  = LoadCursor (NULL, IDC_ARROW) ;
   wndclass.hbrBackground = GetStockObject (BLACK_BRUSH) ;
   wndclass.lpszMenuName  = szAppName ;
   wndclass.lpszClassName = szAppName ;

   if (!RegisterClass (&wndclass))
     return FALSE ;
     }

     if (!GetProfileString("extensions", "bmp", "", ach, sizeof(ach)))
       WriteProfileString("extensions", "bmp", "showdib.exe ^.bmp");
     if (!GetProfileString("extensions", "dib", "", ach, sizeof(ach)))
       WriteProfileString("extensions", "dib", "showdib.exe ^.dib");

     /* Save the pointer to the command line */
     lstrcpy(achFileName, lpszCmdLine);

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     /* Create the app. window */
     hWnd = CreateWindow( szAppName,
        szAppName,
        dwStyle,
        CW_USEDEFAULT,
        0,
        xScreen / 2,
        yScreen / 2,
        NULL,
        NULL,
        hInstance,
        NULL) ;

     ShowWindow (hWndApp = hWnd, nCmdShow) ;

     /* Enter message loop */
     while (GetMessage (&msg, NULL, 0, 0)) {
   TranslateMessage (&msg) ;
   DispatchMessage (&msg) ;
     }

     return msg.wParam ;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : WndProc (hWnd, iMessage, wParam, lParam)        *
 *                      *
 *  PURPOSE    : Processes window messages.            *
 *                      *
 ****************************************************************************
long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)

HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;

{
    PAINTSTRUCT      ps;
    HDC        hDC;
    HANDLE       h;
    int        i;
    int        iMax;
    int        iMin;
    int        iPos;
    int        dn;
    RECT       rc,Rect;
    HPALETTE       hOldPal;
    HMENU       hMenu;

    switch (iMessage) {
  case WM_DESTROY:
    /* Clean up and quit */
    FreeDib();
    PostQuitMessage(0);
    break ;

  case WM_CREATE:
    /* Allocate space for our logical palette */
    pLogPal = (NPLOGPALETTE) LocalAlloc( LMEM_FIXED,
                 (sizeof(LOGPALETTE) +
                 (sizeof(PALETTEENTRY)*(MAXPALETTE))));

    /* If DIB initialization fails, quit */
    if (achFileName[0] && !InitDIB(hWnd))
      PostQuitMessage (3) ;

    /* fall through */

  case WM_WININICHANGE:

    hMenu = GetMenu(hWnd);

    /* If printer initialization succeeds, enable appropriate
     * menu item and clean up.
     */
    if ( hDC = GetPrinterDC() ) {
        EnableMenuItem( hMenu,
            IDM_PRINT,
            (RC_DIBTODEV &
             GetDeviceCaps(hDC, RASTERCAPS)) ?
             MF_ENABLED :
             MF_GRAYED | MF_DISABLED);
        DeleteDC(hDC);
    }

    break;

  case WM_PALETTEISCHANGING:
    /* if SHOWDIB was not responsible for palette change and if
     * ok to hide changes, paint app. window black.
     */
    if (wParam != hWnd && bNoUgly) {
        GetClientRect(hWnd, &Rect);

        hDC = GetDC(hWnd);
        FillRect( hDC, (LPRECT) &Rect, GetStockObject(BLACK_BRUSH));
        ReleaseDC(hWnd, hDC);
    }
    break;

  case WM_ACTIVATE:
    if (!wParam)  /* app. is being de-activated */
       break;
    /* If the app. is moving to the foreground, fall through and
     * redraw full client area with the newly realized palette,
     * if the palette has changed.
     */

  case WM_QUERYNEWPALETTE:
    /* If palette realization causes a palette change,
     * we need to do a full redraw.
     */
    if (bLegitDraw) {
        hDC = GetDC (hWnd);
        hOldPal = SelectPalette (hDC, hpalCurrent, 0);

        i = RealizePalette(hDC);

        SelectPalette (hDC, hOldPal, 0);
        ReleaseDC (hWnd, hDC);

        if (i) {
      InvalidateRect (hWnd, (LPRECT) (NULL), 1);
      UpdateCount = 0;
      return 1;
        } else
      return FALSE;
    }
    else
        return FALSE;
    break;

  case WM_PALETTECHANGED:
    /* if SHOWDIB was not responsible for palette change and if
     * palette realization causes a palette change, do a redraw.
     */
     if (wParam != hWnd){
        if (bLegitDraw){
      hDC = GetDC (hWnd);
      hOldPal = SelectPalette (hDC, hpalCurrent, 0);

      i = RealizePalette (hDC);

      if (i){
          if (bUpdateColors){
        UpdateColors (hDC);
        UpdateCount++;
          }
          else
        InvalidateRect (hWnd, (LPRECT) (NULL), 1);
      }

      SelectPalette (hDC, hOldPal, 0);
      ReleaseDC (hWnd, hDC);
        }
    }
    break;

  case WM_RENDERALLFORMATS:
    /* Ensure that clipboard data can be rendered even tho'
     * app. is being destroyed.
     */
    SendMessage(hWnd,WM_RENDERFORMAT,CF_DIB,0L);
    SendMessage(hWnd,WM_RENDERFORMAT,CF_BITMAP,0L);
    SendMessage(hWnd,WM_RENDERFORMAT,CF_PALETTE,0L);
    break;

  case WM_RENDERFORMAT:
    /* Format data in manner specified and pass the data
     * handle to clipboard.
     */
    if (h = RenderFormat(wParam))
        SetClipboardData(wParam,h);
    break;

  case WM_COMMAND:
    /* Process menu commands */
    return MenuCommand (hWnd, wParam);
    break;

  case WM_TIMER:
    /* Signal for palette animation */
    hDC = GetDC(hWnd);
    hOldPal = SelectPalette(hDC, hpalCurrent, 0);
    {
        PALETTEENTRY peTemp;

        /* Shift all palette entries left by one position and wrap
         * around the first entry
         */
        peTemp = pLogPal->palPalEntry[0];
        for (i = 0; i < (pLogPal->palNumEntries - 1); i++)
       pLogPal->palPalEntry[i] = pLogPal->palPalEntry[i+1];
        pLogPal->palPalEntry[i] = peTemp;
    }
    /* Replace entries in logical palette with new entries*/
    AnimatePalette(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->palPalEnt

    SelectPalette(hDC, hOldPal, 0);
    ReleaseDC(hWnd, hDC);

    /* Decrement animation count and terminate animation
     * if it reaches zero
     */
    if (!(--nAnimating))
        PostMessage(hWnd,WM_COMMAND,IDM_ANIMATE0,0L);
    break;

  case WM_PAINT:
    /* If we have updated more than once, the rest of our
     * window is not in some level of degradation worse than
     * our redraw...  we need to redraw the whole area
     */
    if (UpdateCount > 1) {
        BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        UpdateCount = 0;
        InvalidateRect(hWnd, (LPRECT) (NULL), 1);
        break;
    }

    hDC = BeginPaint(hWnd, &ps);
    AppPaint(hWnd,
       hDC,
       GetScrollPos(hWnd,SB_HORZ),
       GetScrollPos(hWnd,SB_VERT) );
    EndPaint(hWnd, &ps);
    break ;

  case WM_SIZE:
      SetScrollRanges(hWnd);
      break;

  case WM_KEYDOWN:
      /* Translate keyboard messages to scroll commands */
      switch (wParam) {
    case VK_UP:    PostMessage (hWnd, WM_VSCROLL, SB_LINEUP,   0L);
             break;

    case VK_DOWN:  PostMessage (hWnd, WM_VSCROLL, SB_LINEDOWN, 0L);
             break;

    case VK_PRIOR: PostMessage (hWnd, WM_VSCROLL, SB_PAGEUP,   0L);
             break;

    case VK_NEXT:  PostMessage (hWnd, WM_VSCROLL, SB_PAGEDOWN, 0L);
             break;

    case VK_HOME:  PostMessage (hWnd, WM_HSCROLL, SB_PAGEUP,   0L);
             break;

    case VK_END:   PostMessage (hWnd, WM_HSCROLL, SB_PAGEDOWN, 0L);
             break;

    case VK_LEFT:  PostMessage (hWnd, WM_HSCROLL, SB_LINEUP,   0L);
             break;

    case VK_RIGHT: PostMessage (hWnd, WM_HSCROLL, SB_LINEDOWN, 0L);
             break;
      }
      break;

  case WM_KEYUP:
      switch (wParam) {
         case VK_UP:
         case VK_DOWN:
         case VK_PRIOR:
         case VK_NEXT:
      PostMessage (hWnd, WM_VSCROLL, SB_ENDSCROLL, 0L);
      break;

         case VK_HOME:
         case VK_END:
         case VK_LEFT:
         case VK_RIGHT:
      PostMessage (hWnd, WM_HSCROLL, SB_ENDSCROLL, 0L);
      break;
      }
      break;

  case WM_VSCROLL:
      /* Calculate new vertical scroll position */
      GetScrollRange (hWnd, SB_VERT, &iMin, &iMax);
      iPos = GetScrollPos (hWnd, SB_VERT);
      GetClientRect (hWnd, &rc);

      switch (wParam) {
    case SB_LINEDOWN:      dn =  rc.bottom / 16 + 1;
               break;

    case SB_LINEUP:        dn = -rc.bottom / 16 + 1;
               break;

    case SB_PAGEDOWN:      dn =  rc.bottom / 2  + 1;
               break;

    case SB_PAGEUP:        dn = -rc.bottom / 2  + 1;
               break;

    case SB_THUMBTRACK:
    case SB_THUMBPOSITION: dn = LOWORD(lParam)-iPos;
               break;

    default:         dn = 0;
      }
      /* Limit scrolling to current scroll range */
      if (dn = BOUND (iPos + dn, iMin, iMax) - iPos) {
    ScrollWindow (hWnd, 0, -dn, NULL, NULL);
    SetScrollPos (hWnd, SB_VERT, iPos + dn, TRUE);
      }
      break;

  case WM_HSCROLL:
      /* Calculate new horizontal scroll position */
      GetScrollRange (hWnd, SB_HORZ, &iMin, &iMax);
      iPos = GetScrollPos (hWnd, SB_HORZ);
      GetClientRect (hWnd, &rc);

      switch (wParam) {
    case SB_LINEDOWN:      dn =  rc.right / 16 + 1;
               break;

    case SB_LINEUP:        dn = -rc.right / 16 + 1;
               break;

    case SB_PAGEDOWN:      dn =  rc.right / 2  + 1;
               break;

    case SB_PAGEUP:        dn = -rc.right / 2  + 1;
               break;

    case SB_THUMBTRACK:
    case SB_THUMBPOSITION: dn = LOWORD (lParam) - iPos;
               break;

    default:         dn = 0;
      }
      /* Limit scrolling to current scroll range */
      if (dn = BOUND (iPos + dn, iMin, iMax) - iPos) {
    ScrollWindow (hWnd, -dn, 0, NULL, NULL);
    SetScrollPos (hWnd, SB_HORZ, iPos + dn, TRUE);
      }
      break;

  case WM_LBUTTONDOWN:
      /* Start rubberbanding a rect. and track it's dimensions.
       * set the clip rectangle to it's dimensions.
       */
      TrackMouse (hWnd, MAKEPOINT (lParam));
      break;

  case WM_LBUTTONDBLCLK:
      break;

  case WM_INITMENU:
      /* check/uncheck menu items depending on state  of related
       * flags
       */
      CheckMenuItem(wParam, IDM_UPDATECOL,
    (bUpdateColors ? MF_CHECKED : MF_UNCHECKED));
      CheckMenuItem(wParam, IDM_TRANSPARENT,
    (wTransparent == TRANSPARENT ? MF_CHECKED : MF_UNCHECKED));
      CheckMenuItem(wParam, IDM_DIBSCREEN,
    (bDIBToDevice ? MF_CHECKED : MF_UNCHECKED));
      CheckMenuItem(wParam, IDM_NOUGLY,
    (bNoUgly ? MF_CHECKED : MF_UNCHECKED));
      CheckMenuItem(wParam, IDM_MEMORYDIB,
    (bMemoryDIB ? MF_CHECKED : MF_UNCHECKED));
      EnableMenuItem(wParam, IDM_PASTEDIB,
    IsClipboardFormatAvailable(CF_DIB)?MF_ENABLED:MF_GRAYED);
      EnableMenuItem(wParam, IDM_PASTEDDB,
    IsClipboardFormatAvailable(CF_BITMAP)?MF_ENABLED:MF_GRAYED);
      EnableMenuItem(wParam, IDM_PASTEPAL,
    IsClipboardFormatAvailable(CF_PALETTE)?MF_ENABLED:MF_GRAYED);
      EnableMenuItem(wParam, IDM_PRINT,
    bLegitDraw ? MF_ENABLED : MF_GRAYED);
      EnableMenuItem(wParam, IDM_SAVE,
    bLegitDraw ? MF_ENABLED : MF_GRAYED);
      EnableMenuItem(wParam, IDM_COPY,
    bLegitDraw ? MF_ENABLED : MF_GRAYED);

      EnableMenuItem(wParam, IDM_ANIMATE0,
    bLegitDraw ? MF_ENABLED : MF_GRAYED);
      EnableMenuItem(wParam, IDM_ANIMATE5,
    bLegitDraw ? MF_ENABLED : MF_GRAYED);
      EnableMenuItem(wParam, IDM_ANIMATE50,
    bLegitDraw ? MF_ENABLED : MF_GRAYED);
      EnableMenuItem(wParam, IDM_ANIMATE100,
    bLegitDraw ? MF_ENABLED : MF_GRAYED);
      EnableMenuItem(wParam, IDM_ANIMATE200,
    bLegitDraw ? MF_ENABLED : MF_GRAYED);
      EnableMenuItem(wParam, IDM_ANIMATE201,
    bLegitDraw ? MF_ENABLED : MF_GRAYED);
      EnableMenuItem(wParam, IDM_STEALCOL,
    bLegitDraw ? MF_ENABLED : MF_GRAYED);
      break;

  default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ;

    }
    return 0L ;

}
/****************************************************************************
 *                      *
 *  FUNCTION   : MenuCommand ( HWND hWnd, WORD wParam)          *
 *                      *
 *  PURPOSE    : Processes menu commands.            *
 *                      *
 *  RETURNS    : TRUE  - if command could be processed.         *
 *     FALSE - otherwise              *
 *                      *
 ****************************************************************************
BOOL MenuCommand (hWnd, id)
HWND hWnd;
WORD id;

{
    BITMAPINFOHEADER bi;
    HDC        hDC;
    HANDLE       h;
    HBITMAP       hbm;
    HPALETTE       hpal;
    int        i;
    char       Name[40];
    BOOL       bSave;
    int        xSize, ySize, xRes, yRes, dx, dy;
    RECT       Rect;
    int        fh;
    WORD       fFileOptions;

    switch (id) {
  case IDM_ABOUT:
    /* Show About .. box */
    fDialog (ABOUTBOX, hWnd,AppAbout);
    break;

  case IDM_COPY:
    if (!bLegitDraw)
        return 0L;

    /* Clean clipboard of contents */
    if (OpenClipboard(hWnd)) {
        EmptyClipboard ();
        SetClipboardData (CF_DIB   ,NULL);
        SetClipboardData (CF_BITMAP  ,NULL);
        SetClipboardData (CF_PALETTE ,NULL);
        CloseClipboard ();
    }
    break;

  case IDM_PASTEPAL:
    if (OpenClipboard (hWnd)) {
        if (h = GetClipboardData (CF_PALETTE)) {
      /* Delete current palette and get the CF_PALETTE data
       * from the clipboard
       */
      if (hpalCurrent)
          DeleteObject (hpalCurrent);

      hpalCurrent = CopyPalette (h);

      /*
       * If we have a bitmap realized against the old palette
       * delete the bitmap and rebuild it using the new palette.
       */
      if (hbmCurrent){
          DeleteObject (hbmCurrent);
          hbmCurrent = NULL;

          if (hdibCurrent)
        hbmCurrent = BitmapFromDib (hdibCurrent, hpalCurrent);
      }
        }
        CloseClipboard();
    }
    break;

  case IDM_PASTEDIB:
    if (OpenClipboard (hWnd)) {
        if (h = GetClipboardData (CF_DIB)) {
      /* Delete current DIB and get CF_DIB and
       * CF_PALETTE format data from the clipboard
       */
      hpal = GetClipboardData (CF_PALETTE);

      FreeDib();
      hdibCurrent = CopyHandle (h);
      if (hdibCurrent) {
          bLegitDraw = TRUE;
          lstrcpy(achFileName,"<Clipboard>");
          hbiCurrent = hdibCurrent;

          /* If there is a CF_PALETTE object in the
           * clipboard, this is the palette to assume
           * the DIB should be realized against, otherwise
           * create a palette for it.
           */
          if (hpal)
        hpalCurrent = CopyPalette (hpal);
          else
        hpalCurrent = CreateDibPalette (hdibCurrent);

          SizeWindow(hWnd);
      }
      else {
          bLegitDraw = FALSE;
          ErrMsg("No Memory Available!");
      }
        }
        CloseClipboard();
    }
    break;

  case IDM_PASTEDDB:
    if (OpenClipboard (hWnd)) {
        if (hbm = GetClipboardData(CF_BITMAP)) {
      hpal = GetClipboardData(CF_PALETTE);
      FreeDib();

      /*
       * If there is a CF_PALETTE object in the
       * clipboard, this is the palette to assume
       * the bitmap is realized against.
       */
      if (hpal)
          hpalCurrent = CopyPalette(hpal);
      else
          hpalCurrent = GetStockObject(DEFAULT_PALETTE);

      hdibCurrent = DibFromBitmap(hbm,BI_RGB,0,hpalCurrent);

      if (hdibCurrent) {
          bLegitDraw = TRUE;
          lstrcpy(achFileName,"<Clipboard>");
          hbiCurrent = hdibCurrent;

          if (bMemoryDIB)
        hbmCurrent = BitmapFromDib (hdibCurrent, hpalCurrent);

          SizeWindow(hWnd);
      }
      else {
          bLegitDraw = FALSE;
          ErrMsg("No Memory Available!");
      }
        }
        CloseClipboard ();
    }
    break;

  case IDM_PRINT:
    GetWindowText(hWnd, Name, sizeof(Name));

    DibInfo(hbiCurrent, &bi);

    if (!IsRectEmpty(&rcClip))
    {
        bi.biWidth  = rcClip.right  - rcClip.left;
        bi.biHeight = rcClip.bottom - rcClip.top;
    }

    /* Initialise printer stuff */
    if (!(hDC = GetPrinterDC()))
      break;

    xSize = GetDeviceCaps(hDC, HORZRES);
    ySize = GetDeviceCaps(hDC, VERTRES);
    xRes  = GetDeviceCaps(hDC, LOGPIXELSX);
    yRes  = GetDeviceCaps(hDC, LOGPIXELSY);

    /* Use half inch margins on left and right
     * and one inch on top. Maintain the same aspect ratio.
     */

    dx = xSize - xRes;
    dy = (int)((long)dx * bi.biHeight/bi.biWidth);

    /* Fix bounding rectangle for the picture .. */
    Rect.top    = yRes;
    Rect.left   = xRes / 2;
    Rect.bottom = yRes + dy;
    Rect.right  = xRes / 2 + dx;

    /* ... and inform the driver */
    Escape(hDC, SET_BOUNDS, sizeof(RECT), (LPSTR)&Rect, NULL);

    bSave = TRUE;

    if (InitPrinting(hDC, hWnd, hInst, Name)) {

      PrintDIB(hWnd, hDC, xRes/2, yRes, dx, dy);

      /* Signal to the driver to begin translating the drawing
       * commands to printer output...
       */
      Escape (hDC, NEWFRAME, NULL, NULL, NULL);

      TermPrinting(hDC);
    }

    DeleteDC(hDC);
    break;

  case IDM_OPEN:
    /* Bring up File/Open ... dialog */
    fh = DlgOpenFile (hWnd,
          "Select a DIB to display",
          (LONG)OF_EXIST | OF_MUSTEXIST | OF_NOOPTIONS,
          szBitmapExt,
          achFileName,
          NULL
          );

    /*  Load up the DIB if the user did not press cancel */
    if (fh > 0) {
       StartWait();
       if (InitDIB (hWnd))
           InvalidateRect (hWnd, NULL, FALSE);
       else
           bLegitDraw = FALSE;
       EndWait();
    }
    break;

  case IDM_SAVE:
    DibInfo(hbiCurrent,&bi);
    fFileOptions = 0;

    /* Depending on compression type for current DIB,
     * set the appropriate bit in the fFileOptions flag
     */
    if (bi.biCompression == BI_RGB)
        fFileOptions |= F_RGB;
    else if (bi.biCompression == BI_RLE4)
        fFileOptions |= F_RLE4;
    else if (bi.biCompression == BI_RLE8)
        fFileOptions |= F_RLE8;

    /* Depending on bits/pixel type for current DIB,
     * set the appropriate bit in the fFileOptions flag
     */
    switch (bi.biBitCount){
        case  1:
      fFileOptions |= F_1BPP;
      break;

        case  4:
      fFileOptions |= F_4BPP;
      break;

        case  8:
      fFileOptions |= F_8BPP;
      break;

        case 24:
      fFileOptions |= F_24BPP;
    }

    /* Bring up File/Save... dialog and get info. about filename,
     * compression, and bits/pix. of DIB to be written.
     */
    fh = DlgOpenFile (hWnd,
          "Select File to save DIB to",
          (LONG)OF_EXIST | OF_SAVE | OF_NOSHOWSPEC,
          szBitmapExt,
          achFileName,
          &fFileOptions);

    /* Extract DIB specs. if the user did not press cancel */
    if (fh != 0){
        if (fFileOptions & F_RGB)
      bi.biCompression = BI_RGB;

        if (fFileOptions & F_RLE4)
      bi.biCompression = BI_RLE4;

        if (fFileOptions & F_RLE8)
      bi.biCompression = BI_RLE8;

        if (fFileOptions & F_1BPP)
      bi.biBitCount = 1;

        if (fFileOptions & F_4BPP)
      bi.biBitCount = 4;

        if (fFileOptions & F_8BPP)
      bi.biBitCount = 8;

        if (fFileOptions & F_24BPP)
      bi.biBitCount = 24;

        /* Realize a DIB in the specified format and obtain a
         * handle to it.
         */
        hdibCurrent = RealizeDibFormat(bi.biCompression,bi.biBitCount);
        if (!hdibCurrent){
      ErrMsg("Unable to save the specified file");
      return 0L;
        }

        /* Write the DIB */
        StartWait();
        if (!WriteDIB(achFileName,hdibCurrent))
      ErrMsg("Unable to save the specified file");
        EndWait();
    }
    break;

  case IDM_EXIT:
    PostMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
    break;

  case IDM_UPDATECOL:
    /* Toggle state of "update screen colors" flag. If it is
     * off, clear the "hide changes" flag
     */
    bUpdateColors = !bUpdateColors;
    if (bUpdateColors)
        bNoUgly = 0;
    break;

  case IDM_DIBSCREEN:
    bDIBToDevice = !bDIBToDevice;
    InvalidateRect(hWnd, (LPRECT) (NULL), 1);
    break;

  case IDM_MEMORYDIB:
    bMemoryDIB = !bMemoryDIB;
    break;

  case IDM_NOUGLY:
    /* Toggle state of "hide changes" flag. If it is off, clear
     * the "update screen colors" flag. This will tell SHOWDIB
     * to paint itself black while the palette is changing.
     */
    bNoUgly = !bNoUgly;
    if (bNoUgly)
        bUpdateColors = 0;
    break;

  case IDM_TRANSPARENT:
    /* Toggle DC mode */
    wTransparent = wTransparent == TRANSPARENT ?
        OPAQUE : TRANSPARENT;
    break;

  case IDM_ANIMATE0:
    if (!hpalSave)
        break;

    /* Reset animation count and stop timer */
    KillTimer(hWnd, 1);
    nAnimating = 0;

    /* Restore palette which existed before animation started */
    DeleteObject(hpalCurrent);
    hpalCurrent = hpalSave;

    /* Rebuild bitmap based on newly realized information */
    hDC = GetDC (hWnd);
    SelectPalette (hDC, hpalCurrent, 0);
    RealizePalette (hDC);
    ReleaseDC (hWnd, hDC);

    if (hbmCurrent){
        DeleteObject (hbmCurrent);
        hbmCurrent = NULL;

        if (hdibCurrent)
           hbmCurrent = BitmapFromDib (hdibCurrent, hpalCurrent);
    }
    hpalSave = NULL;

    /* Force redraw with new palette for everyone */
    InvalidateRect(hWnd, NULL, TRUE);
    break;

  case IDM_STEALCOL:
  case IDM_ANIMATE5:
  case IDM_ANIMATE20:
  case IDM_ANIMATE50:
  case IDM_ANIMATE100:
  case IDM_ANIMATE200:
  case IDM_ANIMATE201:
    /* Set animation count i.e number of times animation is to
     * take place.
     */
    nAnimating = id;
    if (id == IDM_STEALCOL)
      nAnimating = 0;

    /* Save current palette */
    hpalSave = CopyPalette(hpalCurrent);

    GetObject(hpalCurrent, sizeof(int), (LPSTR)&pLogPal->palNumEntries);
    GetPaletteEntries(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->palPal

    /* Reserve all entries in the palette otherwise AnimatePalette()
     * will not modify them
     */
    for (i = 0; i < pLogPal->palNumEntries; i++) {
         pLogPal->palPalEntry[i].peFlags = (BYTE)PC_RESERVED;
    }

    SetPaletteEntries(hpalCurrent, 0, pLogPal->palNumEntries, pLogPal->palPal

    /* Rebuild bitmap based on newly realized information */
    if (hbmCurrent){
        DeleteObject (hbmCurrent);
        hbmCurrent = NULL;

        if (hdibCurrent)
           hbmCurrent = BitmapFromDib (hdibCurrent, hpalCurrent);
    }

    /* Force redraw with new palette for everyone */
    InvalidateRect(hWnd, NULL, TRUE);

    /* Initiate the timer so that palette can be animated in
     * response to a WM_TIMER message
     */
    if (nAnimating && !SetTimer(hWnd, 1, 250, (LPSTR) NULL))
      nAnimating = 0;

  default:
    break;
    }

    return TRUE;
}

/****************************************************************************
 *                      *
 *  FUNCTION   : InitDIB(hWnd)                *
 *                      *
 *  PURPOSE    : Reads a DIB from a file, obtains a handle to it's          *
 *     BITMAPINFO struct., sets up the palette and loads the DIB. *
 *                      *
 *  RETURNS    : TRUE  - DIB loads ok              *
 *     FALSE - otherwise              *
 *                      *
 ****************************************************************************
int InitDIB(hWnd)
HWND hWnd;
{
    unsigned         fh;
    LPBITMAPINFOHEADER lpbi;
    WORD FAR *         pw;
    int          i;
    BITMAPINFOHEADER   bi;
    OFSTRUCT         of;

    FreeDib();

    /* Open the file and get a handle to it's BITMAPINFO */

    fh = OpenFile (achFileName, (LPOFSTRUCT)&of, OF_READ);
    if (fh == -1) {
  ErrMsg("Can't open file '%ls'", (LPSTR)achFileName);
  return FALSE;
    }
    hbiCurrent = ReadDibBitmapInfo(fh);

    dwOffset = _llseek(fh, 0L, SEEK_CUR);
    _lclose (fh);

    if (hbiCurrent == NULL) {
  ErrMsg("%ls is not a Legitimate DIB File!", (LPSTR)achFileName);
  return FALSE;
    }
    DibInfo(hbiCurrent,&bi);

    /* Set up the palette */
    hpalCurrent = CreateDibPalette(hbiCurrent);
    if (hpalCurrent == NULL) {
  ErrMsg("CreatePalette() Failed");
  return FALSE;
    }

    /*  Convert the DIB color table to palette relative indexes, so
     *  SetDIBits() and SetDIBitsToDevice() can avoid color matching.
     *  We can do this because the palette we realize is identical
     *  to the color table of the bitmap, ie the indexes match 1 to 1
     *
     *  Now that the DIB color table is palette indexes not RGB values
     *  we must use DIB_PAL_COLORS as the wUsage parameter to SetDIBits()
     */
    lpbi = (VOID FAR *)GlobalLock(hbiCurrent);
    if (lpbi->biBitCount != 24) {
  fPalColors = TRUE;

  pw = (WORD FAR *)((LPSTR)lpbi + lpbi->biSize);

  for (i=0; i<(int)lpbi->biClrUsed; i++)
      *pw++ = (WORD)i;
    }
    GlobalUnlock(hbiCurrent);
    bLegitDraw = TRUE;

    /*  If the input bitmap is not in RGB FORMAT the banding code will
     *  not work!  we need to load the DIB bits into memory.
     *  if memory DIB, load it all NOW!  This will avoid calling the
     *  banding code.
     */
    if (bMemoryDIB || bi.biCompression != BI_RGB)
  hdibCurrent = OpenDIB(achFileName);

    /*  If the RLE could not be loaded all at once, exit gracefully NOW,
     *  to avoid calling the banding code
     */
    if ((bi.biCompression != BI_RGB) && !hdibCurrent){
  ErrMsg ("Could not load RLE!");
  FreeDib();
  return FALSE;
    }

    if (hdibCurrent && !bDIBToDevice && bMemoryDIB){
  hbmCurrent = BitmapFromDib(hdibCurrent,hpalCurrent);
  if (!hbmCurrent){
      ErrMsg ("Could not create bitmap!");
      FreeDib();
      return FALSE;
  }
    }

    SizeWindow(hWnd);

    return TRUE;
}
/****************************************************************************
 *                      *
 *  FUNCTION   : FreeDib(void)                *
 *                      *
 *  PURPOSE    : Frees all currently active bitmap, DIB and palette objects *
 *     and initializes their handles.           *
 *                      *
 ****************************************************************************
void FreeDib(void)
{
    if (hpalCurrent)
  DeleteObject(hpalCurrent);

    if (hbmCurrent)
  DeleteObject(hbmCurrent);

    if (hdibCurrent)
  GlobalFree(hdibCurrent);

    if (hbiCurrent && hbiCurrent != hdibCurrent)
  GlobalFree(hbiCurrent);

    fPalColors  = FALSE;
    bLegitDraw  = FALSE;
    hpalCurrent = NULL;
    hdibCurrent = NULL;
    hbmCurrent  = NULL;
    hbiCurrent  = NULL;
    SetRectEmpty (&rcClip);
}


SHOWFONT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SHOWFONT\SHOWFONT.C

/****************************************************************************

    PROGRAM: Showfont.c

    PURPOSE: Adds, deletes, creates and displays fonts

    FUNCTIONS:

        WinMain() - calls initialization function, processes message loop
        EditfileInit() - initializes window data and registers window
        EditfileWndProc() - processes messages
        About() - processes messages for "About" dialog box
        SelectFont() - select a font
        GetSizes() - get size of current font
        GetFonts() - get available fonts
        SetMyDC() - initializes DC
        Metric() - Metric dialog box
        Log() - Log dialog box
        AddDlg() - dialog box for adding a font
        RemoveDlg() - dialog box for removing a font
        CFontDlg()
        _lstrcpy() - long strcpy()
        _lstrncpy() - long strncpy()
        _lstrlen()  - long strlen()
        CheckFileName() - check for valid filename
        SeparateFile() - Separate filename and pathname
        UpdateListBox() - update file list box
        AddExt() - add default extension
        SetFaceName() - update title with current font's face name

****************************************************************************/

#include "windows.h"
#include "showfont.h"

HANDLE hInst;

HFONT hOFont, hFFont, hVFont, hSFont, hDFont, hMFont, hFont;
int hFile;
char line[4][64];
char FontNameList[32][128];                          /* list of added fonts
int nFontIndex = 0;                                  /* position in FontList
int nLineSpace;

TEXTMETRIC TextMetric;
LOGFONT LogFont;
FARPROC lpCFontDlg;
POINT ptCurrent = {0, 0};
short nBkMode = OPAQUE;
DWORD rgbBkColor = RGB(255, 255, 255);
DWORD rgbTextColor = RGB(0, 0, 0);
DWORD rgbColor;
short nAlignLCR = TA_LEFT;
short nAlignTBB = TA_TOP;
WORD wPaint = 0;
FARPROC lpColors;
char FontList[MAXFONT][32];
BYTE CharSet[MAXFONT];
BYTE PitchAndFamily[MAXFONT];
int FontIndex = 0;
int SizeList[MAXSIZE];
int SizeIndex = 0;
int CurrentFont = 0;
int CurrentSize = 0;
FARPROC lpSelectFont;
FARPROC lpEnumFunc;
WORD wPrevVAlign = IDM_ALIGNBASE;
WORD wPrevHAlign = IDM_ALIGNLEFT;
WORD wPrevFont = IDM_SYSTEM;
char AppName[] = "ShowFont Sample Application   Font: ";
char WindowTitle[80];
char str[255];
char DefPath[128];
char DefExt[] = ".fon";
char DefSpec[13];
char FontFileName[128];

/****************************************************************************

    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

    PURPOSE: calls initialization function, processes message loop

****************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int nCmdShow;
{
    HWND hWnd;
    MSG msg;

    if (!hPrevInstance)
        if (!ShowFontInit(hInstance))
            return (FALSE);

    hInst = hInstance;

    strcpy(WindowTitle, AppName);
    strcat(WindowTitle, "SYSTEM");                 /* default is SYSTEM font

    hWnd = CreateWindow("ShowFont",
        WindowTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);

    if (!hWnd)
        return (FALSE);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    while (GetMessage(&msg, NULL, NULL, NULL)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (msg.wParam);
}

/****************************************************************************

    FUNCTION: ShowFontInit(HANDLE)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

int ShowFontInit(hInstance)
HANDLE hInstance;
{
    HANDLE hMemory;
    PWNDCLASS pWndClass;
    BOOL bSuccess;

    hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
    pWndClass = (PWNDCLASS) LocalLock(hMemory);
    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
    pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION);
    pWndClass->lpszMenuName = (LPSTR) "ShowFont";
    pWndClass->lpszClassName = (LPSTR) "ShowFont";
    pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
    pWndClass->hInstance = hInstance;
    pWndClass->style = NULL;
    pWndClass->lpfnWndProc = ShowFontWndProc;

    bSuccess = RegisterClass((LPWNDCLASS) pWndClass);

    LocalUnlock(hMemory);
    LocalFree(hMemory);
    return (bSuccess);
}

/****************************************************************************

    FUNCTION: SetMyDC(HDC)

    PURPOSE: Initializes the DC

****************************************************************************/

HDC SetMyDC(hDC)
HDC hDC;
{
    SetBkMode(hDC, nBkMode);
    SetBkColor(hDC, rgbBkColor);
    SetTextColor(hDC, rgbTextColor);
    SetTextAlign(hDC, nAlignLCR | nAlignTBB);
}

/****************************************************************************

    FUNCTION: GetStringExtent(HDC, PSTR, HFONT)

    PURPOSE: get the string extent

****************************************************************************/

short GetStringExtent(hDC, pString, hFont)
HDC hDC;
PSTR pString;
HFONT hFont;
{
    HFONT hOldFont;
    DWORD dwExtent;

    if (hOldFont=SelectObject(hDC, hFont)) {
        dwExtent = GetTextExtent(hDC, pString, strlen(pString));
        SelectObject(hDC, hOldFont);
        return (LOWORD(dwExtent));
    }
    else
        return (0);
}

/****************************************************************************

    FUNCTION: GetStringExtent(HDC, PSTR, HFONT)

    PURPOSE: Sends string to application's window

****************************************************************************/

short StringOut(hDC, X, Y, pString, hFont)
HDC hDC;
short X;
short Y;
PSTR pString;
HFONT hFont;
{
    HFONT hOldFont;
    DWORD dwExtent;

    hOldFont = SelectObject(hDC, hFont);
    if (hOldFont != NULL) {
        dwExtent = GetTextExtent(hDC, pString, strlen(pString));
        TextOut(hDC, X, Y, pString, strlen(pString));
        SelectObject(hDC, hOldFont);
    }
    return (LOWORD(dwExtent));
}

/****************************************************************************

    FUNCTION: ShowString(HWND)

    PURPOSE: Show string in current font

****************************************************************************/

void ShowString(hWnd)
HWND hWnd;
{
    HFONT hItalicFont;
    HFONT hBoldFont;
    HFONT hUnderlineFont;
    HFONT hStrikeOutFont;
    HDC hDC;
    short X, tmpX;
    short Y;
    short nAlign;

    GetObject(hFont, sizeof(LOGFONT), (LPSTR) &LogFont);
    LogFont.lfItalic = TRUE;
    hItalicFont = CreateFontIndirect(&LogFont);
    LogFont.lfItalic = FALSE;
    LogFont.lfUnderline = TRUE;
    hUnderlineFont = CreateFontIndirect(&LogFont);
    LogFont.lfUnderline = FALSE;
    LogFont.lfStrikeOut = TRUE;
    hStrikeOutFont = CreateFontIndirect(&LogFont);
    LogFont.lfStrikeOut = FALSE;
    LogFont.lfWeight = FW_BOLD;
    hBoldFont = CreateFontIndirect(&LogFont);

    hDC=GetDC(hWnd);
    SetMyDC(hDC);
    X=ptCurrent.x;
    Y=ptCurrent.y;
    nAlign =  nAlignLCR | nAlignTBB;                   /* GetTextAlign(hDC);
    if ((nAlign & TA_CENTER) == TA_CENTER) {
        tmpX = X;
        nAlignLCR = TA_LEFT;
        SetTextAlign(hDC, nAlignLCR | nAlignTBB);
        X += StringOut(hDC, X, Y, ", and ", hFont);
        X += StringOut(hDC, X, Y, "strikeout", hStrikeOutFont);
        X += StringOut(hDC, X, Y, " in a single line.", hFont);
        X = tmpX;
        nAlignLCR = TA_RIGHT;
        SetTextAlign(hDC, nAlignLCR | nAlignTBB);
        X -= StringOut(hDC, X, Y, "underline", hUnderlineFont);
        X -= StringOut(hDC, X, Y, ", ", hFont);
        X -= StringOut(hDC, X, Y, "italic", hItalicFont);
        X -= StringOut(hDC, X, Y, ", ", hFont);
        X -= StringOut(hDC, X, Y, "bold", hBoldFont);
        X -= StringOut(hDC, X, Y, "You can use ", hFont);
        nAlignLCR = TA_CENTER;
    }
    else if ((nAlign & TA_CENTER) == TA_RIGHT) {
        X -= StringOut(hDC, X, Y, " in a single line.", hFont);
        X -= StringOut(hDC, X, Y, "strikeout", hStrikeOutFont);
        X -= StringOut(hDC, X, Y, ", and ", hFont);
        X -= StringOut(hDC, X, Y, "underline", hUnderlineFont);
        X -= StringOut(hDC, X, Y, ", ", hFont);
        X -= StringOut(hDC, X, Y, "italic", hItalicFont);
        X -= StringOut(hDC, X, Y, ", ", hFont);
        X -= StringOut(hDC, X, Y, "bold", hBoldFont);
        X -= StringOut(hDC, X, Y, "You can use ", hFont);
    }
    else  {
        X += StringOut(hDC, X, Y, "You can use ", hFont);
        X += StringOut(hDC, X, Y, "bold", hBoldFont);
        X += StringOut(hDC, X, Y, ", ", hFont);
        X += StringOut(hDC, X, Y, "italic", hItalicFont);
        X += StringOut(hDC, X, Y, ", ", hFont);
        X += StringOut(hDC, X, Y, "underline", hUnderlineFont);
        X += StringOut(hDC, X, Y, ", and ", hFont);
        X += StringOut(hDC, X, Y, "strikeout", hStrikeOutFont);
        X += StringOut(hDC, X, Y, " in a single line.", hFont);
    }
    ReleaseDC(hWnd, hDC);

    DeleteObject(hItalicFont);
    DeleteObject(hUnderlineFont);
    DeleteObject(hStrikeOutFont);
    DeleteObject(hBoldFont);
}

/****************************************************************************

    FUNCTION: ShowCharacterSet(HDC, HFONT)

    PURPOSE: display character set using current font

****************************************************************************/

void ShowCharacterSet(hDC, hFont)
HDC hDC;
HFONT hFont;
{
    HFONT hOldFont;
    TEXTMETRIC TextMetric;
    int LineSpace;
    short X;
    short Y;

    if (!(hOldFont = SelectObject(hDC, hFont)))
        return;
    GetTextMetrics(hDC, &TextMetric);
    nLineSpace = (TextMetric.tmHeight + TextMetric.tmExternalLeading)*2;
    X = ptCurrent.x;
    Y = ptCurrent.y;
    TextOut(hDC, X, Y, line[0], 64);
    TextOut(hDC, X, Y += nLineSpace, line[1], 64);
    TextOut(hDC, X, Y += nLineSpace, line[2], 64);
    TextOut(hDC, X, Y += nLineSpace, line[3], 64);
    SelectObject(hDC, hOldFont);
}

/****************************************************************************

    FUNCTION: ShowLogFont(HWND, HFONT)

    PURPOSE: Create dialog box to show information about logical font

****************************************************************************/

void ShowLogFont(hWnd, hFont)
HWND hWnd;
HFONT hFont;
{
    HFONT hOldFont;
    FARPROC lpProcLog;
    HDC hDC;
    TEXTMETRIC TextMetric;
    HANDLE hDlgBox;
    char buf[80];
    char DialogTitle[100];

    hDC = GetDC(hWnd);
    if (!(hOldFont = SelectObject(hDC, hSFont)))
        return;
    GetTextMetrics(hDC, &TextMetric);
    nLineSpace = TextMetric.tmHeight + TextMetric.tmExternalLeading;
    GetObject(hFont, sizeof(LOGFONT), (LPSTR) &LogFont);

    lpProcLog = MakeProcInstance((FARPROC) Log, hInst);
    hDlgBox = CreateDialog(hInst, "LogBox", hWnd, lpProcLog);

    strcpy(DialogTitle, "Log Font: ");
    strcat(DialogTitle, LogFont.lfFaceName);
    SetWindowText(hDlgBox, (LPSTR) DialogTitle);

    SelectObject(hDC, hOldFont);
    ReleaseDC(hWnd, hDC);
}

/****************************************************************************

    FUNCTION: ShowMetricFont(HWND, HFONT)

    PURPOSE: Create dialog box to show information about metric font

****************************************************************************/

void ShowTextMetric(hWnd, hFont)
HWND hWnd;
HFONT hFont;
{
    FARPROC lpProcMetric;
    HFONT hOldFont;
    TEXTMETRIC LocalTextMetric;
    HDC hDC;
    HANDLE hDlgBox;
    char buf[80];
    char DialogTitle[100];

    hDC = GetDC(hWnd);
    if (!(hOldFont = SelectObject(hDC, hFont)))
        return;
    GetTextMetrics(hDC, &TextMetric);

    lpProcMetric = MakeProcInstance((FARPROC) Metric, hInst);
    hDlgBox = CreateDialog(hInst, "MetricBox", hWnd, lpProcMetric);

    strcpy(DialogTitle, "Metric Font: ");
    GetTextFace(hDC, 80, buf);
    strcat(DialogTitle, buf);
    SetWindowText(hDlgBox, (LPSTR) DialogTitle);

    SelectObject(hDC, hOldFont);
    ReleaseDC(hWnd, hDC);
}

/****************************************************************************

    FUNCTION: Colors(HWND, unsigned, WORD LONG)

    PURPOSE: Dialog box for changing background color of text

****************************************************************************/

BOOL FAR PASCAL Colors(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    int Red, Green, Blue;

    switch (message) {
        case WM_INITDIALOG:
            SetDlgItemInt(hDlg, ID_RED, GetRValue(rgbColor), FALSE);
            SetDlgItemInt(hDlg, ID_GREEN, GetGValue(rgbColor), FALSE);
            SetDlgItemInt(hDlg, ID_BLUE, GetBValue(rgbColor), FALSE);
            return (TRUE);
            break;

        case WM_COMMAND:
            switch (wParam) {
                case IDOK:
                    Red = GetDlgItemInt(hDlg, ID_RED, NULL, FALSE);
                    Green = GetDlgItemInt(hDlg, ID_GREEN, NULL, FALSE);
                    Blue = GetDlgItemInt(hDlg, ID_BLUE, NULL, FALSE);
                    rgbColor = RGB(Red, Green, Blue);
                    EndDialog(hDlg, 1);
                    break;

                case IDCANCEL:
                    EndDialog(hDlg, 0);
                    break;
            }
            break;
    }
    return (FALSE);
}

/****************************************************************************

    FUNCTION: EnumFunc(LPLOGFONT, LPTEXTMETRIC, short, LPSTR)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

int FAR PASCAL EnumFunc(lpLogFont, lpTextMetric, FontType, lpData)
LPLOGFONT lpLogFont;
LPTEXTMETRIC lpTextMetric;
short FontType;
LPSTR lpData;
{
    switch (LOWORD(lpData)) {
        case 0:
            if (FontIndex >= MAXFONT)
                return (0);
            _lstrcpy((LPSTR) FontList[FontIndex],
                (LPSTR) (lpLogFont->lfFaceName));
            CharSet[FontIndex] = lpLogFont->lfCharSet;
            PitchAndFamily[FontIndex] = lpLogFont->lfPitchAndFamily;
            return (++FontIndex);

        case 1:
            if (SizeIndex >= MAXSIZE)
                return (0);
            SizeList[SizeIndex] = lpLogFont->lfHeight;
            return (++SizeIndex);
    }
}

/****************************************************************************

    FUNCTION: GetFonts(HWND)

    PURPOSE: Get available fonts

****************************************************************************/

void GetFonts(hWnd)
HWND hWnd;
{

    HDC hDC;

    FontIndex = 0;
    SizeIndex = 0;
    hDC = GetDC(hWnd);
    lpEnumFunc = MakeProcInstance(EnumFunc, hInst);
    EnumFonts(hDC, (LPSTR) NULL, lpEnumFunc, (LPSTR) NULL);
    FreeProcInstance(lpEnumFunc);
    ReleaseDC(hWnd, hDC);
}

/****************************************************************************

    FUNCTION: GetSizes(hWnd, CurrentFont)

    PURPOSE: Get size of current font

****************************************************************************/

void GetSizes(hWnd, CurrentFont)
HWND hWnd;
int CurrentFont;
{
    HDC hDC;

    SizeIndex = 0;
    hDC = GetDC(hWnd);
    lpEnumFunc = MakeProcInstance(EnumFunc, hInst);
    EnumFonts(hDC, FontList[CurrentFont], lpEnumFunc, (LPSTR) 1L);
    FreeProcInstance(lpEnumFunc);
    ReleaseDC(hWnd, hDC);
}


/****************************************************************************

    FUNCTION: SelectFont(HWND, unsigned, WORD, LONG)

    PURPOSE: Initializes window data and registers window class

****************************************************************************/

BOOL FAR PASCAL SelectFont(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{

    int i;
    int index;
    char buf[LF_FACESIZE];

    switch (message) {
        case WM_INITDIALOG:
            for (i=0; i<FontIndex; i++) {        /* displays available fonts
                SendDlgItemMessage(hDlg, ID_TYPEFACE, LB_ADDSTRING,
                    NULL, (LONG) (LPSTR) FontList[i]);
                SendDlgItemMessage(hDlg, ID_TYPEFACE, LB_SETCURSEL,
                    0, 0L);
            }
            GetSizes(hDlg, 0);
            for (i=0; i<SizeIndex; i++) {        /* displays font sizes
                sprintf(buf, "%d", SizeList[i]);
                SendDlgItemMessage(hDlg, ID_SIZE, LB_ADDSTRING,
                    0, (LONG) (LPSTR) buf);
                SendDlgItemMessage(hDlg, ID_SIZE, LB_SETCURSEL,
                    0, 0L);
            }
            return (TRUE);
            break;

        case WM_COMMAND:
            switch (wParam) {
                case IDOK:
okay:
                    index=SendDlgItemMessage(hDlg, ID_TYPEFACE,
                        LB_GETCURSEL, 0, 0L);
                    if (index == LB_ERR) {
                        MessageBox(hDlg, "No font selected",
                            "Select Font", MB_OK | MB_ICONEXCLAMATION);
                    break;
            }
            CurrentFont = index;
            index = SendDlgItemMessage(hDlg, ID_SIZE,
                LB_GETCURSEL, 0, 0L);
            if (index == LB_ERR) {
                MessageBox(hDlg, "No size selected",
                    "Select Font", MB_OK | MB_ICONEXCLAMATION);
                break;
            }
            CurrentSize = index;
            EndDialog(hDlg, 1);
            break;

        case IDCANCEL:
            EndDialog(hDlg, 0);
            break;

        case ID_TYPEFACE:
            switch (HIWORD(lParam)) {
                case LBN_SELCHANGE:
                    index = SendDlgItemMessage(hDlg, ID_TYPEFACE,
                        LB_GETCURSEL, 0, 0L);
                    if (index == LB_ERR)
                        break;
                    SendDlgItemMessage(hDlg, ID_SIZE, LB_RESETCONTENT, 0, 0L)
                    GetSizes(hDlg, index);
                    for (i = 0; i < SizeIndex; i++) {
                        sprintf(buf, "%d", SizeList[i]);
                        SendDlgItemMessage(hDlg, ID_SIZE,
                            LB_ADDSTRING, 0, (LONG) (LPSTR) buf);
                        SendDlgItemMessage(hDlg, ID_SIZE, LB_SETCURSEL, 0, 0L
            }
            break;

                case LBN_DBLCLK:
                goto okay;
                break;
            }
            break;

        case ID_SIZE:
            if(HIWORD(lParam) == LBN_DBLCLK)
                goto okay;
            break;
        }
        break;
    }
    return (FALSE);
}

/****************************************************************************

    FUNCTION: ShowFontWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE: Processes messages

****************************************************************************/

long FAR PASCAL ShowFontWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout, lpAddDlg, lpRemoveDlg;
    HDC hDC;
    PAINTSTRUCT ps;
    HFONT hOldFont;
    int i;
    short Y;
    char buf[80];

    switch(message) {
        case WM_CREATE:
            GetFonts(hWnd);
            hMFont = CreateFont(
                10,                                      /* height
                10,                                      /* width
                0,                                       /* escapement
                0,                                       /* orientation
                FW_NORMAL,                               /* weight
                FALSE,                                   /* italic
                FALSE,                                   /* underline
                FALSE,                                   /* strikeout
                OEM_CHARSET,                             /* charset
                OUT_DEFAULT_PRECIS,                      /* out precision
                CLIP_DEFAULT_PRECIS,                     /* clip precision
                DEFAULT_QUALITY,                         /* quality
                FIXED_PITCH | FF_MODERN,                 /* pitch and family
                "Courier");                              /* typeface
            hOFont = GetStockObject(OEM_FIXED_FONT);
            hFFont = GetStockObject(ANSI_FIXED_FONT);
            hVFont = GetStockObject(ANSI_VAR_FONT);
            hSFont = GetStockObject(SYSTEM_FONT);
            hDFont = GetStockObject(DEVICE_DEFAULT_FONT);
            hFont = hSFont;
            GetObject(hFont, sizeof(LOGFONT), (LPSTR) &LogFont);
            strcpy(WindowTitle, AppName);
            strcat(WindowTitle, "SYSTEM");
            SetWindowText(hWnd, (LPSTR) WindowTitle);

            for (i=0; i<64; i++) {
                line[0][i] = i;
                line[1][i] = i+64;
                line[2][i] = i+128;
                line[3][i] = i+192;
            }
            break;

        case WM_PAINT:
            hDC = BeginPaint(hWnd, &ps);
            SetMyDC(hDC);
            switch (wPaint) {
                case IDM_SHOWCHARSET:
                ShowCharacterSet(hDC, hFont);
                break;
            }
            EndPaint(hWnd, &ps);
            break;

        case WM_COMMAND:
            switch (wParam) {

                /* File menu */

                case IDM_ADDFONT:

                    /* Call AddDlg() to get the filename */

                    lpAddDlg = MakeProcInstance((FARPROC) AddDlg, hInst);
                    if (DialogBox(hInst, "Add", hWnd, lpAddDlg)) {

                        /* Check to see if it is a new font name */

                        for (i = 0; i < nFontIndex; i++) {
                            if (!strcmp(FontFileName, &FontNameList[i][0])) {
                                MessageBox(hWnd, "Font already exists",
                                    "Add Font", MB_OK | MB_ICONQUESTION);
                                FreeProcInstance(lpAddDlg);
                                return (0L);
                            }
                        }

                        /* Tell Windows to add the font resource */

                        AddFontResource((LPSTR) FontFileName);

                        /* Let all applications know there is a new font
                         * resource
                         */

                        SendMessage((HWND) 0xFFFF, WM_FONTCHANGE, NULL,
                            (LONG) NULL);

                        /* Copy the name selected to the list of fonts added

                        strcpy(&FontNameList[nFontIndex++][0], FontFileName);
                    }

                    FreeProcInstance(lpAddDlg);
                    break;

                case IDM_DELFONT:
                    if (!nFontIndex) {
                        MessageBox(hWnd, "No fonts to delete",
                            "Remove Font", MB_OK | MB_ICONQUESTION);
                        break;
                    }

                    lpRemoveDlg = MakeProcInstance((FARPROC) RemoveDlg, hInst
                    if (DialogBox(hInst, "Remove", hWnd, lpRemoveDlg)) {
                        for (i = 0; i < nFontIndex; i++) {
                            if (!strcmp(FontFileName, &FontNameList[i][0])) {
                                RemoveFontResource((LPSTR) FontFileName);
                                SendMessage((HWND) 0xFFFF, WM_FONTCHANGE, NUL
                                    (LONG) NULL);
                                strcpy(&FontNameList[i][0],
                                    &FontNameList[--nFontIndex][0]);
                                break;
                            }
                        }
                    }
                    FreeProcInstance(lpRemoveDlg);
                    break;

                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;

                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance((FARPROC) About, hInst);
                    DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
                    FreeProcInstance(lpProcAbout);
                    break;

                /* Show menu */

                case IDM_SHOWSTRING:
                    ShowString(hWnd);
                    break;

                case IDM_SHOWCHARSET:
                    InvalidateRect(hWnd, (LPRECT)NULL, TRUE);
                    wPaint = wParam;
                    break;

                case IDM_SHOWLOGFONT:
                    ShowLogFont(hWnd, hFont);
                    break;

                case IDM_SHOWTEXTMETRICS:
                    ShowTextMetric(hWnd, hFont);
                    break;

                case IDM_CLEAR:
                    InvalidateRect(hWnd, (LPRECT)NULL, TRUE);
                    wPaint = 0;
                    break;

                /* Font menu */

                case IDM_OEM:
                    hFont = hOFont;
                    SetFaceName(hWnd);                  /* sets window title
                    CheckMenuItem(GetMenu(hWnd), wPrevFont, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevFont = wParam;
                    break;

                case IDM_ANSIFIXED:
                    hFont = hFFont;
                    SetFaceName(hWnd);
                    CheckMenuItem(GetMenu(hWnd), wPrevFont, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevFont = wParam;
                    break;

                case IDM_ANSIVAR:
                    hFont = hVFont;
                    SetFaceName(hWnd);
                    CheckMenuItem(GetMenu(hWnd), wPrevFont, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevFont = wParam;
                    break;

                case IDM_SYSTEM:
                    hFont = hSFont;
                    SetFaceName(hWnd);
                    CheckMenuItem(GetMenu(hWnd), wPrevFont, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevFont = wParam;
                    break;

                case IDM_DEVICEDEF:
                    hFont = hDFont;
                    SetFaceName(hWnd);
                    CheckMenuItem(GetMenu(hWnd), wPrevFont, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevFont = wParam;
                    break;

                case IDM_SELECTFONT:
                    lpSelectFont = MakeProcInstance(SelectFont, hInst);
                    if (DialogBox(hInst, "SelectFont", hWnd, lpSelectFont)) {
                        DeleteObject(hMFont);
                        hMFont = CreateFont(
                            SizeList[CurrentSize],
                            0,
                            0,
                            0,
                            FW_NORMAL,
                            FALSE,
                            FALSE,
                            FALSE,
                            CharSet[CurrentFont],
                            OUT_DEFAULT_PRECIS,
                            CLIP_DEFAULT_PRECIS,
                            DEFAULT_QUALITY,
                            PitchAndFamily[CurrentFont],
                            FontList[CurrentFont]);
                        hFont = hMFont;
                        SetFaceName(hWnd);
                    }
                    FreeProcInstance(lpSelectFont);
                    break;

                case IDM_CFONT:
                    lpCFontDlg = MakeProcInstance(CFontDlg, hInst);
                    GetObject(hMFont, sizeof(LOGFONT), (LPSTR) &CLogFont);
                    if (DialogBox(hInst, "CFont", hWnd, lpCFontDlg)) {
                        DeleteObject(hMFont);
                        hMFont = CreateFontIndirect(&CLogFont);
                        hFont = hMFont;
                        SetFaceName(hWnd);
                    }
                    FreeProcInstance(lpCFontDlg);
                    break;

                /* Options menu */

                case IDM_TEXTCOLOR:
                    lpColors = MakeProcInstance(Colors, hInst);
                    rgbColor = rgbTextColor;
                    if (DialogBox(hInst, "Colors", hWnd, lpColors))
                        rgbTextColor = rgbColor;
                    FreeProcInstance(lpColors);
                    break;

                case IDM_BACKGROUNDCOLOR:
                    lpColors = MakeProcInstance(Colors, hInst);
                    rgbColor = rgbBkColor;
                    if (DialogBox(hInst, "Colors", hWnd, lpColors))
                        rgbBkColor = rgbColor;
                    FreeProcInstance(lpColors);
                    break;

                case IDM_OPAQUE:
                    nBkMode = OPAQUE;
                    CheckMenuItem(GetMenu(hWnd), IDM_TRANSPARENT, MF_UNCHECKE
                    CheckMenuItem(GetMenu(hWnd), IDM_OPAQUE, MF_CHECKED);
                    break;

                case IDM_TRANSPARENT:
                    nBkMode = TRANSPARENT;
                    CheckMenuItem(GetMenu(hWnd), IDM_OPAQUE,  MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), IDM_TRANSPARENT,  MF_CHECKED
                    break;

                case IDM_ALIGNLEFT:
                    nAlignLCR = TA_LEFT;
                    CheckMenuItem(GetMenu(hWnd), wPrevHAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevHAlign = wParam;
                    break;

                case IDM_ALIGNCENTER:
                    nAlignLCR = TA_CENTER;
                    CheckMenuItem(GetMenu(hWnd), wPrevHAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevHAlign = wParam;
                    break;

                case IDM_ALIGNRIGHT:
                    nAlignLCR = TA_RIGHT;
                    CheckMenuItem(GetMenu(hWnd), wPrevHAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevHAlign = wParam;
                    break;

                case IDM_ALIGNTOP:
                    nAlignTBB = TA_TOP;
                    CheckMenuItem(GetMenu(hWnd), wPrevVAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevVAlign = wParam;
                    break;

                case IDM_ALIGNBASE:
                    nAlignTBB = TA_BASELINE;
                    CheckMenuItem(GetMenu(hWnd), wPrevVAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevVAlign = wParam;
                    break;

                case IDM_ALIGNBOTTOM:
                    nAlignTBB = TA_BOTTOM;
                    CheckMenuItem(GetMenu(hWnd), wPrevVAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevVAlign = wParam;
                    break;
            }
            break;

        case WM_LBUTTONUP:
            ptCurrent.x = LOWORD(lParam);
            ptCurrent.y = HIWORD(lParam);
            ShowString(hWnd);
            break;

        case WM_FONTCHANGE:
            GetFonts(hWnd);
            break;

        case WM_DESTROY:

            /* Remove any fonts that were added */

            for (i = 0; i < nFontIndex; i++)
                RemoveFontResource((LPSTR) &FontNameList[i][0]);

            /* Notify any other applications know the fonts have been deleted

            SendMessage((HWND) 0xFFFF, WM_FONTCHANGE, NULL, (LONG) NULL);
            PostQuitMessage(0);
            break;

        default:
            return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (0L);
}

/****************************************************************************

    FUNCTION: Metric(HWND, unsigned, WORD, LONG)

    PURPOSE: Modeless dialog box to display metric font information

****************************************************************************/

BOOL FAR PASCAL Metric(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:
            SetDlgItemInt(hDlg, IDMB_HEIGHT, TextMetric.tmHeight, FALSE);
            SetDlgItemInt(hDlg, IDMB_ASCENT, TextMetric.tmAscent, FALSE);
            SetDlgItemInt(hDlg, IDMB_DESCENT, TextMetric.tmDescent, FALSE);
            SetDlgItemInt(hDlg, IDMB_INTERNALLEADING,
                TextMetric.tmInternalLeading, FALSE);
            SetDlgItemInt(hDlg, IDMB_EXTERNALLEADING,
                TextMetric.tmExternalLeading, FALSE);
            SetDlgItemInt(hDlg, IDMB_AVECHARWIDTH, TextMetric.tmAveCharWidth,
                FALSE);
            SetDlgItemInt(hDlg, IDMB_MAXCHARWIDTH, TextMetric.tmMaxCharWidth,
                FALSE);
            SetDlgItemInt(hDlg, IDMB_WEIGHT, TextMetric.tmWeight, FALSE);
            SetDlgItemInt(hDlg, IDMB_ITALIC, TextMetric.tmItalic, FALSE);
            SetDlgItemInt(hDlg, IDMB_UNDERLINED, TextMetric.tmUnderlined,
                FALSE);
            SetDlgItemInt(hDlg, IDMB_STRUCKOUT, TextMetric.tmStruckOut, FALSE
            SetDlgItemInt(hDlg, IDMB_FIRSTCHAR, TextMetric.tmFirstChar, FALSE
            SetDlgItemInt(hDlg, IDMB_LASTCHAR, TextMetric.tmLastChar, FALSE);
            SetDlgItemInt(hDlg, IDMB_DEFAULTCHAR, TextMetric.tmDefaultChar,
                FALSE);
            SetDlgItemInt(hDlg, IDMB_BREAKCHAR, TextMetric.tmBreakChar, FALSE
            SetDlgItemInt(hDlg, IDMB_PITCHANDFAMILY,
                TextMetric.tmPitchAndFamily, FALSE);
            SetDlgItemInt(hDlg, IDMB_CHARSET, TextMetric.tmCharSet, FALSE);
            SetDlgItemInt(hDlg, IDMB_OVERHANG, TextMetric.tmOverhang, FALSE);
            SetDlgItemInt(hDlg, IDMB_DIGITIZEDASPECTX,
                TextMetric.tmDigitizedAspectX, FALSE);
            SetDlgItemInt(hDlg, IDMB_DIGITIZEDASPECTY,
    TextMetric.tmDigitizedAspectY, FALSE);
            return (TRUE);

        case WM_CLOSE:
            DestroyWindow(hDlg);
            break;
    }
    return (FALSE);
}

/****************************************************************************

    FUNCTION: Log(HWND, unsigned, WORD, LONG)

    PURPOSE: Displays logical font information

****************************************************************************/

BOOL FAR PASCAL Log(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{

    switch (message) {
        case WM_INITDIALOG:
            SetDlgItemInt(hDlg, IDMI_HEIGHT, LogFont.lfHeight, FALSE);
            SetDlgItemInt(hDlg, IDMI_WIDTH, LogFont.lfWidth, FALSE);
            SetDlgItemInt(hDlg, IDMI_ESCAPEMENT, LogFont.lfEscapement, FALSE)
            SetDlgItemInt(hDlg, IDMI_ORIENTATION, LogFont.lfOrientation, FALS
            SetDlgItemInt(hDlg, IDMI_WEIGHT, LogFont.lfWeight, FALSE);
            SetDlgItemInt(hDlg, IDMI_ITALIC, LogFont.lfItalic, FALSE);
            SetDlgItemInt(hDlg, IDMI_UNDERLINED, LogFont.lfUnderline, FALSE);
            SetDlgItemInt(hDlg, IDMI_STRIKEOUT, LogFont.lfStrikeOut, FALSE);
            SetDlgItemInt(hDlg, IDMI_CHARSET, LogFont.lfCharSet, FALSE);
            SetDlgItemInt(hDlg, IDMI_OUTPRECISION, LogFont.lfOutPrecision,
                FALSE);
            SetDlgItemInt(hDlg, IDMI_CLIPPRECISION, LogFont.lfClipPrecision,
                FALSE);
            SetDlgItemInt(hDlg, IDMI_QUALITY, LogFont.lfQuality, FALSE);
            SetDlgItemInt(hDlg, IDMI_PITCHANDFAMILY,
                LogFont.lfPitchAndFamily, FALSE);
            return (TRUE);

        case WM_CLOSE:
            DestroyWindow(hDlg);
            break;

    }
    return (FALSE);
}

/****************************************************************************

    FUNCTION: AddDlg(HWND, unsigned, WORD, LONG)

    PURPOSE: Used to add a font

    COMMENTS:

        This dialog box displays all the availble font files on the currently
        selected directory, and lets the user select a font to add.

****************************************************************************/

BOOL FAR PASCAL AddDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_COMMAND:
            switch (wParam) {
                case ID_LISTBOX:

                    switch (HIWORD(lParam)) {
                        case LBN_SELCHANGE:
                            /* If item is a directory name, append "*.*" */
                            if (DlgDirSelect(hDlg, str, ID_LISTBOX))
                                strcat(str, DefSpec);

                            SetDlgItemText(hDlg, ID_EDIT, str);
                            SendDlgItemMessage(hDlg,
                                ID_EDIT,
                                EM_SETSEL,
                                NULL,
                                MAKELONG(0, 0x7fff));
                            break;

                        case LBN_DBLCLK:
                            goto CheckSelection;
                            break;

                    }                              /* end of ID_LISTBOX case
                    return (TRUE);

                case IDOK:
CheckSelection:
                    /* Get the filename from the edit control */

                    GetDlgItemText(hDlg, ID_EDIT, str, 128);
                    GetDlgItemText(hDlg, ID_PATH, DefPath, 128);

                    /* Check for wildcard.  If found, use the string as a new
                     * search path.
                     */

                    if (strchr(str, '*') ||
                        strchr(str, '?')) {

                    /* Separate filename from path.  The path is stored in
                     * str which is discarded if null, else it is used for a
                     * search path.
                     */

                        SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,
                            (LPSTR) str);
                        if (str[0])
                            strcpy(DefPath, str);

                        UpdateListBox(hDlg);
                        return (TRUE);
                    }

                    /* Ignore it if no filename specified */

                    if (!str[0]) {
                        MessageBox(hDlg, "No filename specified.",
                            NULL, MB_OK | MB_ICONQUESTION);
                        return (TRUE);
                    }

                    /* Append the default extension if needed */

                    strcpy(FontFileName, DefPath);
                    strcat(FontFileName, str);
                    AddExt(FontFileName, DefExt);
                    EndDialog(hDlg, TRUE);
                    return (TRUE);

                case IDCANCEL:

                    /* Let the caller know the user cancelled */

                    EndDialog(hDlg, FALSE);
                    return (TRUE);
            }
            break;

        case WM_INITDIALOG:
            SetWindowText(hDlg, (LPSTR) "Add Font Resource");
            strcpy(DefSpec, "*.fon");
            UpdateListBox(hDlg);
            SetDlgItemText(hDlg, ID_EDIT, DefSpec);
            SendDlgItemMessage(hDlg, ID_EDIT, EM_SETSEL, NULL,
                MAKELONG(0, 0x7fff));
            SetFocus(GetDlgItem(hDlg, ID_EDIT));
            return (FALSE);
    }
    return FALSE;
}

/****************************************************************************

    FUNCTION: RemoveDlg(HANDLE)

    PURPOSE: Used to remove a font

    COMMENTS:

        This dialog box displays all fonts which have been added to the syste
        and lets the user select which font to delete.

****************************************************************************/

BOOL FAR PASCAL RemoveDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    WORD index;
    int i;

    switch (message) {
        case WM_COMMAND:

            switch (wParam) {
                case ID_LISTBOX:

                    switch (HIWORD(lParam)) {
                        case LBN_SELCHANGE:
                            index = SendDlgItemMessage(hDlg,
                                ID_LISTBOX,
                                LB_GETCURSEL,         /* get index command
                                NULL,
                                (LONG) NULL);
                            SendDlgItemMessage(hDlg,
                                ID_LISTBOX,
                                LB_GETTEXT,           /* copy string command
                                index,
                                (LONG) (LPSTR) FontFileName);
                            SetDlgItemText(hDlg, ID_EDIT, FontFileName);
                            break;

                        case LBN_DBLCLK:
                            GetDlgItemText(hDlg, ID_EDIT, FontFileName, 128);
                            EndDialog(hDlg, TRUE);
                            return (TRUE);
                    }
                    return (TRUE);

                case IDOK:

                    /* Get the filename from the edit control */

                    GetDlgItemText(hDlg, ID_EDIT, FontFileName, 128);

                    /* Ignore it if no filename specified */

                    if (!FontFileName[0]) {
                        MessageBox(hDlg, "No filename specified.",
                            NULL, MB_OK | MB_ICONQUESTION);
                        return (TRUE);
                    }

                    EndDialog(hDlg, TRUE);
                    return (TRUE);

                case IDCANCEL:
                    EndDialog(hDlg, FALSE);
                    return (TRUE);
            }
            break;

        case WM_INITDIALOG:
            SetWindowText(hDlg, (LPSTR) "Remove Font Resource");
            for (i = 0; i < nFontIndex; i++)
                SendDlgItemMessage(hDlg,
                    ID_LISTBOX,
                    LB_ADDSTRING,
                    NULL,
                    (LONG)(char far *) &FontNameList[i][0]);

            SetFocus(GetDlgItem(hDlg, ID_EDIT));
            return (FALSE);
    }
    return FALSE;
}

/****************************************************************************

    FUNCTION: UpdateListBox(HWND);

    PURPOSE: Update the list box of OpenDlg

****************************************************************************/

void UpdateListBox(hDlg)
HWND hDlg;
{
    strcpy(str, DefPath);
    strcat(str, DefSpec);
    DlgDirList(hDlg, str, ID_LISTBOX, ID_PATH, 0x4010);
    SetDlgItemText(hDlg, ID_EDIT, DefSpec);
}

/****************************************************************************

    FUNCTION: AddExt(PSTR, PSTR);

    PURPOSE: Add default extension

/***************************************************************************/

void AddExt(Name, Ext)
PSTR Name, Ext;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr != '.')
        strcat(Name, Ext);
}

/****************************************************************************

    FUNCTION: SeparateFile(HWND, LPSTR, LPSTR, LPSTR)

    PURPOSE: Separate filename and pathname

    COMMENTS:

        This function takes a source filespec and splits it into a path and a
        filename, and copies these into the strings specified.  Because it
        uses the AnsiPrev call, it will work in any language.

****************************************************************************/

void SeparateFile(hDlg, lpDestPath, lpDestFileName, lpSrcFileName)
HWND hDlg;
LPSTR lpDestPath, lpDestFileName, lpSrcFileName;
{
    LPSTR lpTmp;

    lpTmp = lpSrcFileName + (long) _lstrlen(lpSrcFileName);
    while (*lpTmp != ':' && *lpTmp != '\\' && lpTmp > lpSrcFileName)
        lpTmp = AnsiPrev(lpSrcFileName, lpTmp);
    if (*lpTmp != ':' && *lpTmp != '\\') {                  /* no path given
        _lstrcpy(lpDestFileName, lpSrcFileName);
        lpDestPath[0] = 0;
        return;
    }
    _lstrcpy(lpDestFileName, lpTmp + 1L);
    _lstrncpy(lpDestPath, lpSrcFileName, (int) (lpTmp - lpSrcFileName) + 1);
    lpDestPath[(lpTmp - lpSrcFileName) + 1] = 0;
}

/****************************************************************************

    FUNCTION: _lstrlen(LPSTR)

    PURPOSE:  uses a long far pointer to the string, returns the length

****************************************************************************/

int _lstrlen(lpStr)
LPSTR lpStr;
{
    int i;
    for (i=0; *lpStr++; i++);
    return (i);
}

/****************************************************************************

    FUNCTION: _lstrncpy(LPSTR, LPSTR)

    PURPOSE:  FAR version of strncpy()

****************************************************************************/

void _lstrncpy(lpDest, lpSrc, n)
LPSTR lpDest, lpSrc;
int n;
{
    while (n--)
        if(!(*lpDest++ = *lpSrc++))
            return;
}

/****************************************************************************

    FUNCTION: _lstrcpy(LPSTR, LPSTR)

    PURPOSE:  FAR version of strcpy()

****************************************************************************/

void _lstrcpy(lpDest, lpSrc)
LPSTR lpDest, lpSrc;
{
    while(*lpDest++ = *lpSrc++);
}

/****************************************************************************

    FUNCTION: SetFaceName(HWND)

    PURPOSE: Retireves current font's face name, places it in WindowTitle

****************************************************************************/

SetFaceName(hWnd)
HWND hWnd;
{
    char buf[80];
    HDC hDC;

    hDC = GetDC(hWnd);
    SelectObject(hDC, hFont);
    strcpy(WindowTitle, AppName);
    GetTextFace(hDC, 80, buf);
    strcat(WindowTitle, buf);
    SetWindowText(hWnd, (LPSTR) WindowTitle);

    ReleaseDC(hWnd, hDC);
}

/****************************************************************************

    FUNCTION: About(HWND, unsigned, WORD, LONG)

    PURPOSE:  Processes messages for "About" dialog box

    MESSAGES:

        WM_INITDIALOG - initialize dialog box
        WM_COMMAND    - Input received

****************************************************************************/

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:
            return (TRUE);

        case WM_COMMAND:
            if (wParam == IDOK) {
                EndDialog(hDlg, TRUE);
                return (TRUE);
            }
            return (TRUE);
    }
    return (FALSE);
}


TTY.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\TTY\TTY.C

//

//  FILE:    TTY.c

//  PURPOSE: This sample terminal application demonstrates
//          the basic uses of Windows Communications functions.
//          It also shows the basic structure for a terminal program.

//  FUNCTIONS:
//          WinMain() - Initializes app, calls all other functions.
//          TTYWndProc() - Window procedure for terminal window.
//          About() - Window procedure for About dialog box.
//          AboutInit() - Initialization procedure for About dialog box.
//          SettingDlgProc() - Window procedure for Comm Settings dialog.
//

#include <windows.h>
#include <string.h>
#include "wstdio.h"
#include "tty.h"


//========================================================================\\

// Declarations

//========================================================================\\

#define COM1  "com1"
#define COM2  "com2"
#define CommSettings "com1:96,n,8,1"

#define BufMax      160     // Size of line buffer used for displaying text
#define cbInBuf    1024    // Size of receive buffer
#define cbOutBuf   128     // size of transmit buffer

DCB CommDCB;               // DCB for comm port
int PortID;                // The comm port id
COMSTAT CommStat;          // COMSTAT info buffer for comm port
char MsgBuff[BufMax + 1];  // Buffer to hold incoming characters
BOOL bConnected;           // Flag to indicate if connected
short nCommErr;            // Storage for communications error data
WORD wCommEvt;             // Storage for communications event data

HWND hTTYWnd;              // Handle to application window

char sTemp[256];

static HANDLE hInst;       // Global instance handle
FARPROC lpprocAbout;       // Pointer to "About" dialog box procedure
FARPROC lpfnOldTTYProc;    // Pointer to TTY proc prior to subclassing

long FAR PASCAL TTYWndProc(HWND, unsigned, WORD, LONG);


//========================================================================\\

// FUNCTION: About(HWND, unsigned, WORD, LONG)

// PURPOSE:  Processes messages for About dialog box.

//========================================================================\\

BOOL FAR PASCAL About( hDlg, message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    if (message == WM_COMMAND
  || message == WM_LBUTTONDOWN) {

  // if we click the mouse in the dialog, or press 'Enter', then go away
        EndDialog( hDlg, TRUE );
        return TRUE;
        }
    else if (message == WM_INITDIALOG)
        return TRUE;
    else return FALSE;
}


//========================================================================\\

// FUNCTION: AboutInit(HWND, HANDLE)

// PURPOSE:  About box initialization.

//========================================================================\\

BOOL AboutInit(HWND hWnd, HANDLE hInstance)
{
    HMENU hMenu;

    /* Bind callback function with module instance */
    lpprocAbout = MakeProcInstance( (FARPROC)About, hInstance );

    return TRUE;
}


//========================================================================\\

// FUNCTION: SettingDlgProc(HWND, unsigned, WORD, LONG)

// PURPOSE:  Processes messages for Communications Settings dialog.

//========================================================================\\

BOOL FAR PASCAL SettingDlgProc( hDlg, message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
   int theButton;
   static DCB dlgDCB;

   switch(message) {
      case WM_COMMAND:

         // if the Ok button is pressed the new settings are saved

         if(wParam == IDOK) {
            // save the new settings
            CommDCB = dlgDCB;
            // close the dialog
            EndDialog( hDlg, TRUE );

         } else

         // otherwise, the settings are not saved and changes are discarded

            if(wParam == IDCANCEL)
               EndDialog(hDlg,FALSE);
            else
               if(HIWORD(lParam) == BN_CLICKED) {

                  // if a button is clicked and it is a radiobutton,
                  // then we uncheck the current selection and check
                  // the one that was clicked.

                  HWND hStartWnd = GetDlgItem(hDlg,wParam);

                  if(LOWORD(GetWindowLong(hStartWnd,GWL_STYLE))
                     == BS_AUTORADIOBUTTON){
                     HWND hCurrWnd = hStartWnd;
                     do{
                        hCurrWnd = GetNextDlgGroupItem(hDlg,hCurrWnd,1);
                        SendMessage(hCurrWnd, BM_SETCHECK, hCurrWnd == hStart
                        } while(hCurrWnd != hStartWnd);
                  }

      // now we set the appropriate value in the DCB for the
      // button that was clicked

      switch (wParam){
                            case RBBAUD_300: dlgDCB.BaudRate = 300; break;
                            case RBBAUD_1200: dlgDCB.BaudRate = 1200; break;
                            case RBBAUD_2400: dlgDCB.BaudRate = 2400; break;
          case RBBAUD_9600: dlgDCB.BaudRate = 9600; break;

                            case RBDBITS_7: dlgDCB.ByteSize = 7; break;
          case RBDBITS_8: dlgDCB.ByteSize = 8; break;

                            case RBPARITY_EVEN: dlgDCB.Parity = EVENPARITY; b
                            case RBPARITY_ODD: dlgDCB.Parity = ODDPARITY; bre
          case RBPARITY_NONE: dlgDCB.Parity = NOPARITY; break;

                            case RBSBITS_2: dlgDCB.StopBits = TWOSTOPBITS; br
          case RBSBITS_1: dlgDCB.StopBits = ONESTOPBIT; break;

          case CBXONXOFF: dlgDCB.fInX = dlgDCB.fInX?0:1; break;

                            case RBPORT_COM1: dlgDCB.Id = 1; break;
                            case RBPORT_COM2: dlgDCB.Id = 2; break;
                        }
        } else
                       return FALSE;

            break;

  case WM_INITDIALOG:

    // make a copy of the current DCB
    // we will change this copy, and copy back to the original
    // if we click Ok

    dlgDCB = CommDCB;

    // set buttons as reflected by the current DCB

    // if the current port isn't com2, set com1 button
    theButton = (dlgDCB.Id == 2 ? RBPORT_COM2 : RBPORT_COM1);
    SendDlgItemMessage(hDlg,theButton,BM_SETCHECK,1,0L);

    // set baud button
                switch(dlgDCB.BaudRate){
                    case 300: theButton = RBBAUD_300; break;
                    case 1200: theButton = RBBAUD_1200; break;
                    case 2400: theButton = RBBAUD_2400; break;
                    case 9600: theButton = RBBAUD_9600; break;
                    default: theButton = RBBAUD_300; break;
    }
    SendDlgItemMessage(hDlg,theButton,BM_SETCHECK,1,0L);

    // set data bits button. if it's not 8, then it's 7
                theButton = (dlgDCB.ByteSize == 8 ? RBDBITS_8 : RBDBITS_7);
    SendDlgItemMessage(hDlg,theButton,BM_SETCHECK,1,0L);

    // set parity button
                switch(dlgDCB.Parity){
                    case EVENPARITY: theButton = RBPARITY_EVEN; break;
                    case ODDPARITY: theButton = RBPARITY_ODD; break;
                    case NOPARITY: theButton = RBPARITY_NONE; break;
                    default: theButton = RBPARITY_NONE; break;
                }
    SendDlgItemMessage(hDlg,theButton,BM_SETCHECK,1,0L);

    // set stop bits button. if it's not 2, then it's 1
                theButton = (dlgDCB.StopBits == TWOSTOPBITS ? RBSBITS_2 : RBS
    SendDlgItemMessage(hDlg,theButton,BM_SETCHECK,1,0L);

    // set Xon/Xoff check box to on or off
    SendDlgItemMessage(hDlg,CBXONXOFF,BM_SETCHECK,dlgDCB.fInX,0L);

            break;

        default:
            return FALSE;
    }
    return TRUE;
}


//========================================================================\\

// FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)

// PURPOSE:  Main procedure of the application.

//========================================================================\\

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    BOOL bMsgAvail;
    short iNumRead,iError;

    hInst = hInstance;

    // initialize the stdio window library
    if(!hPrevInstance)
        if(!stdioInit(hInstance)) return FALSE;

    // create a stdio window
    if(!(hTTYWnd = CreateStdioWindow(
                      "TTY",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      NULL,
                      hInstance,
                      TRUE)))
        return FALSE;

    // subclass the stdio window

    lpfnOldTTYProc = (FARPROC) SetWindowLong(hTTYWnd,GWL_WNDPROC,
                                          (DWORD) TTYWndProc);

    // add the about box to the system menu
    AboutInit(hTTYWnd,hInstance);

    // add the terminal menu
    SetMenu(hTTYWnd,LoadMenu(hInstance, "TTYMENU"));

    // set the application icon
    SetClassWord(hTTYWnd, GCW_HICON,
                 LoadIcon( hInstance, MAKEINTRESOURCE(TTYICON) ));

    bConnected = FALSE;

    // initialize the DCB to default settings
    if(BuildCommDCB(CommSettings,&CommDCB) != 0) {
        MessageBox(GetFocus(),"Error Building DCB!","",MB_OK);
    }

    CommDCB.CtsTimeout = 100;         // Set Cts Timeout value
    CommDCB.DsrTimeout = 100;         // Set Dsr Timeout value
    CommDCB.fOutX = 1;           // output Xon/Xoff flow control on
    CommDCB.fInX = 1;           // input Xon/Xoff flow control on
    CommDCB.XonChar = 0x11;         // specify the Xon character
    CommDCB.XoffChar = 0x13;         // specify the Xoff character
    CommDCB.fNull = 1;           // strip null characters
    CommDCB.XonLim = 30;         // distance from queue empty to Xon
    CommDCB.XoffLim = (cbInBuf/2) + 1; // distance from queue full to Xoff
    CommDCB.fBinary = 0;

    // show the window
    ShowWindow( hTTYWnd, cmdShow );
    UpdateWindow( hTTYWnd );

    // PeekMessage loop to poll the comm port and pull messages from the queu
    // if there is a message available, process it.
    // otherwise, check the port and handle any available characters.

    while(TRUE){
        bMsgAvail = PeekMessage(&msg,NULL,0,0,PM_REMOVE);

        if(bMsgAvail){

            if(msg.message == WM_QUIT) break;

            TranslateMessage((LPMSG)&msg);
            DispatchMessage((LPMSG)&msg);

        } else {

            // check the comm port and process any available
            // characters. you could also use a timer instead, and have
            // the timer case of the wndproc check the port.
            if(bConnected){

                // get the CommStat record and get the # of characters availa
    GetCommError(CommDCB.Id,&CommStat);

                // get the number of characters available
                iNumRead = CommStat.cbInQue;

                if(iNumRead > 0) {

                    // get the number of characters rounded to the buffer siz
                    if(iNumRead > BufMax) iNumRead = BufMax;

                    // read the characters
                    iNumRead = ReadComm(CommDCB.Id,MsgBuff,
                                        iNumRead);

                    // check for errors
                    if(iNumRead < 0) {
                        iNumRead = -iNumRead;
                        nCommErr = GetCommError(CommDCB.Id,&CommStat);
                        // clear the event mask
      wCommEvt = GetCommEventMask(CommDCB.Id,0xFFFF);
                        // display what the error was
                        LoadString(hInst, nCommErr, sTemp, 20);
                        MessageBox(GetFocus(), sTemp, "Comm Read Error!",MB_O
                    }

                    MsgBuff[iNumRead] = '\0';

                    // send the characters to the tty window for processing
                    SendMessage(hTTYWnd,COMM_CHARS,
        iNumRead,(LONG)(LPSTR)MsgBuff);
        //wputs((LPSTR) MsgBuff);  // could just do this instead
                }


            }
        }
    }

}

//========================================================================\\

// FUNCTION: TTYWndProc(HWND, unsigned, WORD, LONG)

// PURPOSE:  Processes messages for the terminal window.

//========================================================================\\

long FAR PASCAL TTYWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC   lpSettingDlgProc;
    char      szErr[22];
    unsigned  nErr;

    switch (message)
    {

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_ENDSESSION:
  if (wParam && bConnected)
      SendMessage(hWnd, WM_COMMAND, TTYCONNECT, 1L);
  break;

    case WM_CLOSE:
        // disconnect if still connected
        if(bConnected)SendMessage(hWnd,WM_COMMAND,TTYCONNECT,0L);
        // go ahead and close down
        return CallWindowProc(lpfnOldTTYProc,hWnd,
                              message,wParam,lParam);
        break;

    case WM_COMMAND:
        switch(wParam){

        case IDSABOUT:
            DialogBox( hInst, MAKEINTRESOURCE(ABOUTBOX), hWnd, lpprocAbout );
            break;

        case TTYEXIT:
            PostMessage(hWnd,WM_CLOSE,0,0L);
            break;

        case TTYCONNECT:
            // connect to port if not already connected
            if(!bConnected){
    if((PortID = OpenComm((CommDCB.Id == 2?COM2:COM1),cbInBuf,cbOutBuf)) < 0)
                    MessageBox(hWnd,"Error Opening Comm Port!","",MB_OK);
                    break;
                }

                FlushComm(PortID,0);
                FlushComm(PortID,1);

    CommDCB.Id = PortID;
    if(CommDCB.fInX) {
        CommDCB.fOutX = 1;      // enable output Xon/Xoff flow ctl
        CommDCB.fInX = 1;      // enable input Xon/Xoff flow ctl
        CommDCB.fRtsflow = 0;   // disable hardware flow ctl
        CommDCB.fDtrflow = 0;   // disable hardware flow ctl
    } else {
        CommDCB.fOutX = 0;      // disable ouput Xon/Xoff flow ctl
        CommDCB.fInX = 0;      // disable input Xon/Xoff flow ctl
        CommDCB.fRtsflow = 1;   // enable hardware flow ctl
        CommDCB.fDtrflow = 1;   // enable hardware flow ctl
    }


                if(SetCommState(&CommDCB) !=0 ){
                    MessageBox(hWnd,"Error Setting CommState!","",MB_OK);
                    break;
                }
                bConnected = TRUE;
                CheckMenuItem(GetMenu(hWnd),TTYCONNECT,MF_CHECKED);
                EnableMenuItem(GetMenu(hWnd),TTYSETTINGS,MF_DISABLED | MF_GRA
                MessageBox(hWnd,"Connection was successful.","",MB_OK);

            }else{
                // otherwise disconnect
                FlushComm(CommDCB.Id,0);
                FlushComm(CommDCB.Id,1);
                CloseComm(CommDCB.Id);
    if (!lParam)
                    MessageBox(hWnd,"Connection closed.","",MB_OK);
                bConnected = FALSE;
                CheckMenuItem(GetMenu(hWnd),TTYCONNECT,MF_UNCHECKED);
                EnableMenuItem(GetMenu(hWnd),TTYSETTINGS,MF_ENABLED);

            }
            break;

        case TTYSETTINGS:
            // settings dialog
            lpSettingDlgProc = MakeProcInstance(SettingDlgProc,hInst);
            DialogBox(hInst,"SETTINGSDLG",hWnd,lpSettingDlgProc);
            FreeProcInstance(lpSettingDlgProc);
            break;
        }
        break;

    case WM_CHAR:
  if(!bConnected) break;

  // if we're connected, send any keyboard characters to the port

        nCommErr = WriteComm(CommDCB.Id,(LPSTR) &wParam,1);
        if(nCommErr != 1) {
      nCommErr = GetCommError(CommDCB.Id,&CommStat);
            if(nCommErr != 0) {
    sTemp[0] = 0;
    for (nErr = 1; nErr != 0; nErr = nErr << 1) {
        if (nErr & nCommErr) {
      LoadString(hInst, nErr, szErr, 20);
      strcat(sTemp, szErr);
      strcat(sTemp, "\n");
        }
    }
    MessageBox(hWnd, sTemp, "Comm Write Error!", MB_OK);
            }
      wCommEvt = GetCommEventMask(CommDCB.Id, 0xFFFF);
        }
        break;

    case COMM_CHARS:
  // display available characters
        if(wParam > 0)
            wputs((LPSTR) lParam);

        break;

    // Pass all other messages to class's window procedure, since window
    // was subclassed
    default:
        return CallWindowProc(lpfnOldTTYProc,hWnd,
                              message,wParam,lParam);
        break;
    }
    return(0L);
}


WSTDIO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\TTY\WSTDIO.C

//

//  FILE:    WSTDIO.c

//  PURPOSE: Contains functions for managing a standard I/O window.
//          Provides a means for easily sending text to a window
//          for debugging, etc.

//  FUNCTIONS:
//          SetupStdioDC() - Initializes DC.
//          ResetStdioDC() - Selects former font into DC.
//          GetStdioLine() - Returns pointer to specified line in buffer.
//          StdioUpdate() - Scroll and update displayed text.
//          putStdio() - Process I/O window messages.
//          StdioPaint() - Paint procedure for I/O window.
//          InitStdio() - Initialize values used by I/O window.
//          stdioInit() - Define/register I/O window class.
//          wopen() - Create a default I/O window.
//          CreateStdioWindow() - Create a customized I/O window.
//          wputs() - Puts a string in the I/O window.
//          StdioWndProc() - Processes messages for the I/O window.
//


#include <windows.h>
#include "wstdio.h"

//========================================================================\\

// Declarations

//========================================================================\\

#define MaxLines   25
#define MaxLine    MaxLines - 1
char sScrBuff[MaxLines][81];  // Array of characters on TTY
                                 // could make this heap object so can reallo
short nFirstLine;    // Index of first line on TTY in the array
short nLastLine;    // Index of last line on TTY in the array

short nCurrPos;     // Current TTY line output position
short nStdioCharWidth,
      nStdioCharHeight;   // width and height of Stdio font chars


DWORD StdiobkRGB;                      // background color
DWORD StdiotextRGB;                    // text color
#define Stdio_FONT SYSTEM_FIXED_FONT   // font used for display
HFONT hOldFont;
HWND hWndStdio = NULL;                 // Handle to standard I/O window
HANDLE hStdioInst;
BOOL bStdioQuit;
BOOL bInited = FALSE;


//========================================================================\\

// FUNCTION: SetupStdioDC(HWND, HDC)

// PURPOSE:  Sets up the I/O window DC. Called at GetDC/BeginPaint time.

//========================================================================\\

void SetupStdioDC(HWND hWnd, HDC hDC)
{
    RECT rClRect;

    GetClientRect(hWnd,&rClRect);

    // set origin to 25(+1 extra) lines from the bottom of the window
    SetViewportOrg(hDC,0,rClRect.bottom - ((MaxLines+1) * nStdioCharHeight));

    SetMapMode(hDC, MM_ANISOTROPIC);

    // Set the extents such that one unit horizontally or
    // vertically is one character width or height.
    SetWindowExt(hDC,1,1);

    // Set the viewport such that the last line in the buffer is
    // displayed at the bottom of the window.
    SetViewportExt(hDC,nStdioCharWidth,nStdioCharHeight);

    // Set the background mode to opaque, and select the font.
    SetBkMode(hDC,OPAQUE);
    hOldFont = SelectObject(hDC,GetStockObject(Stdio_FONT));

}


//========================================================================\\

// FUNCTION: ResetStdioDC(HDC)

// PURPOSE:  Prepare to release the DC by selecting the system font.

//========================================================================\\

void ResetStdioDC(HDC hDC)
{
    SelectObject(hDC,hOldFont);
}



//========================================================================\\

// FUNCTION: GetStdioLine(short)

// PURPOSE:  Return a pointer to the specified line of the display.

//========================================================================\\

char *GetStdioLine(short ndx)
{
    short pos;

    // find the first line (one past the last line since we have a
    // circular buffer). index to the desired line from there.
    pos = nLastLine + 1;
    if(pos == MaxLines) pos = 0;

    pos = pos + ndx;
    if(pos > MaxLine) pos = pos - MaxLines;

    return(sScrBuff[pos]);
}



//========================================================================\\

// FUNCTION: StdioUpdate(HWND, HDC, int)

// PURPOSE:  Scroll the window by the number of lines we have received,
//           and display the text in the invalidated areas.

//========================================================================\\

void StdioUpdate(HWND hWnd, HDC hDC, int iLinesOut)
{
    RECT rcRect;

    if(iLinesOut > 0){

         // scroll screen by number of lines received
   GetClientRect(hWnd,&rcRect);
   rcRect.bottom -= nStdioCharHeight;

   ScrollWindow(hWnd,0,-(nStdioCharHeight * iLinesOut),&rcRect,NULL);
    }

    UpdateWindow(hWnd);
}


//========================================================================\\

// FUNCTION: putStdio(HWND, HDC, WORD, LPSTR)

// PURPOSE:  Process incoming text to Stdio window.

//========================================================================\\

void putStdio(HWND hWnd, HDC hDC, WORD wParam, LPSTR lParam)
{
    short i, j;
    char *sBuffer;
    RECT rClRect, rcInvalid;
    char *psLine;
    short iLinesOut = 0;    // # of lines to scroll

    sBuffer = sScrBuff[nLastLine]; // pointer to current line

    // scan the text, handle any special characters, and display the rest.

    for(i=0; i<wParam; i++){
  switch(lParam[i]) {

        case '\r': // return
            // move to the start of the line
      nCurrPos = 0;   // reset the current position in the line
            break;

        case '\n': // new line

      // "scroll" the window
      ++iLinesOut;    // increment lines to scroll
      nCurrPos = 0;   // reset the current position in the line

      ++nLastLine;
      if(nLastLine > MaxLine) nLastLine = 0;

            // clear the new line
      sBuffer = sScrBuff[nLastLine];
      for(j=0; j<80; j++) sBuffer[j] = '\0';
            break;

        case '\b': // backspace

            // move back one space
      if(nCurrPos > 0) {

    --nCurrPos;
    sBuffer[nCurrPos] = '\0';
    rcInvalid.top = MaxLine; rcInvalid.bottom = MaxLine + 1;
    rcInvalid.left = nCurrPos;
    rcInvalid.right = nCurrPos + 1;
    LPtoDP(hDC,(POINT *) &rcInvalid, 2);

    // invalidate the area so that it gets redrawn
    InvalidateRect(hWnd,&rcInvalid, TRUE);

      }
      break;

  case '\t':
      // ignore tabs for now
      break;

        default:
            //add char to buffer
      if(nCurrPos < 80){

    // put the character in the screen buffer
    sBuffer[nCurrPos] = lParam[i]; // add char to screen line

    // calculate area to invalidate
    rcInvalid.top = MaxLine; rcInvalid.bottom = MaxLine + 1;
    rcInvalid.left = nCurrPos;
    ++nCurrPos;
    rcInvalid.right = nCurrPos;

    // only need to invalidate the area if it is on the last line
    if(iLinesOut == 0) {
        LPtoDP(hDC,(POINT *) &rcInvalid, 2);
        // invalidate the area so that it gets redrawn
        InvalidateRect(hWnd,&rcInvalid, FALSE);
    }
            }
            break;
  }
  // force scroll after 2 lines. you will scroll faster if you increase
  // this, but it may not look good.

  if(iLinesOut > 2) {
      StdioUpdate(hWnd, hDC, iLinesOut);
      iLinesOut = 0;
  }
    }

    // force scroll and update at the end of each bunch of characters.
    StdioUpdate(hWnd, hDC, iLinesOut);
}

//========================================================================\\

// FUNCTION: StdioPaint(HWND)

// PURPOSE:  The I/O window paint procedure.  Draws necessary text in
//           the window.

//========================================================================\\

void StdioPaint(HWND hWnd )
{
    char *psLine;
    register int i;
    PAINTSTRUCT ps;
    HDC hDC;
    RECT rcUpdate, rcClient;
    int nVPaintBeg, nVPaintEnd, nHPaintBeg, nHPaintEnd;

    hDC = BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
    SetupStdioDC(hWnd,hDC);

    rcUpdate = ps.rcPaint;
    DPtoLP(hDC,(POINT *) &rcUpdate, 2);

    // calculate first and last lines to update
    nVPaintBeg = max (0, rcUpdate.top);
    nVPaintEnd = min (MaxLines, rcUpdate.bottom);

    // calculate the first and last columns to update
    nHPaintBeg = max (0, rcUpdate.left);
    nHPaintEnd = min (80, rcUpdate.right);

    // display the lines that need to be drawn
    for(i=nVPaintBeg; i<nVPaintEnd; i++){
  psLine = GetStdioLine(i) + nHPaintBeg;
        TextOut(hDC,
    nHPaintBeg,
                i,
    psLine,
    strlen(psLine));
    }
    ResetStdioDC(hDC);
    EndPaint( hWnd, (LPPAINTSTRUCT)&ps );

}


//========================================================================\\

// FUNCTION: InitStdio(HWND)

// PURPOSE:  Initialize variables used by I/O window.

//========================================================================\\

void InitStdio(HWND hWnd)
{
    int i,j;
    HDC hDC;
    TEXTMETRIC Metrics;

    // initialize screen buffer to nulls
    for(i=0; i<MaxLines; i++)
  for(j=0; j<81; j++)
      sScrBuff[i][j] = '\0';

    nFirstLine = 0;
    nLastLine = MaxLine;
    nCurrPos = 0;

    // get the text metrics for the font we are using
    hDC = GetDC(hWnd);
    hOldFont = SelectObject(hDC,GetStockObject(Stdio_FONT));
    GetTextMetrics(hDC,&Metrics);
    SelectObject(hDC,hOldFont);
    ReleaseDC(hWnd,hDC);

    // calculate the height and width of the font
    nStdioCharWidth = Metrics.tmMaxCharWidth;
    nStdioCharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;

    // get the background and forground colors we are going to use
    StdiobkRGB = GetSysColor(COLOR_WINDOW); // background color
    StdiotextRGB = GetSysColor(COLOR_WINDOWTEXT); // text color

    bInited = TRUE;

}


//========================================================================\\

// FUNCTION: stdioInit(HANDLE)

// PURPOSE:  Initialize the stdio module. Registers the window class.

// RETURNS:  Status of RegisterClass().

//========================================================================\\

BOOL stdioInit(HANDLE hInstance)
{

    PWNDCLASS pStdioClass;
    HWND hDummyWnd;

    if(hInstance == NULL) return FALSE;

    // create the stdio window
    pStdioClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pStdioClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pStdioClass->lpszClassName  = (LPSTR)"Stdio";
    pStdioClass->hbrBackground  = COLOR_WINDOW + 1;
    pStdioClass->hInstance      = hInstance;
    pStdioClass->style    = CS_HREDRAW | CS_VREDRAW;
    pStdioClass->lpfnWndProc    = StdioWndProc;

    if (!RegisterClass( (LPWNDCLASS)pStdioClass ) )
        // Initialization failed.
        // Windows will automatically deallocate all allocated memory.
        return FALSE;

    LocalFree( (HANDLE)pStdioClass );

    hStdioInst = hInstance;
    return TRUE;
}


//========================================================================\\

// FUNCTION: wopen(HWND, BOOL)

// PURPOSE:  Create a default style stdio window. If bQuit is TRUE,
//           PostQuitMessage will be called when the window is closed.
//           Therefore, the stdio window can be used for the main
//           application window.

// RETURNS:  Handle to window created.

//========================================================================\\

HWND wopen(HWND hWndParent, BOOL bQuit)
{

    // if window already created, return handle
    if(hWndStdio != NULL) return hWndStdio;

    hWndStdio = CreateWindow((LPSTR)"Stdio",
                    (LPSTR)"STDIO",
        WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    CW_USEDEFAULT,
                    (HWND)hWndParent,
                    (HMENU)NULL,
                    (HANDLE)hStdioInst,
                    (LPSTR)NULL
                );
    if(hWndStdio == NULL) return FALSE;
    ShowWindow(hWndStdio, SW_SHOW);
    UpdateWindow(hWndStdio);

    bStdioQuit = bQuit;
    return hWndStdio;

}


//========================================================================\\

// FUNCTION: CreateStdioWindow(LPSTR, DWORD, int, int, int, int, HWND,
//                            HANDLE, BOOL)

// PURPOSE:  Create an I/O window with definable name, style, size, etc.

// RETURNS:  Handle to window created.

//========================================================================\\

HWND CreateStdioWindow(LPSTR lpWindowName, DWORD dwStyle,
                       int X, int Y, int nWidth, int nHeight,
                       HWND hWndParent, HANDLE hInstance, BOOL bQuit)
{

    // if window already created, return handle
    if(hWndStdio != NULL) return hWndStdio;

    hWndStdio = CreateWindow((LPSTR)"Stdio",
                    (LPSTR)lpWindowName,
                    dwStyle,
                    X,
                    Y,
                    nWidth,
                    nHeight,
                    (HWND)hWndParent,
                    (HMENU)NULL,
                    (HANDLE)hInstance,
                    (LPSTR)NULL);

    if(hWndStdio == NULL) return FALSE;

    bStdioQuit = bQuit;
    return hWndStdio;
}


//========================================================================\\

// FUNCTION: wputs(LPSTR)

// PURPOSE:  Equivalent to puts() stdio function. Currently, '\n' is
//           not recognized as in '\r\n', as with normal puts(). Must
//           send '\r\n' explicitly.

// RETURNS:  Status of wopen(), if called, otherwise TRUE.

//========================================================================\\


BOOL wputs(LPSTR lpStr)
{
    HDC hDC;
    int nStrLen;

    // if being used for quick and dirty text output, a stdio window
    // will be opened if it hasn't been already.
    if(hWndStdio == NULL) if(wopen(NULL, FALSE) == NULL) return FALSE;

    hDC = GetDC(hWndStdio);
    SetupStdioDC(hWndStdio,hDC);
    nStrLen = lstrlen(lpStr);

    putStdio(hWndStdio,hDC,nStrLen,(LPSTR)lpStr);

    ResetStdioDC(hDC);
    ReleaseDC(hWndStdio,hDC);

    return TRUE;
}


//========================================================================\\

// FUNCTION: StdioWndProc(HWND, unsigned, WORD, LONG)

// PURPOSE:  Process messages for the I/O window. This function should
//           be exported in the application's .DEF file.

//========================================================================\\

long FAR PASCAL StdioWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;
    HDC hDC;
    LPPOINT ptMinMaxInfo;


    switch (message)
    {

    case WM_CREATE:

  // initialize stdio variables
  InitStdio(hWnd);
  break;


    case WM_SYSCOLORCHANGE:

  // if the colors have been changed in the control panel,
  // we need to change also.

  StdiobkRGB = GetSysColor(COLOR_WINDOW); // background color
  StdiotextRGB = GetSysColor(COLOR_WINDOWTEXT); // text color
        return DefWindowProc( hWnd, message, wParam, lParam );
  break;

    case WM_GETMINMAXINFO:
  if(!bInited) InitStdio(hWnd);

  // constrain the sizing of the window to 80 by 25 characters.

  ptMinMaxInfo = (LPPOINT) lParam;

  ptMinMaxInfo[1].x = nStdioCharWidth * 80
           + 2 * GetSystemMetrics(SM_CXFRAME);
  ptMinMaxInfo[1].y = nStdioCharHeight * 26
           + 2 * GetSystemMetrics(SM_CYFRAME);

  ptMinMaxInfo[4].x = nStdioCharWidth * 80
           + 2 * GetSystemMetrics(SM_CXFRAME);
  ptMinMaxInfo[4].y = nStdioCharHeight * 26
           + 2 * GetSystemMetrics(SM_CYFRAME);
  break;

    case WM_PAINT:

  // repaint the Stdio window
  StdioPaint(hWnd);
  break;

    case WM_DESTROY:

  // if specified when created, PostQuitMessage should be called
  // when the window is destroyed.

        if(bStdioQuit)
            PostQuitMessage(0);
        break;

    case WM_CLOSE:
        // destroy stdio data
        hWndStdio = NULL;

        // go ahead and close down
        // -- fall through to default --
    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}




Microsoft Windows S.D.K. v3.0 Sample MASM Source Code


CLOCKDAT.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\CLOCK\CLOCKDAT.ASM

        title   Hardware Dependent Parameters
        %out    config
        page    ,132
OEM     segment public
dw         0,     -7999
dw         836,   -7956
dw         1663,  -7825
dw         2472,  -7608
dw         3253,  -7308
dw         3999,  -6928
dw         4702,  -6472
dw         5353,  -5945
dw         5945,  -5353
dw         6472,  -4702
dw         6928,  -4000
dw         7308,  -3253
dw         7608,  -2472
dw         7825,  -1663
dw         7956,  -836

dw         8000,  0
dw         7956,  836
dw         7825,  1663
dw         7608,  2472
dw         7308,  3253
dw         6928,  4000
dw         6472,  4702
dw         5945,  5353
dw         5353,  5945
dw         4702,  6472
dw         3999,  6928
dw         3253,  7308
dw         2472,  7608
dw         1663,  7825
dw         836,   7956

dw          0,    7999
dw         -836,  7956
dw         -1663, 7825
dw         -2472, 7608
dw         -3253, 7308
dw         -4000, 6928
dw         -4702, 6472
dw         -5353, 5945
dw         -5945, 5353
dw         -6472, 4702
dw         -6928, 3999
dw         -7308, 3253
dw         -7608, 2472
dw         -7825, 1663
dw         -7956, 836

dw         -7999, -0
dw         -7956, -836
dw         -7825, -1663
dw         -7608, -2472
dw         -7308, -3253
dw         -6928, -4000
dw         -6472, -4702
dw         -5945, -5353
dw         -5353, -5945
dw         -4702, -6472
dw         -3999, -6928
dw         -3253, -7308
dw         -2472, -7608
dw         -1663, -7825
dw         -836 , -7956
OEM     ends
end



DLGOPENA.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SHOWDIB\DLGOPENA.ASM

  title  dlgopena.asm
;****************************************************************************
;*                         *
;*  MODULE  : DLGOPENA.ASM                   *
;*                         *
;*  DESCRIPTION : Assembly language helper routines for DLGOPEN.C         *
;*                         *
;*  FUNCTIONS  : chdir ()  - change to specified asciiz directory.         *
;*                         *
;****************************************************************************
?WIN = 1

?PLM=1      ; PASCAL Calling convention is DEFAULT
?WIN=1      ; Windows calling convention
?386=0      ; Use 386 code?
include cmacros.inc

;*********************************************************************
;* The following structure should be used to access high and low
;* words of a DWORD.  This means that "word ptr foo[2]" -> "foo.hi".
;*********************************************************************

LONG    struc
lo      dw      ?
hi      dw      ?
LONG    ends

FARPOINTER      struc
off     dw      ?
sel     dw      ?
FARPOINTER      ends

;*********************************************************************
;               DATA SEGMENT DECLARATIONS
;*********************************************************************

ifndef SEGNAME
    SEGNAME equ <TEXT>
endif

if ?386
    .386p
    createSeg _%SEGNAME, CodeSeg, word, use16, CODE
else
    .286p
    createSeg _%SEGNAME, CodeSeg, word, public, CODE
endif

sBegin  DATA
sEnd  DATA

sBegin  CodeSeg

assumes CS,CodeSeg
assumes DS,DATA

;****************************************************************************
;*                      *
;*  FUNCTION   : chdir (p)                *
;*                      *
;*  PURPOSE    : Change to asciiz directory specified in p        *
;*                      *
;*  RETURNS    : 1 - Success                *
;*     0 - Error                *
;*                      *
;****************************************************************************

cProc  chdir,<PUBLIC,FAR,PASCAL>,<ds>
  parmD p
cBegin
  lds  dx,p
  mov  bx,dx

  cmp  BYTE PTR ds:[bx+1],':'
        jnz     chdnod                  ; No drive
        mov     dl,ds:[bx]
        or      dl,20h
        sub     dl,'a'

  mov  ah,0eh      ; Set current drive
  int  21h

  mov  ah,19h      ; Get current drive
  int  21h

  cmp  al,dl
  jne  chderror

  lds  dx,p
  add  dx,2
  mov  bx,dx
  cmp  BYTE PTR ds:[bx],0  ; If path name is "" we are there
  jz  chdok
chdnod:
  mov  ah,3bh
  int  21h
  jc  chderror
chdok:
  mov  ax,1
chdexit:
cEnd
chderror:
  xor  ax,ax
  jmp  short chdexit

sEnd  CodeSeg

end


GETTIME.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\CLOCK\GETTIME.ASM

; get the time more efficiently than cmerge and DOSCALL() do

?PLM=0
include cmacros.inc

time    struc
        hour    dw  ?
        minute  dw  ?
        second  dw  ?
time    ends

assumes CS,CODE
assumes DS,DATA

sBegin   CODE

cProc   GetTime, <PUBLIC, NEAR>
        parmW   pTime               ; pointer to the structure to fill

cBegin
        mov     ax, 2c00h           ; get time
        int     21h
        mov     bx, pTime
        cmp     ch, 12                  ; if hour <12
        jl      lt12                    ; we're ok
        sub     ch,12                   ; else adjust it
lt12:
        xor     ax,ax
        mov     al,ch
        mov     [bx].hour, ax
        mov     al,cl
        mov     [bx].minute, ax
        mov     al,dh
        mov     [bx].second, ax
cEnd
sEnd    CODE
        END


LIBENTRY.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\SELECT\LIBENTRY.ASM

PAGE,132
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;       LIBENTRY.ASM
;
;       Windows dynamic link library entry routine
;
;   This module generates a code segment called INIT_TEXT.
;   It initializes the local heap if one exists and then calls
;   the C routine LibMain() which should have the form:
;   BOOL FAR PASCAL LibMain(HANDLE hInstance,
;                           WORD   wDataSeg,
;                           WORD   cbHeap,
;                           LPSTR  lpszCmdLine);
;
;   The result of the call to LibMain is returned to Windows.
;   The C routine should return TRUE if it completes initialization
;   successfully, FALSE if some error occurs.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

include cmacros.inc

externFP <LibMain>               ; the C routine to be called

createSeg INIT_TEXT, INIT_TEXT, BYTE, PUBLIC, CODE
sBegin  INIT_TEXT
assumes CS,INIT_TEXT

?PLM=0                           ; 'C'naming
externA  <_acrtused>             ; ensures that Win DLL startup code is linke

?PLM=1                           ; 'PASCAL' naming
externFP <LocalInit>             ; Windows heap init routine

cProc   LibEntry, <PUBLIC,FAR>   ; entry point into DLL

cBegin
        push    di               ; handle of the module instance
        push    ds               ; library data segment
        push    cx               ; heap size
        push    es               ; command line segment
        push    si               ; command line offset

        ; if we have some heap then initialize it
        jcxz    callc            ; jump if no heap specified

        ; call the Windows function LocalInit() to set up the heap
        ; LocalInit((LPSTR)start, WORD cbHeap);

        xor     ax,ax
        cCall   LocalInit <ds, ax, cx>
        or      ax,ax            ; did it do it ok ?
        jz      error            ; quit if it failed

        ; invoke the C routine to do any special initialization

callc:
        call    LibMain          ; invoke the 'C' routine (result in AX)
        jmp short exit           ; LibMain is responsible for stack clean up

error:
  pop  si     ; clean up stack on a LocalInit error
        pop     es
        pop     cx
        pop     ds
        pop     di

exit:

cEnd

sEnd  INIT_TEXT

end LibEntry


LIBENTRY.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_SDK\RAINBOW\LIBENTRY.ASM

PAGE,132
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;       LIBENTRY.ASM
;
;       Windows dynamic link library entry routine
;
;   This module generates a code segment called INIT_TEXT.
;   It initializes the local heap if one exists and then calls
;   the C routine LibMain() which should have the form:
;   BOOL FAR PASCAL LibMain(HANDLE hInstance,
;                           WORD   wDataSeg,
;                           WORD   cbHeap,
;                           LPSTR  lpszCmdLine);
;
;   The result of the call to LibMain is returned to Windows.
;   The C routine should return TRUE if it completes initialization
;   successfully, FALSE if some error occurs.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

include cmacros.inc

externFP <LibMain>               ; the C routine to be called

createSeg INIT_TEXT, INIT_TEXT, BYTE, PUBLIC, CODE
sBegin  INIT_TEXT
assumes CS,INIT_TEXT

?PLM=0                           ; 'C'naming
externA  <_acrtused>             ; ensures that Win DLL startup code is linke

?PLM=1                           ; 'PASCAL' naming
externFP <LocalInit>             ; Windows heap init routine

cProc   LibEntry, <PUBLIC,FAR>   ; entry point into DLL

cBegin
        push    di               ; handle of the module instance
        push    ds               ; library data segment
        push    cx               ; heap size
        push    es               ; command line segment
        push    si               ; command line offset

        ; if we have some heap then initialize it
        jcxz    callc            ; jump if no heap specified

        ; call the Windows function LocalInit() to set up the heap
        ; LocalInit((LPSTR)start, WORD cbHeap);

        xor     ax,ax
        cCall   LocalInit <ds, ax, cx>
        or      ax,ax            ; did it do it ok ?
        jz      error            ; quit if it failed

        ; invoke the C routine to do any special initialization

callc:
        call    LibMain          ; invoke the 'C' routine (result in AX)
        jmp short exit           ; LibMain is responsible for stack clean up

error:
  pop  si     ; clean up stack on a LocalInit error
        pop     es
        pop     cx
        pop     ds
        pop     di

exit:

cEnd

sEnd  INIT_TEXT

end LibEntry




Programming Windows (C. Petzold) Sample `C' Source Code


ABOUT1.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP10\ABOUT1.C

/*------------------------------------------
   ABOUT1.C -- About Box Demo Program No. 1
         (c) Charles Petzold, 1990
  ------------------------------------------*/

#include <windows.h>
#include "about1.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG);

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
        LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName [] = "About1" ;
     MSG         msg;
     HWND        hwnd ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "About Box Demo Program",
                          WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd);

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

BOOL FAR PASCAL AboutDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lPar
     {
     switch (message)
          {
          case WM_INITDIALOG:
               return TRUE ;

          case WM_COMMAND:
               switch (wParam)
                    {
        case IDOK:
        case IDCANCEL:
                         EndDialog (hDlg, 0) ;
       return TRUE ;
                    }
               break ;
          }
     return FALSE ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static FARPROC lpfnAboutDlgProc ;
     static HANDLE  hInstance ;

     switch (message)
          {
          case WM_CREATE:
               hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;

               lpfnAboutDlgProc = MakeProcInstance (AboutDlgProc, hInstance)
               return 0 ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDM_ABOUT:
                         DialogBox (hInstance, "AboutBox", hwnd,
                                        lpfnAboutDlgProc) ;
                         return 0 ;
                    }
               break ;

          case WM_DESTROY :
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


ABOUT2.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP10\ABOUT2.C

/*------------------------------------------
   ABOUT2.C -- About Box Demo Program No. 2
               (c) Charles Petzold, 1990
  ------------------------------------------*/

#include <windows.h>
#include "about2.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG);

short nCurrentColor  = IDD_BLACK,
      nCurrentFigure = IDD_RECT ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName [] = "About2" ;
     MSG         msg;
     HWND        hwnd ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "About Box Demo Program",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd);

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

void PaintWindow (HWND hwnd, short nColor, short nFigure)
     {
     static DWORD dwColor [8] = { RGB (0,     0, 0), RGB (  0,   0, 255),
                                  RGB (0,   255, 0), RGB (  0, 255, 255),
                                  RGB (255,   0, 0), RGB (255,   0, 255),
                                  RGB (255, 255, 0), RGB (255, 255, 255) } ;
     HBRUSH       hBrush ;
     HDC          hdc ;
     RECT         rect ;

     hdc = GetDC (hwnd) ;
     GetClientRect (hwnd, &rect) ;
     hBrush = CreateSolidBrush (dwColor [nColor - IDD_BLACK]) ;
     hBrush = SelectObject (hdc, hBrush) ;

     if (nFigure == IDD_RECT)
          Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom) ;
     else
          Ellipse   (hdc, rect.left, rect.top, rect.right, rect.bottom) ;

     DeleteObject (SelectObject (hdc, hBrush)) ;
     ReleaseDC (hwnd, hdc) ;
     }

void PaintTheBlock (HWND hCtrl, short nColor, short nFigure)
     {
     InvalidateRect (hCtrl, NULL, TRUE) ;
     UpdateWindow (hCtrl) ;
     PaintWindow (hCtrl, nColor, nFigure) ;
     }

BOOL FAR PASCAL AboutDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lPar
     {
     static HWND  hCtrlBlock ;
     static short nColor, nFigure ;

     switch (message)
          {
          case WM_INITDIALOG:
               nColor  = nCurrentColor ;
               nFigure = nCurrentFigure ;

               CheckRadioButton (hDlg, IDD_BLACK, IDD_WHITE, nColor) ;
               CheckRadioButton (hDlg, IDD_RECT,  IDD_ELL,   nFigure) ;

               hCtrlBlock = GetDlgItem (hDlg, IDD_PAINT) ;

               SetFocus (GetDlgItem (hDlg, nColor)) ;
               return FALSE ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDOK:
                         nCurrentColor  = nColor ;
                         nCurrentFigure = nFigure ;
                         EndDialog (hDlg, TRUE) ;
                         return TRUE ;

                    case IDCANCEL:
                         EndDialog (hDlg, FALSE) ;
                         return TRUE ;

                    case IDD_BLACK:
                    case IDD_RED:
                    case IDD_GREEN:
                    case IDD_YELLOW:
                    case IDD_BLUE:
                    case IDD_MAGENTA:
                    case IDD_CYAN:
                    case IDD_WHITE:
                         nColor = wParam ;
                         CheckRadioButton (hDlg, IDD_BLACK, IDD_WHITE, wParam
                         PaintTheBlock (hCtrlBlock, nColor, nFigure) ;
                         return TRUE ;

                    case IDD_RECT:
                    case IDD_ELL:
                         nFigure = wParam ;
                         CheckRadioButton (hDlg, IDD_RECT, IDD_ELL, wParam) ;
                         PaintTheBlock (hCtrlBlock, nColor, nFigure) ;
                         return TRUE ;
                    }
               break ;

          case WM_PAINT:
               PaintTheBlock (hCtrlBlock, nColor, nFigure) ;
               break ;
          }
     return FALSE ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static FARPROC lpfnAboutDlgProc ;
     static HANDLE  hInstance ;
     PAINTSTRUCT    ps ;

     switch (message)
          {
          case WM_CREATE:
               hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;

               lpfnAboutDlgProc = MakeProcInstance (AboutDlgProc, hInstance)
               return 0 ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDM_ABOUT:
                         if (DialogBox (hInstance, "AboutBox", hwnd,
                                        lpfnAboutDlgProc))
                              InvalidateRect (hwnd, NULL, TRUE) ;
                         return 0 ;
                    }
               break ;

          case WM_PAINT:
               BeginPaint (hwnd, &ps) ;
               EndPaint (hwnd, &ps) ;

               PaintWindow (hwnd, nCurrentColor, nCurrentFigure) ;
               return 0 ;

          case WM_DESTROY :
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


ABOUT3.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP10\ABOUT3.C

/*------------------------------------------
   ABOUT3.C -- About Box Demo Program No. 3
               (c) Charles Petzold, 1990
  ------------------------------------------*/

#include <windows.h>
#include "about3.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
long FAR PASCAL EllipPushWndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName [] = "About3" ;
     MSG         msg;
     HWND        hwnd ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;

          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = EllipPushWndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = COLOR_WINDOW + 1 ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = "EllipPush" ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "About Box Demo Program",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd);

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

BOOL FAR PASCAL AboutDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lPar
     {
     switch (message)
          {
          case WM_INITDIALOG:
               return TRUE ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDOK:
                         EndDialog (hDlg, 0) ;
                         return TRUE ;
                    }
               break ;
          }
     return FALSE ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static FARPROC lpfnAboutDlgProc ;
     static HANDLE  hInstance ;

     switch (message)
          {
          case WM_CREATE:
               hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;

               lpfnAboutDlgProc = MakeProcInstance (AboutDlgProc, hInstance)
               return 0 ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDM_ABOUT:
                         DialogBox (hInstance, "AboutBox", hwnd,
                                        lpfnAboutDlgProc) ;
                         return 0 ;
                    }
               break ;

          case WM_DESTROY :
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }

long FAR PASCAL EllipPushWndProc (HWND hwnd, WORD message,
                                  WORD wParam, LONG lParam)
     {
     char        szText [40] ;
     HBRUSH      hBrush ;
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT        rect ;

     switch (message)
          {
          case WM_PAINT:
               GetClientRect (hwnd, &rect) ;
               GetWindowText (hwnd, szText, sizeof szText) ;

               hdc = BeginPaint (hwnd, &ps) ;

               hBrush = CreateSolidBrush (GetSysColor (COLOR_WINDOW)) ;
               hBrush = SelectObject (hdc, hBrush) ;
               SetBkColor (hdc, GetSysColor (COLOR_WINDOW)) ;
               SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)) ;

               Ellipse (hdc, rect.left, rect.top, rect.right, rect.bottom) ;
               DrawText (hdc, szText, -1, &rect,
                              DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

               DeleteObject (SelectObject (hdc, hBrush)) ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_KEYUP:
               if (wParam != VK_SPACE)
                    break ;
                                        // fall through
          case WM_LBUTTONUP:
               SendMessage (GetParent (hwnd), WM_COMMAND,
                    GetWindowWord (hwnd, GWW_ID), (LONG) hwnd) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


ARCS.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP12\ARCS.C

/*-------------------------------------------------------
   ARCS.C -- Demonstrates Drawing Arcs, Chords, and Pies
             (c) Charles Petzold, 1990
  -------------------------------------------------------*/

#include <windows.h>
#include "arcs.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Arcs" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Arcs, Chords, and Pies",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static short cxClient, cyClient, x1, x2, x3, x4, y1, y2, y3, y4,
                  nFigure = IDM_ARC ;
     HDC          hdc ;
     HMENU        hMenu ;
     HPEN         hPen ;
     PAINTSTRUCT  ps ;
     short        x, y ;

     switch (message)
          {
          case WM_SIZE:
               x3 = y3 = 0 ;
               x4 = cxClient = LOWORD (lParam) ;
               y4 = cyClient = HIWORD (lParam) ;
               x2 = 3 * (x1 = cxClient / 4) ;
               y2 = 3 * (y1 = cyClient / 4) ;
               return 0 ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDM_ARC:
                    case IDM_CHORD:
                    case IDM_PIE:
                         hMenu = GetMenu (hwnd) ;
                         CheckMenuItem (hMenu, nFigure, MF_UNCHECKED) ;
                         CheckMenuItem (hMenu, nFigure = wParam, MF_CHECKED)
                         InvalidateRect (hwnd, NULL, FALSE) ;
                         return 0 ;
                    }
               break ;

          case WM_LBUTTONDOWN:
               if (!(wParam & MK_SHIFT))
                    {
                    x3 = LOWORD (lParam) ;
                    y3 = HIWORD (lParam) ;
                    InvalidateRect (hwnd, NULL, TRUE) ;
                    return 0 ;
                    }
                                        // fall through for MK_SHIFT
          case WM_RBUTTONDOWN:
               x4 = LOWORD (lParam) ;
               y4 = HIWORD (lParam) ;
               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               hPen = SelectObject (hdc, CreatePen (PS_DOT, 1, 0L)) ;
               Rectangle (hdc, x1, y1, x2, y2) ;
               Ellipse   (hdc, x1, y1, x2, y2) ;

               DeleteObject (SelectObject (hdc, CreatePen (PS_SOLID, 3, 0L)))

               switch (nFigure)
                    {
                    case IDM_ARC:
                         Arc (hdc, x1, y1, x2, y2, x3, y3, x4, y4) ;
                         break ;

                    case IDM_CHORD:
                         Chord (hdc, x1, y1, x2, y2, x3, y3, x4, y4) ;
                         break ;

                    case IDM_PIE:
                         Pie (hdc, x1, y1, x2, y2, x3, y3, x4, y4) ;
                         break ;
                    }

               DeleteObject (SelectObject (hdc, hPen)) ;

               MoveTo (hdc, x3, y3) ;
               LineTo (hdc, cxClient / 2, cyClient / 2) ;
               LineTo (hdc, x4, y4) ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


BEEPER1.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP05\BEEPER1.C

/*-----------------------------------------
   BEEPER1.C  -- Timer Demo Program No. 1
                 (c) Charles Petzold, 1990
  -----------------------------------------*/

#include <windows.h>
#define ID_TIMER    1

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Beeper1" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Beeper1 Timer Demo",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     while (!SetTimer (hwnd, ID_TIMER, 1000, NULL))
          if (IDCANCEL == MessageBox (hwnd,
                              "Too many clocks or timers!", szAppName,
                              MB_ICONEXCLAMATION | MB_RETRYCANCEL))
               return FALSE ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL fFlipFlop = FALSE ;
     HBRUSH      hBrush ;
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT        rc ;

     switch (message)
          {
          case WM_TIMER:
               MessageBeep (0) ;

               fFlipFlop = !fFlipFlop ;
               InvalidateRect (hwnd, NULL, FALSE) ;

               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               GetClientRect (hwnd, &rc) ;

               hBrush = CreateSolidBrush (fFlipFlop ? RGB(255,0,0) :
                                                      RGB(0,0,255)) ;
               FillRect (hdc, &rc, hBrush) ;
               EndPaint (hwnd, &ps) ;
               DeleteObject (hBrush) ;
               return 0 ;

          case WM_DESTROY:
               KillTimer (hwnd, ID_TIMER) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


BEEPER2.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP05\BEEPER2.C

/*----------------------------------------
   BEEPER2.C -- Timer Demo Program No. 2
                (c) Charles Petzold, 1990
  ----------------------------------------*/

#include <windows.h>
#define ID_TIMER    1

long FAR PASCAL WndProc   (HWND, WORD, WORD, LONG) ;
WORD FAR PASCAL TimerProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Beeper2" ;
     FARPROC     lpfnTimerProc ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Beeper2 Timer Demo",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     lpfnTimerProc = MakeProcInstance (TimerProc, hInstance) ;

     while (!SetTimer (hwnd, ID_TIMER, 1000, lpfnTimerProc))
          if (IDCANCEL == MessageBox (hwnd,
                              "Too many clocks or timers!", szAppName,
                              MB_ICONEXCLAMATION | MB_RETRYCANCEL))
               return FALSE ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     switch (message)
          {
          case WM_DESTROY:
               KillTimer (hwnd, ID_TIMER) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }

WORD FAR PASCAL TimerProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL fFlipFlop = FALSE ;
     HBRUSH      hBrush ;
     HDC         hdc ;
     RECT        rc ;

     MessageBeep (0) ;
     fFlipFlop = !fFlipFlop ;

     GetClientRect (hwnd, &rc) ;

     hdc = GetDC (hwnd) ;
     hBrush = CreateSolidBrush (fFlipFlop ? RGB(255,0,0) : RGB(0,0,255)) ;

     FillRect (hdc, &rc, hBrush) ;
     ReleaseDC (hwnd, hdc) ;
     DeleteObject (hBrush) ;

     return 0 ;
     }


BITLIB.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP19\BITLIB.C

/*--------------------------------------------------------------
   BITLIB.C -- Code entry point for BITLIB dynamic link library
               (c) Charles Petzold,  1990
  --------------------------------------------------------------*/
#include <windows.h>

int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg, WORD wHeapSize,
                        LPSTR lpszCmdLine)
     {
     if (wHeapSize > 0)
          UnlockData (0) ;

     return 1 ;
     }


BLOWUP1.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP04\BLOWUP1.C

/*------------------------------------------------
   BLOWUP1.C -- Screen Capture Mouse Demo Program
               (c) Charles Petzold, 1990
  ------------------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "BlowUp1" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Blow-Up Mouse Demo",
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

void InvertBlock (HWND hwnd, POINT ptBeg, POINT ptEnd)
     {
     HDC hdc ;

     hdc = CreateDC ("DISPLAY", NULL, NULL, NULL) ;
     ClientToScreen (hwnd, &ptBeg) ;
     ClientToScreen (hwnd, &ptEnd) ;
     PatBlt (hdc, ptBeg.x, ptBeg.y, ptEnd.x - ptBeg.x, ptEnd.y - ptBeg.y,
             DSTINVERT) ;
     DeleteDC (hdc) ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL  fCapturing, fBlocking ;
     static POINT ptBeg, ptEnd ;
     HDC          hdc ;
     RECT         rect ;

     switch (message)
          {
          case WM_LBUTTONDOWN:
               if (!fCapturing)
                    {
                    fCapturing = TRUE ;
                    SetCapture (hwnd) ;
                    SetCursor (LoadCursor (NULL, IDC_CROSS)) ;
                    }
               else if (!fBlocking)
                    {
                    fBlocking = TRUE ;
                    ptBeg = MAKEPOINT (lParam) ;
                    }
               return 0 ;

          case WM_MOUSEMOVE:
               if (fBlocking)
                    {
                    ptEnd = MAKEPOINT (lParam) ;
                    InvertBlock (hwnd, ptBeg, ptEnd) ;
                    InvertBlock (hwnd, ptBeg, ptEnd) ;
                    }
               return 0 ;

          case WM_LBUTTONUP:
               if (fBlocking)
                    {
                    fCapturing = fBlocking = FALSE ;
                    ptEnd = MAKEPOINT (lParam) ;
                    SetCursor (LoadCursor (NULL, IDC_WAIT)) ;

                    hdc = GetDC (hwnd) ;
                    GetClientRect (hwnd, &rect) ;
                    StretchBlt (hdc, 0, 0, rect.right, rect.bottom,
                                hdc, ptBeg.x, ptBeg.y,
                                ptEnd.x - ptBeg.x, ptEnd.y - ptBeg.y,
                                SRCCOPY) ;

                    ReleaseDC (hwnd, hdc) ;
                    SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
                    ReleaseCapture () ;
                    }
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


BLOWUP2.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP16\BLOWUP2.C

/*------------------------------------------------
   BLOWUP2.C -- Capture Screen Image to Clipboard
                (c) Charles Petzold, 1990
  ------------------------------------------------*/

#include <windows.h>
#include <stdlib.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName [] = "Blowup2" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, szAppName,
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

void InvertBlock (HWND hwnd, POINT org, POINT len)
     {
     HDC   hdc ;

     hdc = CreateDC ("DISPLAY", NULL, NULL, NULL) ;
     ClientToScreen (hwnd, &org) ;
     PatBlt (hdc, org.x, org.y, len.x, len.y, DSTINVERT) ;
     DeleteDC (hdc) ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL  bCapturing, bBlocking ;
     static POINT org, len ;
     static short cxClient, cyClient ;
     BITMAP       bm ;
     HDC          hdc, hdcMem ;
     HBITMAP      hBitmap ;
     PAINTSTRUCT  ps ;

     switch (message)
          {
          case WM_SIZE:
               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;
               return 0 ;

          case WM_LBUTTONDOWN:
               if (!bCapturing)
                    {
                    bCapturing = TRUE ;
                    SetCapture (hwnd) ;
                    SetCursor (LoadCursor (NULL, IDC_CROSS)) ;
                    }
               else if (!bBlocking)
                    {
                    bBlocking = TRUE ;
                    org = MAKEPOINT (lParam) ;
                    }
               return 0 ;

          case WM_MOUSEMOVE:
               if (bCapturing)
                    SetCursor (LoadCursor (NULL, IDC_CROSS)) ;

               if (bBlocking)
                    {
                    len = MAKEPOINT (lParam) ;
                    len.x -= org.x ;
                    len.y -= org.y ;

                    InvertBlock (hwnd, org, len) ;
                    InvertBlock (hwnd, org, len) ;
                    }
               return 0 ;

          case WM_LBUTTONUP:
               if (!bBlocking)
                    break ;

               bCapturing = bBlocking = FALSE ;
               SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
               ReleaseCapture () ;

               if (len.x == 0 || len.y == 0)
                    break ;

               hdc = GetDC (hwnd) ;
               hdcMem = CreateCompatibleDC (hdc) ;
               hBitmap = CreateCompatibleBitmap (hdc,
                                    abs (len.x), abs (len.y)) ;
               if (hBitmap)
                    {
                    SelectObject (hdcMem, hBitmap) ;
                    StretchBlt (hdcMem, 0, 0, abs (len.x), abs (len.y),
                         hdc, org.x, org.y, len.x, len.y, SRCCOPY) ;

                    OpenClipboard (hwnd) ;
                    EmptyClipboard () ;
                    SetClipboardData (CF_BITMAP, hBitmap) ;
                    CloseClipboard () ;

                    InvalidateRect (hwnd, NULL, TRUE) ;
                    }
               else
                    MessageBeep (0) ;

               DeleteDC (hdcMem) ;
               ReleaseDC (hwnd, hdc) ;
               return 0 ;

          case WM_PAINT:
               InvalidateRect (hwnd, NULL, TRUE) ;
               hdc = BeginPaint (hwnd, &ps) ;
               OpenClipboard (hwnd) ;

               if (hBitmap = GetClipboardData (CF_BITMAP))
                    {
                    SetCursor (LoadCursor (NULL, IDC_WAIT)) ;

                    hdcMem = CreateCompatibleDC (hdc) ;
                    SelectObject (hdcMem, hBitmap) ;
                    GetObject (hBitmap, sizeof (BITMAP), (LPSTR) &bm) ;

                    SetStretchBltMode (hdc, COLORONCOLOR) ;
                    StretchBlt (hdc, 0, 0, cxClient, cyClient,
                                hdcMem, 0, 0, bm.bmWidth, bm.bmHeight,
                                                  SRCCOPY) ;

                    SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
                    DeleteDC (hdcMem) ;
                    }

               CloseClipboard () ;
               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


BOUNCE.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP13\BOUNCE.C

/*---------------------------------------
   BOUNCE.C -- Bouncing Ball Program
               (c) Charles Petzold, 1990
  ---------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName [] = "Bounce" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Bouncing Ball",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     if (!SetTimer (hwnd, 1, 50, NULL))
          {
          MessageBox (hwnd, "Too many clocks or timers!",
                      szAppName, MB_ICONEXCLAMATION | MB_OK) ;
          return FALSE ;
          }

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HANDLE hBitmap ;
     static short  cxClient, cyClient, xCenter, yCenter, cxTotal, cyTotal,
                   cxRadius, cyRadius, cxMove, cyMove, xPixel, yPixel ;
     HBRUSH        hBrush ;
     HDC           hdc, hdcMem ;
     short         nScale ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;
               xPixel = GetDeviceCaps (hdc, ASPECTX) ;
               yPixel = GetDeviceCaps (hdc, ASPECTY) ;
               ReleaseDC (hwnd, hdc) ;
               return 0 ;

          case WM_SIZE:
               xCenter = (cxClient = LOWORD (lParam)) / 2 ;
               yCenter = (cyClient = HIWORD (lParam)) / 2 ;

               nScale = min (cxClient * xPixel, cyClient * yPixel) / 16 ;

               cxRadius = nScale / xPixel ;
               cyRadius = nScale / yPixel ;

               cxMove = max (1, cxRadius / 4) ;
               cyMove = max (1, cyRadius / 4) ;

               cxTotal = 2 * (cxRadius + cxMove) ;
               cyTotal = 2 * (cyRadius + cyMove) ;

               if (hBitmap)
                    DeleteObject (hBitmap) ;

               hdc = GetDC (hwnd) ;
               hdcMem = CreateCompatibleDC (hdc) ;
               hBitmap = CreateCompatibleBitmap (hdc, cxTotal, cyTotal) ;
               ReleaseDC (hwnd, hdc) ;

               SelectObject (hdcMem, hBitmap) ;
               Rectangle (hdcMem, -1, -1, cxTotal + 1, cyTotal + 1) ;

               hBrush = CreateHatchBrush (HS_DIAGCROSS, 0L) ;
               SelectObject (hdcMem, hBrush) ;
               SetBkColor (hdcMem, RGB (255, 0, 255)) ;
               Ellipse (hdcMem, cxMove, cyMove, cxTotal - cxMove,
                                                cyTotal - cyMove) ;
               DeleteDC (hdcMem) ;
               DeleteObject (hBrush) ;
               return 0 ;

          case WM_TIMER:
               if (!hBitmap)
                    break ;

               hdc = GetDC (hwnd) ;
               hdcMem = CreateCompatibleDC (hdc) ;
               SelectObject (hdcMem, hBitmap) ;

               BitBlt (hdc, xCenter - cxTotal / 2,
                            yCenter - cyTotal / 2, cxTotal, cyTotal,
                       hdcMem, 0, 0, SRCCOPY) ;

               ReleaseDC (hwnd, hdc) ;
               DeleteDC (hdcMem) ;

               xCenter += cxMove ;
               yCenter += cyMove ;

               if ((xCenter + cxRadius >= cxClient) ||
                   (xCenter - cxRadius <= 0))
                         cxMove = -cxMove ;

               if ((yCenter + cyRadius >= cyClient) ||
                   (yCenter - cyRadius <= 0))
                         cyMove = -cyMove ;
               return 0 ;

          case WM_DESTROY:
               if (hBitmap)
                    DeleteObject (hBitmap) ;

               KillTimer (hwnd, 1) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


BTNLOOK.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP06\BTNLOOK.C

/*----------------------------------------
   BTNLOOK.C -- Button Look Program
                (c) Charles Petzold, 1990
  ----------------------------------------*/

#include <windows.h>
#include <stdio.h>

struct
     {
     long style ;
     char *text ;
     }
     button[] =
     {
     BS_PUSHBUTTON,      "PUSHBUTTON",
     BS_DEFPUSHBUTTON,   "DEFPUSHBUTTON",
     BS_CHECKBOX,        "CHECKBOX",
     BS_AUTOCHECKBOX,    "AUTOCHECKBOX",
     BS_RADIOBUTTON,     "RADIOBUTTON",
     BS_3STATE,          "3STATE",
     BS_AUTO3STATE,      "AUTO3STATE",
     BS_GROUPBOX,        "GROUPBOX",
     BS_USERBUTTON,      "USERBUTTON",
     BS_AUTORADIOBUTTON, "AUTORADIO",
     BS_PUSHBOX,         "PUSHBOX"
     } ;

#define NUM (sizeof button / sizeof button [0])

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "BtnLook" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Button Look",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static char  szPrm []    = "wParam       LOWORD(lParam)  HIWORD(lParam)"
                  szTop []    = "Control ID   Window Handle   Notification",
                  szUnd []    = "__________   _____________   ____________",
                  szFormat [] = " %5u           %4X          %5u",
                  szBuffer [50] ;
     static HWND  hwndButton [NUM] ;
     static RECT  rect ;
     static int   cxChar, cyChar ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     int          i ;
     TEXTMETRIC   tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;
               ReleaseDC (hwnd, hdc) ;

               for (i = 0 ; i < NUM ; i++)
                    hwndButton [i] = CreateWindow ("button", button[i].text,
                              WS_CHILD | WS_VISIBLE | button[i].style,
                              cxChar, cyChar * (1 + 2 * i),
                              20 * cxChar, 7 * cyChar / 4,
                              hwnd, i,
                              ((LPCREATESTRUCT) lParam) -> hInstance, NULL) ;
               return 0 ;

          case WM_SIZE:
               rect.left   = 24 * cxChar ;
               rect.top    =  3 * cyChar ;
               rect.right  = LOWORD (lParam) ;
               rect.bottom = HIWORD (lParam) ;
               return 0 ;

          case WM_PAINT:
               InvalidateRect (hwnd, &rect, TRUE) ;

               hdc = BeginPaint (hwnd, &ps) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
               SetBkMode (hdc, TRANSPARENT) ;

               TextOut (hdc, 24 * cxChar, 1 * cyChar, szPrm, sizeof szPrm - 1
               TextOut (hdc, 24 * cxChar, 2 * cyChar, szTop, sizeof szTop - 1
               TextOut (hdc, 24 * cxChar, 2 * cyChar, szUnd, sizeof szUnd - 1

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_COMMAND:
               ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ;
               hdc = GetDC (hwnd) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

               TextOut (hdc, 24 * cxChar, cyChar * (rect.bottom / cyChar - 1)
                        szBuffer, sprintf (szBuffer, szFormat, wParam,
                        LOWORD (lParam), HIWORD (lParam))) ;

               ReleaseDC (hwnd, hdc) ;
               ValidateRect (hwnd, NULL) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


CHECKER1.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP04\CHECKER1.C

/*-------------------------------------------------
   CHECKER1.C -- Mouse Hit-Test Demo Program No. 1
                 (c) Charles Petzold, 1990
  -------------------------------------------------*/

#include <windows.h>
#define DIVISIONS 5

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR  lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Checker1" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Checker1 Mouse Hit-Test Demo",
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL  fState[DIVISIONS][DIVISIONS] ;
     static short cxBlock, cyBlock ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     RECT         rect ;
     short        x, y ;

     switch (message)
          {
          case WM_SIZE:
               cxBlock = LOWORD (lParam) / DIVISIONS ;
               cyBlock = HIWORD (lParam) / DIVISIONS ;
               return 0 ;

          case WM_LBUTTONDOWN:
               x = LOWORD (lParam) / cxBlock ;
               y = HIWORD (lParam) / cyBlock ;

               if (x < DIVISIONS && y < DIVISIONS)
                    {
                    fState [x][y] ^= 1 ;

                    rect.left   = x * cxBlock ;
                    rect.top    = y * cyBlock ;
                    rect.right  = (x + 1) * cxBlock ;
                    rect.bottom = (y + 1) * cyBlock ;

                    InvalidateRect (hwnd, &rect, FALSE) ;
                    }
               else
                    MessageBeep (0) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               for (x = 0 ; x < DIVISIONS ; x++)
                    for (y = 0 ; y < DIVISIONS ; y++)
                         {
                         Rectangle (hdc, x * cxBlock, y * cyBlock,
                                   (x + 1) * cxBlock, (y + 1) * cyBlock) ;

                         if (fState [x][y])
                              {
                              MoveTo (hdc,  x    * cxBlock,  y    * cyBlock)
                              LineTo (hdc, (x+1) * cxBlock, (y+1) * cyBlock)
                              MoveTo (hdc,  x    * cxBlock, (y+1) * cyBlock)
                              LineTo (hdc, (x+1) * cxBlock,  y    * cyBlock)
                              }
                         }
               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


CHECKER2.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP04\CHECKER2.C

/*-------------------------------------------------
   CHECKER2.C -- Mouse Hit-Test Demo Program No. 2
                 (c) Charles Petzold, 1990
  -------------------------------------------------*/

#include <windows.h>
#define DIVISIONS 5

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Checker2" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Checker2 Mouse Hit-Test Demo",
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL  fState[DIVISIONS][DIVISIONS] ;
     static short cxBlock, cyBlock ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     POINT        point ;
     RECT         rect ;
     short        x, y ;

     switch (message)
          {
          case WM_SIZE:
               cxBlock = LOWORD (lParam) / DIVISIONS ;
               cyBlock = HIWORD (lParam) / DIVISIONS ;
               return 0 ;

          case WM_SETFOCUS:
               ShowCursor (TRUE) ;
               return 0 ;

          case WM_KILLFOCUS:
               ShowCursor (FALSE) ;
               return 0 ;

          case WM_KEYDOWN:
               GetCursorPos (&point) ;
               ScreenToClient (hwnd, &point) ;

               x = max (0, min (DIVISIONS - 1, point.x / cxBlock)) ;
               y = max (0, min (DIVISIONS - 1, point.y / cyBlock)) ;

               switch (wParam)
                    {
                    case VK_UP:
                         y -- ;
                         break ;

                    case VK_DOWN:
                         y ++ ;
                         break ;

                    case VK_LEFT:
                         x -- ;
                         break ;

                    case VK_RIGHT:
                         x ++ ;
                         break ;

                    case VK_HOME:
                         x = y = 0 ;
                         break ;

                    case VK_END:
                         x = y = DIVISIONS - 1 ;
                         break ;

                    case VK_RETURN:
                    case VK_SPACE:
                         SendMessage (hwnd, WM_LBUTTONDOWN, MK_LBUTTON,
                                   MAKELONG (x * cxBlock, y * cyBlock)) ;
                         break ;
                    }
               x = (x + DIVISIONS) % DIVISIONS ;
               y = (y + DIVISIONS) % DIVISIONS ;

               point.x = x * cxBlock + cxBlock / 2 ;
               point.y = y * cyBlock + cyBlock / 2 ;

               ClientToScreen (hwnd, &point) ;
               SetCursorPos (point.x, point.y) ;
               return 0 ;

          case WM_LBUTTONDOWN:
               x = LOWORD (lParam) / cxBlock ;
               y = HIWORD (lParam) / cyBlock ;

               if (x < DIVISIONS && y < DIVISIONS)
                    {
                    fState[x][y] ^= 1 ;

                    rect.left   = x * cxBlock ;
                    rect.top    = y * cyBlock ;
                    rect.right  = (x + 1) * cxBlock ;
                    rect.bottom = (y + 1) * cyBlock ;

                    InvalidateRect (hwnd, &rect, FALSE) ;
                    }
               else
                    MessageBeep (0) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               for (x = 0 ; x < DIVISIONS ; x++)
                    for (y = 0 ; y < DIVISIONS ; y++)
                         {
                         Rectangle (hdc, x * cxBlock, y * cyBlock,
                                   (x + 1) * cxBlock, (y + 1) * cyBlock) ;

                         if (fState [x][y])
                              {
                              MoveTo (hdc,  x    * cxBlock,  y    * cyBlock)
                              LineTo (hdc, (x+1) * cxBlock, (y+1) * cyBlock)
                              MoveTo (hdc,  x    * cxBlock, (y+1) * cyBlock)
                              LineTo (hdc, (x+1) * cxBlock,  y    * cyBlock)
                              }
                         }
               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


CHECKER3.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP04\CHECKER3.C

/*-------------------------------------------------
   CHECKER3.C -- Mouse Hit-Test Demo Program No. 3
                 (c) Charles Petzold, 1990
  -------------------------------------------------*/

#include <windows.h>
#define DIVISIONS 5

long FAR PASCAL WndProc      (HWND, WORD, WORD, LONG) ;
long FAR PASCAL ChildWndProc (HWND, WORD, WORD, LONG) ;

char szChildClass[] = "Checker3_Child" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Checker3" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;

          wndclass.lpfnWndProc   = ChildWndProc ;
          wndclass.cbWndExtra    = sizeof (WORD) ;
          wndclass.hIcon         = NULL ;
          wndclass.lpszClassName = szChildClass ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Checker3 Mouse Hit-Test Demo",
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HWND hwndChild [DIVISIONS] [DIVISIONS] ;
     short       cxBlock, cyBlock, x, y ;

     switch (message)
          {
          case WM_CREATE:
               for (x = 0 ; x < DIVISIONS ; x++)
                    for (y = 0 ; y < DIVISIONS ; y++)
                         {
                         hwndChild [x][y] = CreateWindow (szChildClass, NULL,
                              WS_CHILDWINDOW | WS_VISIBLE,
                              0, 0, 0, 0,
                              hwnd, y << 8 | x,
                              GetWindowWord (hwnd, GWW_HINSTANCE), NULL) ;
                         }
               return 0 ;

          case WM_SIZE:
               cxBlock = LOWORD (lParam) / DIVISIONS ;
               cyBlock = HIWORD (lParam) / DIVISIONS ;

               for (x = 0 ; x < DIVISIONS ; x++)
                    for (y = 0 ; y < DIVISIONS ; y++)
                         MoveWindow (hwndChild [x][y],
                              x * cxBlock, y * cyBlock,
                              cxBlock, cyBlock, TRUE) ;
               return 0 ;

          case WM_LBUTTONDOWN:
               MessageBeep (0) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }

long FAR PASCAL ChildWndProc (HWND hwnd, WORD message, WORD wParam, LONG lPar
     {
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT        rect ;

     switch (message)
          {
          case WM_CREATE:
               SetWindowWord (hwnd, 0, 0) ;       // on/off flag
               return 0 ;

          case WM_LBUTTONDOWN:
               SetWindowWord (hwnd, 0, 1 ^ GetWindowWord (hwnd, 0)) ;
               InvalidateRect (hwnd, NULL, FALSE) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               GetClientRect (hwnd, &rect) ;
               Rectangle (hdc, 0, 0, rect.right, rect.bottom) ;

               if (GetWindowWord (hwnd, 0))
                    {
                    MoveTo (hdc, 0,          0) ;
                    LineTo (hdc, rect.right, rect.bottom) ;
                    MoveTo (hdc, 0,          rect.bottom) ;
                    LineTo (hdc, rect.right, 0) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


CLIPVIEW.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP16\CLIPVIEW.C

/*-----------------------------------------
   CLIPVIEW.C -- Simple Clipboard Viewer
                 (c) Charles Petzold, 1990
  -----------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static    char szAppName [] = "ClipView" ;
     HWND      hwnd ;
     MSG       msg ;
     WNDCLASS  wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Simple Clipboard Viewer (Text Only)",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HWND hwndNextViewer ;
     HANDLE      hGMem ;
     HDC         hdc ;
     LPSTR       lpGMem ;
     PAINTSTRUCT ps ;
     RECT        rect ;

     switch (message)
          {
          case WM_CREATE:
               hwndNextViewer = SetClipboardViewer (hwnd) ;
               return 0 ;

          case WM_CHANGECBCHAIN :
               if (wParam == hwndNextViewer)
                    hwndNextViewer = LOWORD (lParam) ;

               else if (hwndNextViewer)
                    SendMessage (hwndNextViewer, message, wParam, lParam) ;

               return 0 ;

          case WM_DRAWCLIPBOARD :
               if (hwndNextViewer)
                    SendMessage (hwndNextViewer, message, wParam, lParam) ;

               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;
               GetClientRect (hwnd, &rect) ;
               OpenClipboard (hwnd) ;

               if (hGMem = GetClipboardData (CF_TEXT))
                    {
                    lpGMem = GlobalLock (hGMem) ;
                    DrawText (hdc, lpGMem, -1, &rect, DT_EXPANDTABS) ;
                    GlobalUnlock (hGMem) ;
                    }

               CloseClipboard () ;
               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               ChangeClipboardChain (hwnd, hwndNextViewer) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


CLOVER.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP12\CLOVER.C

/*--------------------------------------------------
   CLOVER.C -- Clover Drawing Program using Regions
               (c) Charles Petzold, 1990
  --------------------------------------------------*/

#include <windows.h>
#include <math.h>
#define TWO_PI (2.0 * 3.14159)

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Clover" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Draw a Clover",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HRGN  hRgnClip ;
     static short cxClient, cyClient ;
     double       fAngle, fRadius ;
     HCURSOR      hCursor ;
     HDC          hdc ;
     HRGN         hRgnTemp [6] ;
     PAINTSTRUCT  ps ;
     short        i ;

     switch (message)
          {
          case WM_SIZE:
               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;

               hCursor = SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
               ShowCursor (TRUE) ;

               if (hRgnClip)
                    DeleteObject (hRgnClip) ;

               hRgnTemp [0] = CreateEllipticRgn (0, cyClient / 3,
                                        cxClient / 2, 2 * cyClient / 3) ;
               hRgnTemp [1] = CreateEllipticRgn (cxClient / 2, cyClient / 3,
                                        cxClient, 2 * cyClient / 3) ;
               hRgnTemp [2] = CreateEllipticRgn (cxClient / 3, 0,
                                        2 * cxClient / 3, cyClient / 2) ;
               hRgnTemp [3] = CreateEllipticRgn (cxClient / 3, cyClient / 2,
                                        2 * cxClient / 3, cyClient) ;
               hRgnTemp [4] = CreateRectRgn (0, 0, 1, 1) ;
               hRgnTemp [5] = CreateRectRgn (0, 0, 1, 1) ;
               hRgnClip     = CreateRectRgn (0, 0, 1, 1) ;

               CombineRgn (hRgnTemp [4], hRgnTemp [0], hRgnTemp [1], RGN_OR)
               CombineRgn (hRgnTemp [5], hRgnTemp [2], hRgnTemp [3], RGN_OR)
               CombineRgn (hRgnClip,     hRgnTemp [4], hRgnTemp [5], RGN_XOR)

               for (i = 0 ; i < 6 ; i++)
                    DeleteObject (hRgnTemp [i]) ;

               SetCursor (hCursor) ;
               ShowCursor (FALSE) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               SetViewportOrg (hdc, cxClient / 2, cyClient / 2) ;
               SelectClipRgn (hdc, hRgnClip) ;

               fRadius = hypot (cxClient / 2.0, cyClient / 2.0) ;

               for (fAngle = 0.0 ; fAngle < TWO_PI ; fAngle += TWO_PI / 360)
                    {
                    MoveTo (hdc, 0, 0) ;
                    LineTo (hdc, (short) ( fRadius * cos (fAngle) + 0.5),
                                 (short) (-fRadius * sin (fAngle) + 0.5)) ;
                    }
               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               DeleteObject (hRgnClip) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


COLORS1.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP06\COLORS1.C

/*----------------------------------------
   COLORS1.C -- Colors Using Scroll Bars
                (c) Charles Petzold, 1990
  ----------------------------------------*/

#include <windows.h>
#include <stdlib.h>

long FAR PASCAL WndProc    (HWND, WORD, WORD, LONG) ;
long FAR PASCAL ScrollProc (HWND, WORD, WORD, LONG) ;

FARPROC lpfnOldScr[3] ;
HWND    hwndScrol[3], hwndLabel[3], hwndValue[3], hwndRect ;
short   color[3], nFocus ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Colors1" ;
     static char *szColorLabel[] = { "Red", "Green", "Blue" } ;
     FARPROC     lpfnScrollProc ;
     HWND        hwnd ;
     MSG         msg;
     short       n ;
     WNDCLASS    wndclass ;

     if (hPrevInstance)
          return FALSE ;

     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = NULL ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = CreateSolidBrush (0L) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     RegisterClass (&wndclass) ;

     hwnd = CreateWindow (szAppName, "Color Scroll",
                          WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     hwndRect = CreateWindow ("static", NULL,
                              WS_CHILD | WS_VISIBLE | SS_WHITERECT,
                              0, 0, 0, 0,
                              hwnd, 9, hInstance, NULL) ;

     lpfnScrollProc = MakeProcInstance ((FARPROC) ScrollProc, hInstance) ;

     for (n = 0 ; n < 3 ; n++)
          {
          hwndScrol[n] = CreateWindow ("scrollbar", NULL,
                              WS_CHILD | WS_VISIBLE | WS_TABSTOP | SBS_VERT,
                              0, 0, 0, 0,
                              hwnd, n, hInstance, NULL) ;

          hwndLabel[n] = CreateWindow ("static", szColorLabel[n],
                              WS_CHILD | WS_VISIBLE | SS_CENTER,
                              0, 0, 0, 0,
                              hwnd, n + 3, hInstance, NULL) ;

          hwndValue[n] = CreateWindow ("static", "0",
                              WS_CHILD | WS_VISIBLE | SS_CENTER,
                              0, 0, 0, 0,
                              hwnd, n + 6, hInstance, NULL) ;

          lpfnOldScr[n] = (FARPROC) GetWindowLong (hwndScrol[n], GWL_WNDPROC)
          SetWindowLong (hwndScrol[n], GWL_WNDPROC, (LONG) lpfnScrollProc) ;

          SetScrollRange (hwndScrol[n], SB_CTL, 0, 255, FALSE) ;
          SetScrollPos   (hwndScrol[n], SB_CTL, 0, FALSE) ;
          }

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd);

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HBRUSH hBrush[3] ;
     char          szbuffer[10] ;
     HDC           hdc ;
     POINT         point ;
     short         n, cxClient, cyClient, cyChar ;
     TEXTMETRIC    tm ;

     switch (message)
          {
          case WM_CREATE :
               hBrush[0] = CreateSolidBrush (RGB (255, 0, 0)) ;
               hBrush[1] = CreateSolidBrush (RGB (0, 255, 0)) ;
               hBrush[2] = CreateSolidBrush (RGB (0, 0, 255)) ;
               return 0 ;

          case WM_SIZE :
               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;

               hdc = GetDC (hwnd) ;
               GetTextMetrics (hdc, &tm) ;
               cyChar = tm.tmHeight ;
               ReleaseDC (hwnd, hdc) ;

               MoveWindow (hwndRect, 0, 0, cxClient / 2, cyClient, TRUE) ;

               for (n = 0 ; n < 3 ; n++)
                    {
                    MoveWindow (hwndScrol[n],
                         (2 * n + 1) * cxClient / 14, 2 * cyChar,
                         cxClient / 14, cyClient - 4 * cyChar, TRUE) ;

                    MoveWindow (hwndLabel[n],
                         (4 * n + 1) * cxClient / 28, cyChar / 2,
                         cxClient / 7, cyChar, TRUE) ;

                    MoveWindow (hwndValue[n],
                         (4 * n + 1) * cxClient / 28, cyClient - 3 * cyChar /
                         cxClient / 7, cyChar, TRUE) ;
                    }
               SetFocus (hwnd) ;
               return 0 ;

          case WM_SETFOCUS:
               SetFocus (hwndScrol[nFocus]) ;
               return 0 ;

          case WM_VSCROLL :
               n = GetWindowWord (HIWORD (lParam), GWW_ID) ;

               switch (wParam)
                    {
                    case SB_PAGEDOWN :
                         color[n] += 15 ;         /* fall through */
                    case SB_LINEDOWN :
                         color[n] = min (255, color[n] + 1) ;
                         break ;
                    case SB_PAGEUP :
                         color[n] -= 15 ;         /* fall through */
                    case SB_LINEUP :
                         color[n] = max (0, color[n] - 1) ;
                         break ;
                    case SB_TOP:
                         color[n] = 0 ;
                         break ;
                    case SB_BOTTOM :
                         color[n] = 255 ;
                         break ;
                    case SB_THUMBPOSITION :
                    case SB_THUMBTRACK :
                         color[n] = LOWORD (lParam) ;
                         break ;
                    default :
                         break ;
                    }
               SetScrollPos  (hwndScrol[n], SB_CTL, color[n], TRUE) ;
               SetWindowText (hwndValue[n], itoa (color[n], szbuffer, 10)) ;

               DeleteObject (GetClassWord (hwnd, GCW_HBRBACKGROUND)) ;
               SetClassWord (hwnd, GCW_HBRBACKGROUND,
                    CreateSolidBrush (RGB (color[0], color[1], color[2]))) ;

               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          case WM_CTLCOLOR:
               if (HIWORD (lParam) == CTLCOLOR_SCROLLBAR)
                    {
                    SetBkColor (wParam, GetSysColor (COLOR_CAPTIONTEXT)) ;
                    SetTextColor (wParam, GetSysColor (COLOR_WINDOWFRAME)) ;

                    n = GetWindowWord (LOWORD (lParam), GWW_ID) ;
                    point.x = point.y = 0 ;
                    ClientToScreen (hwnd, &point) ;
                    UnrealizeObject (hBrush[n]) ;
                    SetBrushOrg (wParam, point.x, point.y) ;
                    return ((DWORD) hBrush[n]) ;
                    }
               break ;

          case WM_DESTROY:
               DeleteObject (GetClassWord (hwnd, GCW_HBRBACKGROUND)) ;
               for (n = 0 ; n < 3 ; DeleteObject (hBrush [n++])) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }

long FAR PASCAL ScrollProc (HWND hwnd, WORD message, WORD wParam, LONG lParam
     {
     short n = GetWindowWord (hwnd, GWW_ID) ;

     switch (message)
          {
          case WM_KEYDOWN:
               if (wParam == VK_TAB)
                    SetFocus (hwndScrol[(n +
                         (GetKeyState (VK_SHIFT) < 0 ? 2 : 1)) % 3]) ;
               break ;

          case WM_SETFOCUS:
               nFocus = n ;
               break ;
          }
     return CallWindowProc (lpfnOldScr[n], hwnd, message, wParam, lParam) ;
     }


COLORS2.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP10\COLORS2.C

/*--------------------------------------------------------
   COLORS2.C -- Version using Modeless Dialog Box Version
                (c) Charles Petzold, 1990
  --------------------------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc     (HWND, WORD, WORD, LONG) ;
BOOL FAR PASCAL ColorScrDlg (HWND, WORD, WORD, LONG) ;

HWND hDlgModeless ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Colors2" ;
     HWND        hwnd ;
     MSG         msg;
     WNDCLASS    wndclass ;

     if (hPrevInstance)
          return FALSE ;

     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = NULL ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = CreateSolidBrush (0L) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     RegisterClass (&wndclass) ;

     hwnd = CreateWindow (szAppName, "Color Scroll",
                          WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd);

     hDlgModeless = CreateDialog (hInstance, "ColorScrDlg", hwnd,
                         MakeProcInstance (ColorScrDlg, hInstance)) ;

     while (GetMessage (&msg, NULL, 0, 0))
          {
          if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))
               {
               TranslateMessage (&msg) ;
               DispatchMessage  (&msg) ;
               }
          }
     return msg.wParam ;
     }

BOOL FAR PASCAL ColorScrDlg (HWND hDlg, WORD message, WORD wParam, LONG lPara
     {
     static short color [3] ;
     HWND         hwndParent, hCtrl ;
     short        nCtrlID, nIndex ;

     switch (message)
          {
          case WM_INITDIALOG:
               for (nCtrlID = 10 ; nCtrlID < 13 ; nCtrlID++)
                    {
                    hCtrl = GetDlgItem (hDlg, nCtrlID) ;
                    SetScrollRange (hCtrl, SB_CTL, 0, 255, FALSE) ;
                    SetScrollPos   (hCtrl, SB_CTL, 0, FALSE) ;
                    }
               return TRUE ;

          case WM_VSCROLL :
               hCtrl   = HIWORD (lParam) ;
               nCtrlID = GetWindowWord (hCtrl, GWW_ID) ;
               nIndex  = nCtrlID - 10 ;
               hwndParent = GetParent (hDlg) ;

               switch (wParam)
                    {
                    case SB_PAGEDOWN :
                         color [nIndex] += 15 ;        // fall through
                    case SB_LINEDOWN :
                         color [nIndex] = min (255, color [nIndex] + 1) ;
                         break ;
                    case SB_PAGEUP :
                         color [nIndex] -= 15 ;        // fall through
                    case SB_LINEUP :
                         color [nIndex] = max (0, color [nIndex] - 1) ;
                         break ;
                    case SB_TOP:
                         color [nIndex] = 0 ;
                         break ;
                    case SB_BOTTOM :
                         color [nIndex] = 255 ;
                         break ;
                    case SB_THUMBPOSITION :
                    case SB_THUMBTRACK :
                         color [nIndex] = LOWORD (lParam) ;
                         break ;
                    default :
                         return FALSE ;
                    }
               SetScrollPos  (hCtrl, SB_CTL,      color [nIndex], TRUE) ;
               SetDlgItemInt (hDlg,  nCtrlID + 3, color [nIndex], FALSE) ;

               DeleteObject (GetClassWord (hwndParent, GCW_HBRBACKGROUND)) ;
               SetClassWord (hwndParent, GCW_HBRBACKGROUND,
                    CreateSolidBrush (RGB (color [0], color [1], color [2])))

               InvalidateRect (hwndParent, NULL, TRUE) ;
               return TRUE ;
          }
     return FALSE ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     switch (message)
          {
          case WM_DESTROY:
               DeleteObject (GetClassWord (hwnd, GCW_HBRBACKGROUND)) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


CONNECT.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP04\CONNECT.C

/*--------------------------------------------------
   CONNECT.C -- Connect-the-Dots Mouse Demo Program
                (c) Charles Petzold, 1990
  --------------------------------------------------*/

#include <windows.h>
#define MAXPOINTS 1000

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Connect" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Connect-the-Points Mouse Demo",
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         CW_USEDEFAULT, CW_USEDEFAULT,
                         NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static POINT points[MAXPOINTS] ;
     static short nCount ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     short        i, j ;

     switch (message)
          {
          case WM_LBUTTONDOWN:
               nCount = 0 ;
               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          case WM_MOUSEMOVE:
               if (wParam & MK_LBUTTON && nCount < 1000)
                    {
                    points [nCount++] = MAKEPOINT (lParam) ;
                    hdc = GetDC (hwnd) ;
                    SetPixel (hdc, LOWORD (lParam), HIWORD (lParam), 0L) ;
                    ReleaseDC (hwnd, hdc) ;
                    }
               return 0 ;

          case WM_LBUTTONUP:
               InvalidateRect (hwnd, NULL, FALSE) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               for (i = 0 ; i < nCount - 1 ; i++)
                    for (j = i ; j < nCount ; j++)
                         {
                         MoveTo (hdc, points[i].x, points[i].y) ;
                         LineTo (hdc, points[j].x, points[j].y) ;
                         }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


DDEPOP.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP17\DDEPOP.C

/*--------------------------------------------
   DDEPOP.C -- DDE Server for Population Data
               (c) Charles Petzold, 1990
  --------------------------------------------*/

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

struct
     {
     char *szState ;
     long lPop70 ;
     long lPop80 ;
     long lPop ;
     }
     pop [] = {
              "AL",   3444354,   3894025, 0, "AK",    302583,    401851, 0,
              "AZ",   1775399,   2716598, 0, "AR",   1923322,   2286357, 0,
              "CA",  19971069,  23667764, 0, "CO",   2209596,   2889735, 0,
              "CT",   3032217,   3107564, 0, "DE",    548104,    594338, 0,
              "DC",    756668,    638432, 0, "FL",   6791418,   9746961, 0,
              "GA",   4587930,   5462982, 0, "HI",    769913,    964691, 0,
              "ID",    713015,    944127, 0, "IL",  11110285,  11427409, 0,
              "IN",   5195392,   5490212, 0, "IA",   2825368,   2913808, 0,
              "KS",   2249071,   2364236, 0, "KY",   3220711,   3660324, 0,
              "LA",   3644637,   4206116, 0, "ME",    993722,   1125043, 0,
              "MD",   3923897,   4216933, 0, "MA",   5689170,   5737093, 0,
              "MI",   8881826,   9262044, 0, "MN",   3806103,   4075970, 0,
              "MS",   2216994,   2520770, 0, "MO",   4677623,   4916762, 0,
              "MT",    694409,    786690, 0, "NE",   1485333,   1569825, 0,
              "NV",    488738,    800508, 0, "NH",    737681,    920610, 0,
              "NJ",   7171112,   7365011, 0, "NM",   1017055,   1303302, 0,
              "NY",  18241391,  17558165, 0, "NC",   5084411,   5880415, 0,
              "ND",    617792,    652717, 0, "OH",  10657423,  10797603, 0,
              "OK",   2559463,   3025487, 0, "OR",   2091533,   2633156, 0,
              "PA",  11800766,  11864720, 0, "RI",    949723,    947154, 0,
              "SC",   2590713,   3120730, 0, "SD",    666257,    690768, 0,
              "TN",   3926018,   4591023, 0, "TX",  11198655,  14225513, 0,
              "UT",   1059273,   1461037, 0, "VT",    444732,    511456, 0,
              "VA",   4651448,   5346797, 0, "WA",   3413244,   4132353, 0,
              "WV",   1744237,   1950186, 0, "WI",   4417821,   4705642, 0,
              "WY",    332416,    469557, 0, "US", 203302031, 226542580, 0
              } ;

#define NUM_STATES (sizeof (pop) / sizeof (pop [0]))

typedef struct
     {
     unsigned int fAdvise:1 ;
     unsigned int fDeferUpd:1 ;
     unsigned int fAckReq:1 ;
     unsigned int dummy:13 ;
     long         lPopPrev ;
     }
     POPADVISE ;

#define ID_TIMER    1
#define DDE_TIMEOUT 3000

long FAR PASCAL WndProc         (HWND, WORD, WORD, LONG) ;
long FAR PASCAL ServerProc      (HWND, WORD, WORD, LONG) ;
BOOL FAR PASCAL TimerEnumProc   (HWND, LONG) ;
BOOL FAR PASCAL CloseEnumProc   (HWND, LONG) ;
BOOL            PostDataMessage (HWND, HWND, int, BOOL, BOOL, BOOL) ;

char   szAppName []     = "DdePop" ;
char   szServerClass [] = "DdePop.Server" ;
HANDLE hInst ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (hPrevInstance)
          return FALSE ;

     hInst = hInstance ;

               // Register window class

     wndclass.style         = 0 ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     RegisterClass (&wndclass) ;

               // Register window class for DDE Server

     wndclass.style         = 0 ;
     wndclass.lpfnWndProc   = ServerProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 2 * sizeof (WORD) ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = NULL ;
     wndclass.hCursor       = NULL ;
     wndclass.hbrBackground = NULL ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szServerClass ;

     RegisterClass (&wndclass) ;

     hwnd = CreateWindow (szAppName, "DDE Population Server",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     SendMessage (hwnd, WM_TIMER, 0, 0L) ;   // initialize 'pop' structure

     if (!SetTimer (hwnd, ID_TIMER, 5000, NULL))
          {
          MessageBox (hwnd, "Too many clocks or timers!", szAppName,
                      MB_ICONEXCLAMATION | MB_OK) ;

          return FALSE ;
          }

     ShowWindow (hwnd, SW_SHOWMINNOACTIVE) ;
     UpdateWindow (hwnd) ;

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

     KillTimer (hwnd, ID_TIMER) ;

     return msg.wParam ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static FARPROC lpTimerEnumProc, lpCloseEnumProc ;
     static char    szTopic [] = "US_Population" ;
     ATOM           aApp, aTop ;
     HWND           hwndClient, hwndServer ;
     int            i ;
     long double    ldSecsInDecade, ldSecSince1970 ;
     time_t         lSecSince1970 ;

     switch (message)
          {
          case WM_CREATE:
               lpTimerEnumProc = MakeProcInstance (TimerEnumProc, hInst) ;
               lpCloseEnumProc = MakeProcInstance (CloseEnumProc, hInst) ;
               return 0 ;

          case WM_DDE_INITIATE:

                    // wParam          -- sending window handle
                    // LOWORD (lParam) -- application atom
                    // HIWORD (lParam) -- topic atom

               hwndClient = wParam ;

               aApp = GlobalAddAtom (szAppName) ;
               aTop = GlobalAddAtom (szTopic) ;

                    // Check for matching atoms, create window, and acknowled

               if ((LOWORD (lParam) == NULL || LOWORD (lParam) == aApp) &&
                   (HIWORD (lParam) == NULL || HIWORD (lParam) == aTop))
                    {
                    hwndServer = CreateWindow (szServerClass, NULL,
                                               WS_CHILD, 0, 0, 0, 0,
                                               hwnd, NULL, hInst, NULL) ;

                    SetWindowWord (hwndServer, 0, hwndClient) ;
                    SendMessage (wParam, WM_DDE_ACK, hwndServer,
                                 MAKELONG (aApp, aTop)) ;
                    }

                    // Otherwise, delete the atoms just created

               else
                    {
                    GlobalDeleteAtom (aApp) ;
                    GlobalDeleteAtom (aTop) ;
                    }

               return 0 ;

          case WM_TIMER:
          case WM_TIMECHANGE:
               time (&lSecSince1970) ;

                    // Calculate new current populations

               ldSecSince1970 = (long double) lSecSince1970 ;
               ldSecsInDecade = (long double) 3652 * 24 * 60 * 60 ;

               for (i = 0 ; i < NUM_STATES ; i++)
                    {
                    pop[i].lPop = (long)
                         (((ldSecsInDecade - ldSecSince1970) * pop[i].lPop70
                            ldSecSince1970 * pop[i].lPop80) / ldSecsInDecade
                                   + .5) ;
                    }

                    // Notify all child windows

               EnumChildWindows (hwnd, lpTimerEnumProc, 0L) ;
               return 0 ;

          case WM_QUERYOPEN:
               return 0 ;

          case WM_CLOSE:

                    // Notify all child windows

               EnumChildWindows (hwnd, lpCloseEnumProc, 0L) ;

               break ;                  // for default processing

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }

long FAR PASCAL ServerProc (HWND hwnd, WORD message, WORD wParam, LONG lParam
     {
     ATOM          aItem ;
     char          szItem [10], szPopulation [10] ;
     DDEACK        DdeAck ;
     DDEADVISE     Advise ;
     DDEADVISE FAR *lpDdeAdvise ;
     DDEDATA FAR   *lpDdeData ;
     DWORD         dwTime ;
     GLOBALHANDLE  hPopAdvise, hDdeData, hDdeAdvise, hCommands, hDdePoke ;
     int           i ;
     HWND          hwndClient ;
     MSG           msg ;
     POPADVISE FAR *lpPopAdvise ;
     WORD          cfFormat, wStatus ;

     switch (message)
          {
          case WM_CREATE:

                    // Allocate memory for POPADVISE structures

               hPopAdvise = GlobalAlloc (GHND, NUM_STATES * sizeof (POPADVISE

               if (hPopAdvise == NULL)
                    DestroyWindow (hwnd) ;
               else
                    SetWindowWord (hwnd, 2, hPopAdvise) ;

               return 0 ;

          case WM_DDE_REQUEST:

                    // wParam          -- sending window handle
                    // LOWORD (lParam) -- data format
                    // HIWORD (lParam) -- item atom

               hwndClient = wParam ;
               cfFormat   = LOWORD (lParam) ;
               aItem      = HIWORD (lParam) ;

                    // Check for matching format and data item

               if (cfFormat == CF_TEXT)
                    {
                    GlobalGetAtomName (aItem, szItem, sizeof (szItem)) ;

                    for (i = 0 ; i < NUM_STATES ; i++)
                         if (strcmp (szItem, pop[i].szState) == 0)
                              break ;

                    if (i < NUM_STATES)
                         {
                         GlobalDeleteAtom (aItem) ;
                         PostDataMessage (hwnd, hwndClient, i,
                                          FALSE, FALSE, TRUE) ;
                         return 0 ;
                         }
                    }

                    // Negative acknowledge if no match

               DdeAck.bAppReturnCode = 0 ;
               DdeAck.reserved       = 0 ;
               DdeAck.fBusy          = FALSE ;
               DdeAck.fAck           = FALSE ;

               wStatus = * (WORD *) & DdeAck ;

               if (!PostMessage (hwndClient, WM_DDE_ACK, hwnd,
                                 MAKELONG (wStatus, aItem)))
                    {
                    GlobalDeleteAtom (aItem) ;
                    }

               return 0 ;

          case WM_DDE_ADVISE:

                    // wParam          -- sending window handle
                    // LOWORD (lParam) -- DDEADVISE memory handle
                    // HIWORD (lParam) -- item atom

               hwndClient = wParam ;
               hDdeAdvise = LOWORD (lParam) ;
               aItem      = HIWORD (lParam) ;

               lpDdeAdvise = (DDEADVISE FAR *) GlobalLock (hDdeAdvise) ;

                    // Check for matching format and data item

               if (lpDdeAdvise->cfFormat == CF_TEXT)
                    {
                    GlobalGetAtomName (aItem, szItem, sizeof (szItem)) ;

                    for (i = 0 ; i < NUM_STATES ; i++)
                         if (strcmp (szItem, pop[i].szState) == 0)
                              break ;

                         // Fill in the POPADVISE structure and acknowledge

                    if (i < NUM_STATES)
                         {
                         hPopAdvise = GetWindowWord (hwnd, 2) ;
                         lpPopAdvise = (POPADVISE FAR *)
                                              GlobalLock (hPopAdvise) ;

                         lpPopAdvise[i].fAdvise   = TRUE ;
                         lpPopAdvise[i].fDeferUpd = lpDdeAdvise->fDeferUpd ;
                         lpPopAdvise[i].fAckReq   = lpDdeAdvise->fAckReq ;
                         lpPopAdvise[i].lPopPrev  = pop[i].lPop ;

                         GlobalUnlock (hDdeAdvise) ;
                         GlobalFree (hDdeAdvise) ;

                         DdeAck.bAppReturnCode = 0 ;
                         DdeAck.reserved       = 0 ;
                         DdeAck.fBusy          = FALSE ;
                         DdeAck.fAck           = TRUE ;

                         wStatus = * (WORD *) & DdeAck ;

                         if (!PostMessage (hwndClient, WM_DDE_ACK, hwnd,
                                           MAKELONG (wStatus, aItem)))
                              {
                              GlobalDeleteAtom (aItem) ;
                              }
                         else
                              {
                              PostDataMessage (hwnd, hwndClient, i,
                                               lpPopAdvise[i].fDeferUpd,
                                               lpPopAdvise[i].fAckReq,
                                               FALSE) ;
                              }

                         GlobalUnlock (hPopAdvise) ;
                         return 0 ;
                         }
                    }

                         // Otherwise post a negative WM_DDE_ACK

               GlobalUnlock (hDdeAdvise) ;

               DdeAck.bAppReturnCode = 0 ;
               DdeAck.reserved       = 0 ;
               DdeAck.fBusy          = FALSE ;
               DdeAck.fAck           = FALSE ;

               wStatus = * (WORD *) & DdeAck ;

               if (!PostMessage (hwndClient, WM_DDE_ACK, hwnd,
                                 MAKELONG (wStatus, aItem)))
                    {
                    GlobalFree (hDdeAdvise) ;
                    GlobalDeleteAtom (aItem) ;
                    }

               return 0 ;

          case WM_DDE_UNADVISE:

                    // wParam          -- sending window handle
                    // LOWORD (lParam) -- data format
                    // HIWORD (lParam) -- item atom

               hwndClient = wParam ;
               cfFormat   = LOWORD (lParam) ;
               aItem      = HIWORD (lParam) ;

               DdeAck.bAppReturnCode = 0 ;
               DdeAck.reserved       = 0 ;
               DdeAck.fBusy          = FALSE ;
               DdeAck.fAck           = TRUE ;

               hPopAdvise  = GetWindowWord (hwnd, 2) ;
               lpPopAdvise = (POPADVISE FAR *) GlobalLock (hPopAdvise) ;

                    // Check for matching format and data item

               if (cfFormat == CF_TEXT || cfFormat == 0)
                    {
                    if (aItem == NULL)
                         for (i = 0 ; i < NUM_STATES ; i++)
                              lpPopAdvise[i].fAdvise = FALSE ;
                    else
                         {
                         GlobalGetAtomName (aItem, szItem, sizeof (szItem)) ;

                         for (i = 0 ; i < NUM_STATES ; i++)
                              if (strcmp (szItem, pop[i].szState) == 0)
                                   break ;

                         if (i < NUM_STATES)
                              lpPopAdvise[i].fAdvise = FALSE ;
                         else
                              DdeAck.fAck = FALSE ;
                         }
                    }
               else
                    DdeAck.fAck = FALSE ;

                    // Acknowledge either positively or negatively

               wStatus = * (WORD *) & DdeAck ;

               if (!PostMessage (hwndClient, WM_DDE_ACK, hwnd,
                                 MAKELONG (wStatus, aItem)))
                    {
                    if (aItem != NULL)
                         GlobalDeleteAtom (aItem) ;
                    }

               GlobalUnlock (hPopAdvise) ;
               return 0 ;

          case WM_DDE_EXECUTE:

                    // Post negative acknowledge

               hwndClient = wParam ;
               hCommands  = HIWORD (lParam) ;

               DdeAck.bAppReturnCode = 0 ;
               DdeAck.reserved       = 0 ;
               DdeAck.fBusy          = FALSE ;
               DdeAck.fAck           = FALSE ;

               wStatus = * (WORD *) & DdeAck ;

               if (!PostMessage (hwndClient, WM_DDE_ACK, hwnd,
                                 MAKELONG (wStatus, hCommands)))
                    {
                    GlobalFree (hCommands) ;
                    }
               return 0 ;

          case WM_DDE_POKE:

                    // Post negative acknowledge

               hwndClient = wParam ;
               hDdePoke   = LOWORD (lParam) ;
               aItem      = HIWORD (lParam) ;

               DdeAck.bAppReturnCode = 0 ;
               DdeAck.reserved       = 0 ;
               DdeAck.fBusy          = FALSE ;
               DdeAck.fAck           = FALSE ;

               wStatus = * (WORD *) & DdeAck ;

               if (!PostMessage (hwndClient, WM_DDE_ACK, hwnd,
                                 MAKELONG (wStatus, aItem)))
                    {
                    GlobalFree (hDdePoke) ;
                    GlobalDeleteAtom (aItem) ;
                    }

               return 0 ;

          case WM_DDE_TERMINATE:

                    // Respond with another WM_DDE_TERMINATE message

               hwndClient = wParam ;
               PostMessage (hwndClient, WM_DDE_TERMINATE, hwnd, 0L) ;
               DestroyWindow (hwnd) ;
               return 0 ;

          case WM_TIMER:

                    // Post WM_DDE_DATA messages for changed populations

               hwndClient  = GetWindowWord (hwnd, 0) ;
               hPopAdvise  = GetWindowWord (hwnd, 2) ;
               lpPopAdvise = (POPADVISE FAR *) GlobalLock (hPopAdvise) ;

               for (i = 0 ; i < NUM_STATES ; i++)
                    if (lpPopAdvise[i].fAdvise)
                         if (lpPopAdvise[i].lPopPrev != pop[i].lPop)
                              {
                              if (!PostDataMessage (hwnd, hwndClient, i,
                                                    lpPopAdvise[i].fDeferUpd,
                                                    lpPopAdvise[i].fAckReq,
                                                    FALSE))
                                   break ;

                              lpPopAdvise[i].lPopPrev = pop[i].lPop ;
                              }

               GlobalUnlock (hPopAdvise) ;
               return 0 ;

          case WM_CLOSE:

                    // Post a WM_DDE_TERMINATE message to the client

               hwndClient = GetWindowWord (hwnd, 0) ;
               PostMessage (hwndClient, WM_DDE_TERMINATE, hwnd, 0L) ;

               dwTime = GetCurrentTime () ;

               while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
                    if (PeekMessage (&msg, hwnd, WM_DDE_TERMINATE,
                                     WM_DDE_TERMINATE, PM_REMOVE))
                         break ;

               DestroyWindow (hwnd) ;
               return 0 ;

          case WM_DESTROY:
               hPopAdvise = GetWindowWord (hwnd, 2) ;
               GlobalFree (hPopAdvise) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }

BOOL FAR PASCAL TimerEnumProc (HWND hwnd, LONG lParam)
     {
     SendMessage (hwnd, WM_TIMER, 0, 0L) ;

     return TRUE ;
     }

BOOL FAR PASCAL CloseEnumProc (HWND hwnd, LONG lParam)
     {
     SendMessage (hwnd, WM_CLOSE, 0, 0L) ;

     return TRUE ;
     }

BOOL PostDataMessage (HWND hwndServer, HWND hwndClient, int iState,
                      BOOL fDeferUpd, BOOL fAckReq, BOOL fResponse)
     {
     ATOM         aItem ;
     char         szPopulation [10] ;
     DDEACK       DdeAck ;
     DDEDATA FAR  *lpDdeData ;
     DWORD        dwTime ;
     GLOBALHANDLE hDdeData ;
     MSG          msg ;

     aItem = GlobalAddAtom (pop[iState].szState) ;

          // Allocate a DDEDATA structure if not defered update

     if (fDeferUpd)
          {
          hDdeData = NULL ;
          }
     else
          {
          wsprintf (szPopulation, "%ld\r\n", pop[iState].lPop) ;

          hDdeData = GlobalAlloc (GHND | GMEM_DDESHARE,
                                  sizeof (DDEDATA) + strlen (szPopulation)) ;

          lpDdeData = (DDEDATA FAR *) GlobalLock (hDdeData) ;

          lpDdeData->fResponse = fResponse ;
          lpDdeData->fRelease  = TRUE ;
          lpDdeData->fAckReq   = fAckReq ;
          lpDdeData->cfFormat  = CF_TEXT ;

          lstrcpy ((LPSTR) lpDdeData->Value, szPopulation) ;

          GlobalUnlock (hDdeData) ;
          }

          // Post the WM_DDE_DATA message

     if (!PostMessage (hwndClient, WM_DDE_DATA, hwndServer,
                       MAKELONG (hDdeData, aItem)))
          {
          if (hDdeData != NULL)
               GlobalFree (hDdeData) ;

          GlobalDeleteAtom (aItem) ;
          return FALSE ;
          }

          // Wait for the acknowledge message if it's requested

     if (fAckReq)
          {
          DdeAck.fAck = FALSE ;

          dwTime = GetCurrentTime () ;

          while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
               {
               if (PeekMessage (&msg, hwndServer, WM_DDE_ACK, WM_DDE_ACK,
                                PM_REMOVE))
                    {
                    DdeAck = * (DDEACK *) & LOWORD (msg.lParam) ;
                    aItem  = HIWORD (msg.lParam) ;
                    GlobalDeleteAtom (aItem) ;
                    break ;
                    }
               }

          if (DdeAck.fAck == FALSE)
               {
               if (hDdeData != NULL)
                    GlobalFree (hDdeData) ;

               return FALSE ;
               }
          }

     return TRUE ;
     }


DEVCAPS.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\DEVCAPS.C

/*---------------------------------------------------------
   DEVCAPS.C -- Display routines for DEVCAPS1 and DEVCAPS2
                (c) Charles Petzold, 1990
  ---------------------------------------------------------*/

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

typedef struct
     {
     short nMask ;
     char  *szMask ;
     char  *szDesc ;
     }
     BITS ;

void DoBasicInfo (HDC hdc, HDC hdcInfo, short cxChar, short cyChar)
     {
     static struct
          {
          short nIndex ;
          char  *szDesc ;
          }
          info [] =
          {
          HORZSIZE,      "HORZSIZE     Width in millimeters:",
          VERTSIZE,      "VERTSIZE     Height in millimeters:",
          HORZRES,       "HORZRES      Width in pixels:",
          VERTRES,       "VERTRES      Height in raster lines:",
          BITSPIXEL,     "BITSPIXEL    Color bits per pixel:",
          PLANES,        "PLANES       Number of color planes:",
          NUMBRUSHES,    "NUMBRUSHES   Number of device brushes:",
          NUMPENS,       "NUMPENS      Number of device pens:",
          NUMMARKERS,    "NUMMARKERS   Number of device markers:",
          NUMFONTS,      "NUMFONTS     Number of device fonts:",
          NUMCOLORS,     "NUMCOLORS    Number of device colors:",
          PDEVICESIZE,   "PDEVICESIZE  Size of device structure:",
          ASPECTX,       "ASPECTX      Relative width of pixel:",
          ASPECTY,       "ASPECTY      Relative height of pixel:",
          ASPECTXY,      "ASPECTXY     Relative diagonal of pixel:",
          LOGPIXELSX,    "LOGPIXELSX   Horizontal dots per inch:",
          LOGPIXELSY,    "LOGPIXELSY   Vertical dots per inch:",
          SIZEPALETTE,   "SIZEPALETTE  Number of palette entries:",
          NUMRESERVED,   "NUMRESERVED  Reserved palette entries:",
          COLORRES,      "COLORRES     Actual color resolution:"
          } ;
     char   szBuffer [80] ;
     short  i, nLine ;

     for (i = 0 ; i < sizeof info / sizeof info [0] ; i++)
          TextOut (hdc, cxChar, (i + 1) * cyChar, szBuffer,
               sprintf (szBuffer, "%-40s%8d", info[i].szDesc,
                    GetDeviceCaps (hdcInfo, info[i].nIndex))) ;
     }

void DoOtherInfo (HDC hdc, HDC hdcInfo, short cxChar, short cyChar)
     {
     static BITS clip [] =
          {
          CP_RECTANGLE,  "CP_RECTANGLE",     "Can Clip To Rectangle:"
          } ;

     static BITS raster [] =
          {
          RC_BITBLT,       "RC_BITBLT",       "Capable of simple BitBlt:",
          RC_BANDING,      "RC_BANDING",      "Requires banding support:",
          RC_SCALING,      "RC_SCALING",      "Requires scaling support:",
          RC_BITMAP64,     "RC_BITMAP64",     "Supports bitmaps >64K:",
          RC_GDI20_OUTPUT, "RC_GDI20_OUTPUT", "Has 2.0 output calls:",
          RC_DI_BITMAP,    "RC_DI_BITMAP",    "Supports DIB to memory:",
          RC_PALETTE,      "RC_PALETTE",      "Supports a palette:",
          RC_DIBTODEV,     "RC_DIBTODEV",     "Supports bitmap conversion:",
          RC_BIGFONT,      "RC_BIGFONT",      "Supports fonts >64K:",
          RC_STRETCHBLT,   "RC_STRETCHBLT",   "Supports StretchBlt:",
          RC_FLOODFILL,    "RC_FLOODFILL",    "Supports FloodFill:"
          } ;

     static char *szTech [] = { "DT_PLOTTER (Vector plotter)",
                                "DT_RASDISPLAY (Raster display)",
                                "DT_RASPRINTER (Raster printer)",
                                "DT_RASCAMERA (Raster camera)",
                                "DT_CHARSTREAM (Character-stream, PLP)",
                                "DT_METAFILE (Metafile, VDM)",
                                "DT_DISPFILE (Display-file)" } ;
     char        szBuffer [80] ;
     short       i ;

     TextOut (hdc, cxChar, cyChar, szBuffer,
          sprintf (szBuffer, "%-24s%04XH",
               "DRIVERVERSION:", GetDeviceCaps (hdcInfo, DRIVERVERSION))) ;

     TextOut (hdc, cxChar, 2 * cyChar, szBuffer,
          sprintf (szBuffer, "%-24s%-40s",
               "TECHNOLOGY:", szTech [GetDeviceCaps (hdcInfo, TECHNOLOGY)]))

     TextOut (hdc, cxChar, 4 * cyChar, szBuffer,
          sprintf (szBuffer, "CLIPCAPS (Clipping capabilities)")) ;

     for (i = 0 ; i < sizeof clip / sizeof clip [0] ; i++)
          TextOut (hdc, 9 * cxChar, (i + 6) * cyChar, szBuffer,
               sprintf (szBuffer, "%-16s%-28s %3s",
                    clip[i].szMask, clip[i].szDesc,
                    GetDeviceCaps (hdcInfo, CLIPCAPS) & clip[i].nMask ?
                         "Yes" : "No")) ;

     TextOut (hdc, cxChar, 8 * cyChar, szBuffer,
          sprintf (szBuffer, "RASTERCAPS (Raster capabilities)")) ;

     for (i = 0 ; i < sizeof raster / sizeof raster [0] ; i++)
          TextOut (hdc, 9 * cxChar, (i + 10) * cyChar, szBuffer,
               sprintf (szBuffer, "%-16s%-28s %3s",
                    raster[i].szMask, raster[i].szDesc,
                    GetDeviceCaps (hdcInfo, RASTERCAPS) & raster[i].nMask ?
                         "Yes" : "No")) ;
     }

void DoBitCodedCaps (HDC hdc, HDC hdcInfo, short cxChar, short cyChar,
                     short nType)
     {
     static BITS curves [] =
          {
          CC_CIRCLES,    "CC_CIRCLES",    "circles:",
          CC_PIE,        "CC_PIE",        "pie wedges:",
          CC_CHORD,      "CC_CHORD",      "chord arcs:",
          CC_ELLIPSES,   "CC_ELLIPSES",   "ellipses:",
          CC_WIDE,       "CC_WIDE",       "wide borders:",
          CC_STYLED,     "CC_STYLED",     "styled borders:",
          CC_WIDESTYLED, "CC_WIDESTYLED", "wide and styled borders:",
          CC_INTERIORS,  "CC_INTERIORS",  "interiors:"
          } ;

     static BITS lines [] =
          {
          LC_POLYLINE,   "LC_POLYLINE",   "polyline:",
          LC_MARKER,     "LC_MARKER",     "markers:",
          LC_POLYMARKER, "LC_POLYMARKER", "polymarkers",
          LC_WIDE,       "LC_WIDE",       "wide lines:",
          LC_STYLED,     "LC_STYLED",     "styled lines:",
          LC_WIDESTYLED, "LC_WIDESTYLED", "wide and styled lines:",
          LC_INTERIORS,  "LC_INTERIORS",  "interiors:"
          } ;

     static BITS poly [] =
          {
          PC_POLYGON,    "PC_POLYGON",    "alternate fill polygon:",
          PC_RECTANGLE,  "PC_RECTANGLE",  "rectangle:",
          PC_TRAPEZOID,  "PC_TRAPEZOID",  "winding number fill polygon:",
          PC_SCANLINE,   "PC_SCANLINE",   "scanlines:",
          PC_WIDE,       "PC_WIDE",       "wide borders:",
          PC_STYLED,     "PC_STYLED",     "styled borders:",
          PC_WIDESTYLED, "PC_WIDESTYLED", "wide and styled borders:",
          PC_INTERIORS,  "PC_INTERIORS",  "interiors:"
          } ;

     static BITS text [] =
          {
          TC_OP_CHARACTER, "TC_OP_CHARACTER", "character output precision:",
          TC_OP_STROKE,    "TC_OP_STROKE",    "stroke output precision:",
          TC_CP_STROKE,    "TC_CP_STROKE",    "stroke clip precision:",
          TC_CR_90,        "TC_CP_90",        "90 degree character rotation:"
          TC_CR_ANY,       "TC_CR_ANY",       "any character rotation:",
          TC_SF_X_YINDEP,  "TC_SF_X_YINDEP", "scaling independent of X and Y:
          TC_SA_DOUBLE,    "TC_SA_DOUBLE",   "doubled character for scaling:"
          TC_SA_INTEGER,   "TC_SA_INTEGER",  "integer multiples for scaling:"
          TC_SA_CONTIN,    "TC_SA_CONTIN",  "any multiples for exact scaling:
          TC_EA_DOUBLE,    "TC_EA_DOUBLE",  "double weight characters:",
          TC_IA_ABLE,      "TC_IA_ABLE",    "italicizing:",
          TC_UA_ABLE,      "TC_UA_ABLE",    "underlining:",
          TC_SO_ABLE,      "TC_SO_ABLE",    "strikeouts:",
          TC_RA_ABLE,      "TC_RA_ABLE",    "raster fonts:",
          TC_VA_ABLE,      "TC_VA_ABLE",    "vector fonts:"
          } ;

     static struct
          {
          short nIndex ;
          char  *szTitle ;
          BITS  (*pbits) [] ;
          short nSize ;
          }
          bitinfo [] =
          {
          CURVECAPS,  "CURVCAPS (Curve Capabilities)",
                      (BITS (*)[]) curves, sizeof curves / sizeof curves [0],
          LINECAPS,   "LINECAPS (Line Capabilities)",
                      (BITS (*)[]) lines, sizeof lines / sizeof lines [0],
          POLYGONALCAPS, "POLYGONALCAPS (Polygonal Capabilities)",
                      (BITS (*)[]) poly, sizeof poly / sizeof poly [0],
          TEXTCAPS,   "TEXTCAPS (Text Capabilities)",
                      (BITS (*)[]) text, sizeof text / sizeof text [0]
          } ;

     static char szBuffer [80] ;
     BITS        (*pbits) [] = bitinfo [nType].pbits ;
     short       nDevCaps = GetDeviceCaps (hdcInfo, bitinfo [nType].nIndex) ;
     short       i ;

     TextOut (hdc, cxChar, cyChar, bitinfo [nType].szTitle,
                    strlen (bitinfo [nType].szTitle)) ;

     for (i = 0 ; i < bitinfo [nType].nSize ; i++)
          TextOut (hdc, cxChar, (i + 3) * cyChar, szBuffer,
               sprintf (szBuffer, "%-16s %s %-32s %3s",
                    (*pbits)[i].szMask, "Can do", (*pbits)[i].szDesc,
                    nDevCaps & (*pbits)[i].nMask ? "Yes" : "No")) ;
     }


DEVCAPS.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP11\DEVCAPS.C

/*---------------------------------------------------------
   DEVCAPS.C -- Display routines for DEVCAPS1 and DEVCAPS2
                (c) Charles Petzold, 1990
  ---------------------------------------------------------*/

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

typedef struct
     {
     short nMask ;
     char  *szMask ;
     char  *szDesc ;
     }
     BITS ;

void DoBasicInfo (HDC hdc, HDC hdcInfo, short cxChar, short cyChar)
     {
     static struct
          {
          short nIndex ;
          char  *szDesc ;
          }
          info [] =
          {
          HORZSIZE,      "HORZSIZE     Width in millimeters:",
          VERTSIZE,      "VERTSIZE     Height in millimeters:",
          HORZRES,       "HORZRES      Width in pixels:",
          VERTRES,       "VERTRES      Height in raster lines:",
          BITSPIXEL,     "BITSPIXEL    Color bits per pixel:",
          PLANES,        "PLANES       Number of color planes:",
          NUMBRUSHES,    "NUMBRUSHES   Number of device brushes:",
          NUMPENS,       "NUMPENS      Number of device pens:",
          NUMMARKERS,    "NUMMARKERS   Number of device markers:",
          NUMFONTS,      "NUMFONTS     Number of device fonts:",
          NUMCOLORS,     "NUMCOLORS    Number of device colors:",
          PDEVICESIZE,   "PDEVICESIZE  Size of device structure:",
          ASPECTX,       "ASPECTX      Relative width of pixel:",
          ASPECTY,       "ASPECTY      Relative height of pixel:",
          ASPECTXY,      "ASPECTXY     Relative diagonal of pixel:",
          LOGPIXELSX,    "LOGPIXELSX   Horizontal dots per inch:",
          LOGPIXELSY,    "LOGPIXELSY   Vertical dots per inch:",
          SIZEPALETTE,   "SIZEPALETTE  Number of palette entries:",
          NUMRESERVED,   "NUMRESERVED  Reserved palette entries:",
          COLORRES,      "COLORRES     Actual color resolution:"
          } ;
     char   szBuffer [80] ;
     short  i, nLine ;

     for (i = 0 ; i < sizeof info / sizeof info [0] ; i++)
          TextOut (hdc, cxChar, (i + 1) * cyChar, szBuffer,
               sprintf (szBuffer, "%-40s%8d", info[i].szDesc,
                    GetDeviceCaps (hdcInfo, info[i].nIndex))) ;
     }

void DoOtherInfo (HDC hdc, HDC hdcInfo, short cxChar, short cyChar)
     {
     static BITS clip [] =
          {
          CP_RECTANGLE,  "CP_RECTANGLE",     "Can Clip To Rectangle:"
          } ;

     static BITS raster [] =
          {
          RC_BITBLT,       "RC_BITBLT",       "Capable of simple BitBlt:",
          RC_BANDING,      "RC_BANDING",      "Requires banding support:",
          RC_SCALING,      "RC_SCALING",      "Requires scaling support:",
          RC_BITMAP64,     "RC_BITMAP64",     "Supports bitmaps >64K:",
          RC_GDI20_OUTPUT, "RC_GDI20_OUTPUT", "Has 2.0 output calls:",
          RC_DI_BITMAP,    "RC_DI_BITMAP",    "Supports DIB to memory:",
          RC_PALETTE,      "RC_PALETTE",      "Supports a palette:",
          RC_DIBTODEV,     "RC_DIBTODEV",     "Supports bitmap conversion:",
          RC_BIGFONT,      "RC_BIGFONT",      "Supports fonts >64K:",
          RC_STRETCHBLT,   "RC_STRETCHBLT",   "Supports StretchBlt:",
          RC_FLOODFILL,    "RC_FLOODFILL",    "Supports FloodFill:"
          } ;

     static char *szTech [] = { "DT_PLOTTER (Vector plotter)",
                                "DT_RASDISPLAY (Raster display)",
                                "DT_RASPRINTER (Raster printer)",
                                "DT_RASCAMERA (Raster camera)",
                                "DT_CHARSTREAM (Character-stream, PLP)",
                                "DT_METAFILE (Metafile, VDM)",
                                "DT_DISPFILE (Display-file)" } ;
     char        szBuffer [80] ;
     short       i ;

     TextOut (hdc, cxChar, cyChar, szBuffer,
          sprintf (szBuffer, "%-24s%04XH",
               "DRIVERVERSION:", GetDeviceCaps (hdcInfo, DRIVERVERSION))) ;

     TextOut (hdc, cxChar, 2 * cyChar, szBuffer,
          sprintf (szBuffer, "%-24s%-40s",
               "TECHNOLOGY:", szTech [GetDeviceCaps (hdcInfo, TECHNOLOGY)]))

     TextOut (hdc, cxChar, 4 * cyChar, szBuffer,
          sprintf (szBuffer, "CLIPCAPS (Clipping capabilities)")) ;

     for (i = 0 ; i < sizeof clip / sizeof clip [0] ; i++)
          TextOut (hdc, 9 * cxChar, (i + 6) * cyChar, szBuffer,
               sprintf (szBuffer, "%-16s%-28s %3s",
                    clip[i].szMask, clip[i].szDesc,
                    GetDeviceCaps (hdcInfo, CLIPCAPS) & clip[i].nMask ?
                         "Yes" : "No")) ;

     TextOut (hdc, cxChar, 8 * cyChar, szBuffer,
          sprintf (szBuffer, "RASTERCAPS (Raster capabilities)")) ;

     for (i = 0 ; i < sizeof raster / sizeof raster [0] ; i++)
          TextOut (hdc, 9 * cxChar, (i + 10) * cyChar, szBuffer,
               sprintf (szBuffer, "%-16s%-28s %3s",
                    raster[i].szMask, raster[i].szDesc,
                    GetDeviceCaps (hdcInfo, RASTERCAPS) & raster[i].nMask ?
                         "Yes" : "No")) ;
     }

void DoBitCodedCaps (HDC hdc, HDC hdcInfo, short cxChar, short cyChar,
                     short nType)
     {
     static BITS curves [] =
          {
          CC_CIRCLES,    "CC_CIRCLES",    "circles:",
          CC_PIE,        "CC_PIE",        "pie wedges:",
          CC_CHORD,      "CC_CHORD",      "chord arcs:",
          CC_ELLIPSES,   "CC_ELLIPSES",   "ellipses:",
          CC_WIDE,       "CC_WIDE",       "wide borders:",
          CC_STYLED,     "CC_STYLED",     "styled borders:",
          CC_WIDESTYLED, "CC_WIDESTYLED", "wide and styled borders:",
          CC_INTERIORS,  "CC_INTERIORS",  "interiors:"
          } ;

     static BITS lines [] =
          {
          LC_POLYLINE,   "LC_POLYLINE",   "polyline:",
          LC_MARKER,     "LC_MARKER",     "markers:",
          LC_POLYMARKER, "LC_POLYMARKER", "polymarkers",
          LC_WIDE,       "LC_WIDE",       "wide lines:",
          LC_STYLED,     "LC_STYLED",     "styled lines:",
          LC_WIDESTYLED, "LC_WIDESTYLED", "wide and styled lines:",
          LC_INTERIORS,  "LC_INTERIORS",  "interiors:"
          } ;

     static BITS poly [] =
          {
          PC_POLYGON,    "PC_POLYGON",    "alternate fill polygon:",
          PC_RECTANGLE,  "PC_RECTANGLE",  "rectangle:",
          PC_TRAPEZOID,  "PC_TRAPEZOID",  "winding number fill polygon:",
          PC_SCANLINE,   "PC_SCANLINE",   "scanlines:",
          PC_WIDE,       "PC_WIDE",       "wide borders:",
          PC_STYLED,     "PC_STYLED",     "styled borders:",
          PC_WIDESTYLED, "PC_WIDESTYLED", "wide and styled borders:",
          PC_INTERIORS,  "PC_INTERIORS",  "interiors:"
          } ;

     static BITS text [] =
          {
          TC_OP_CHARACTER, "TC_OP_CHARACTER", "character output precision:",
          TC_OP_STROKE,    "TC_OP_STROKE",    "stroke output precision:",
          TC_CP_STROKE,    "TC_CP_STROKE",    "stroke clip precision:",
          TC_CR_90,        "TC_CP_90",        "90 degree character rotation:"
          TC_CR_ANY,       "TC_CR_ANY",       "any character rotation:",
          TC_SF_X_YINDEP,  "TC_SF_X_YINDEP", "scaling independent of X and Y:
          TC_SA_DOUBLE,    "TC_SA_DOUBLE",   "doubled character for scaling:"
          TC_SA_INTEGER,   "TC_SA_INTEGER",  "integer multiples for scaling:"
          TC_SA_CONTIN,    "TC_SA_CONTIN",  "any multiples for exact scaling:
          TC_EA_DOUBLE,    "TC_EA_DOUBLE",  "double weight characters:",
          TC_IA_ABLE,      "TC_IA_ABLE",    "italicizing:",
          TC_UA_ABLE,      "TC_UA_ABLE",    "underlining:",
          TC_SO_ABLE,      "TC_SO_ABLE",    "strikeouts:",
          TC_RA_ABLE,      "TC_RA_ABLE",    "raster fonts:",
          TC_VA_ABLE,      "TC_VA_ABLE",    "vector fonts:"
          } ;

     static struct
          {
          short nIndex ;
          char  *szTitle ;
          BITS  (*pbits) [] ;
          short nSize ;
          }
          bitinfo [] =
          {
          CURVECAPS,  "CURVCAPS (Curve Capabilities)",
                      (BITS (*)[]) curves, sizeof curves / sizeof curves [0],
          LINECAPS,   "LINECAPS (Line Capabilities)",
                      (BITS (*)[]) lines, sizeof lines / sizeof lines [0],
          POLYGONALCAPS, "POLYGONALCAPS (Polygonal Capabilities)",
                      (BITS (*)[]) poly, sizeof poly / sizeof poly [0],
          TEXTCAPS,   "TEXTCAPS (Text Capabilities)",
                      (BITS (*)[]) text, sizeof text / sizeof text [0]
          } ;

     static char szBuffer [80] ;
     BITS        (*pbits) [] = bitinfo [nType].pbits ;
     short       nDevCaps = GetDeviceCaps (hdcInfo, bitinfo [nType].nIndex) ;
     short       i ;

     TextOut (hdc, cxChar, cyChar, bitinfo [nType].szTitle,
                    strlen (bitinfo [nType].szTitle)) ;

     for (i = 0 ; i < bitinfo [nType].nSize ; i++)
          TextOut (hdc, cxChar, (i + 3) * cyChar, szBuffer,
               sprintf (szBuffer, "%-16s %s %-32s %3s",
                    (*pbits)[i].szMask, "Can do", (*pbits)[i].szDesc,
                    nDevCaps & (*pbits)[i].nMask ? "Yes" : "No")) ;
     }


DEVCAPS1.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP11\DEVCAPS1.C

/*------------------------------------------------------
   DEVCAPS1.C -- Displays Device Capability Information
                 (c) Charles Petzold, 1990
  ------------------------------------------------------*/

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

void DoBasicInfo (HDC, HDC, short, short) ;       // in DEVCAPS.C
void DoOtherInfo (HDC, HDC, short, short) ;
void DoBitCodedCaps (HDC, HDC, short, short, short) ;

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "DevCaps" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          !RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Device Capabilities",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

HDC GetPrinterIC ()
     {
     char szPrinter [64] ;
     char *szDevice, *szDriver, *szOutput ;

     GetProfileString ("windows", "device", "", szPrinter, 64) ;

     if ((szDevice = strtok (szPrinter, "," )) &&
         (szDriver = strtok (NULL,      ", ")) &&
         (szOutput = strtok (NULL,      ", ")))

               return CreateIC (szDriver, szDevice, szOutput, NULL) ;

     return NULL ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static short cxChar, cyChar, nCurrentDevice = IDM_SCREEN,
                                  nCurrentInfo   = IDM_BASIC ;
     HDC          hdc, hdcInfo ;
     HMENU        hMenu ;
     PAINTSTRUCT  ps ;
     TEXTMETRIC   tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;

               ReleaseDC (hwnd, hdc) ;
               return 0 ;

          case WM_COMMAND:
               hMenu = GetMenu (hwnd) ;

               switch (wParam)
                    {
                    case IDM_SCREEN:
                    case IDM_PRINTER:
                         CheckMenuItem (hMenu, nCurrentDevice, MF_UNCHECKED)
                         nCurrentDevice = wParam ;
                         CheckMenuItem (hMenu, nCurrentDevice, MF_CHECKED) ;
                         InvalidateRect (hwnd, NULL, TRUE) ;
                         return 0 ;

                    case IDM_BASIC:
                    case IDM_OTHER:
                    case IDM_CURVE:
                    case IDM_LINE:
                    case IDM_POLY:
                    case IDM_TEXT:
                         CheckMenuItem (hMenu, nCurrentInfo, MF_UNCHECKED) ;
                         nCurrentInfo = wParam ;
                         CheckMenuItem (hMenu, nCurrentInfo, MF_CHECKED) ;
                         InvalidateRect (hwnd, NULL, TRUE) ;
                         return 0 ;
                    }
               break ;

          case WM_DEVMODECHANGE:
               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

               if (nCurrentDevice == IDM_SCREEN)
                    hdcInfo = CreateIC ("DISPLAY", NULL, NULL, NULL) ;
               else
                    hdcInfo = GetPrinterIC () ;

               if (hdcInfo)
                    {
                    switch (nCurrentInfo)
                         {
                         case IDM_BASIC:
                              DoBasicInfo (hdc, hdcInfo, cxChar, cyChar) ;
                              break ;

                         case IDM_OTHER:
                              DoOtherInfo (hdc, hdcInfo, cxChar, cyChar) ;
                              break ;

                         case IDM_CURVE:
                         case IDM_LINE:
                         case IDM_POLY:
                         case IDM_TEXT:
                              DoBitCodedCaps (hdc, hdcInfo, cxChar, cyChar,
                                              nCurrentInfo - IDM_CURVE) ;
                              break ;
                         }
                    DeleteDC (hdcInfo) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


DEVCAPS2.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\DEVCAPS2.C

/*------------------------------------------------------------------
   DEVCAPS2.C -- Displays Device Capability Information (Version 2)
                 (c) Charles Petzold, 1990
  ------------------------------------------------------------------*/

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

void DoBasicInfo (HDC, HDC, short, short) ;            // in DEVCAPS.C
void DoOtherInfo (HDC, HDC, short, short) ;
void DoBitCodedCaps (HDC, HDC, short, short, short) ;

typedef VOID (FAR PASCAL *DEVMODEPROC) (HWND, HANDLE, LPSTR, LPSTR) ;

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "DevCaps2" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, NULL,
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

void DoEscSupport (HDC hdc, HDC hdcInfo, short cxChar, short cyChar)
     {
     static struct
          {
          char  *szEscCode ;
          short nEscCode ;
          }
          esc [] =
          {
          "NEWFRAME",          NEWFRAME,
          "ABORTDOC",          ABORTDOC,
          "NEXTBAND",          NEXTBAND,
          "SETCOLORTABLE",     SETCOLORTABLE,
          "GETCOLORTABLE",     GETCOLORTABLE,
          "FLUSHOUTPUT",       FLUSHOUTPUT,
          "DRAFTMODE",         DRAFTMODE,
          "QUERYESCSUPPORT",   QUERYESCSUPPORT,
          "SETABORTPROC",      SETABORTPROC,
          "STARTDOC",          STARTDOC,
          "ENDDOC",            ENDDOC,
          "GETPHYSPAGESIZE",   GETPHYSPAGESIZE,
          "GETPRINTINGOFFSET", GETPRINTINGOFFSET,
          "GETSCALINGFACTOR",  GETSCALINGFACTOR } ;

     static char *szYesNo [] = { "Yes", "No" } ;
     char        szBuffer [32] ;
     POINT       pt ;
     short       n, nReturn ;

     TextOut (hdc, cxChar, cyChar, "Escape Support", 14) ;

     for (n = 0 ; n < sizeof esc / sizeof esc [0] ; n++)
          {
          nReturn = Escape (hdcInfo, QUERYESCSUPPORT, 1,
                                   (LPSTR) & esc[n].nEscCode, NULL) ;
          TextOut (hdc, 6 * cxChar, (n + 3) * cyChar, szBuffer,
               wsprintf (szBuffer, "%-24s %3s", (LPSTR) esc[n].szEscCode,
                         (LPSTR) szYesNo [nReturn > 0 ? 0 : 1])) ;

          if (nReturn > 0 && esc[n].nEscCode >= GETPHYSPAGESIZE
                          && esc[n].nEscCode <= GETSCALINGFACTOR)
               {
               Escape (hdcInfo, esc[n].nEscCode, 0, NULL, (LPSTR) &pt) ;
               TextOut (hdc, 36 * cxChar, (n + 3) * cyChar, szBuffer,
                        wsprintf (szBuffer, "(%u,%u)", pt.x, pt.y)) ;
               }
          }
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static char   szAllDevices [4096], szDevice [32], szDriver [16],
                   szDriverFile [16], szWindowText [64] ;
     static HANDLE hLibrary ;
     static short  n, cxChar, cyChar, nCurrentDevice = IDM_SCREEN,
                                      nCurrentInfo   = IDM_BASIC ;
     char          *szOutput, *szPtr ;
     DEVMODEPROC   lpfnDM ;
     HDC           hdc, hdcInfo ;
     HMENU         hMenu ;
     PAINTSTRUCT   ps ;
     TEXTMETRIC    tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;
               ReleaseDC (hwnd, hdc) ;

               lParam = NULL ;
                                                  // fall through
          case WM_WININICHANGE:
               if (lParam != NULL && lstrcmp ((LPSTR) lParam, "devices") != 0
                    return 0 ;

               hMenu = GetSubMenu (GetMenu (hwnd), 0) ;

               while (GetMenuItemCount (hMenu) > 1)
                    DeleteMenu (hMenu, 1, MF_BYPOSITION) ;

               GetProfileString ("devices", NULL, "", szAllDevices,
                         sizeof szAllDevices) ;

               n = IDM_SCREEN + 1 ;
               szPtr = szAllDevices ;
               while (*szPtr)
                    {
                    AppendMenu (hMenu, n % 16 ? 0 : MF_MENUBARBREAK, n, szPtr
                    n++ ;
                    szPtr += strlen (szPtr) + 1 ;
                    }
               AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ;
               AppendMenu (hMenu, 0, IDM_DEVMODE, "Device Mode") ;

               wParam = IDM_SCREEN ;
                                                  // fall through
          case WM_COMMAND:
               hMenu = GetMenu (hwnd) ;

               if (wParam < IDM_DEVMODE)          // IDM_SCREEN & Printers
                    {
                    CheckMenuItem (hMenu, nCurrentDevice, MF_UNCHECKED) ;
                    nCurrentDevice = wParam ;
                    CheckMenuItem (hMenu, nCurrentDevice, MF_CHECKED) ;
                    }
               else if (wParam == IDM_DEVMODE)
                    {
                    GetMenuString (hMenu, nCurrentDevice, szDevice,
                                   sizeof szDevice, MF_BYCOMMAND) ;

                    GetProfileString ("devices", szDevice, "",
                                      szDriver, sizeof szDriver) ;

                    szOutput = strtok (szDriver, ", ") ;
                    strcat (strcpy (szDriverFile, szDriver), ".DRV") ;

                    if (hLibrary >= 32)
                         FreeLibrary (hLibrary) ;

                    hLibrary = LoadLibrary (szDriverFile) ;
                    if (hLibrary >= 32)
                         {
                         lpfnDM = GetProcAddress (hLibrary, "DEVICEMODE") ;
                         (*lpfnDM) (hwnd, hLibrary, (LPSTR) szDevice,
                                                    (LPSTR) szOutput) ;
                         }
                    }
               else                               // info menu items
                    {
                    CheckMenuItem (hMenu, nCurrentInfo, MF_UNCHECKED) ;
                    nCurrentInfo = wParam ;
                    CheckMenuItem (hMenu, nCurrentInfo, MF_CHECKED) ;
                    }
               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          case WM_INITMENUPOPUP:
               if (lParam == 0)
                    EnableMenuItem (GetMenu (hwnd), IDM_DEVMODE,
                         nCurrentDevice == IDM_SCREEN ?
                              MF_GRAYED : MF_ENABLED) ;
               return 0 ;

          case WM_PAINT:
               strcpy (szWindowText, "Device Capabilities: ") ;

               if (nCurrentDevice == IDM_SCREEN)
                    {
                    strcpy (szDriver, "DISPLAY") ;
                    strcat (szWindowText, szDriver) ;
                    hdcInfo = CreateIC (szDriver, NULL, NULL, NULL) ;
                    }
               else
                    {
                    hMenu = GetMenu (hwnd) ;

                    GetMenuString (hMenu, nCurrentDevice, szDevice,
                                   sizeof szDevice, MF_BYCOMMAND) ;

                    GetProfileString ("devices", szDevice, "", szDriver, 10)
                    szOutput = strtok (szDriver, ", ") ;
                    strcat (szWindowText, szDevice) ;

                    hdcInfo = CreateIC (szDriver, szDevice, szOutput, NULL) ;
                    }
               SetWindowText (hwnd, szWindowText) ;

               hdc = BeginPaint (hwnd, &ps) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

               if (hdcInfo)
                    {
                    switch (nCurrentInfo)
                         {
                         case IDM_BASIC:
                              DoBasicInfo (hdc, hdcInfo, cxChar, cyChar) ;
                              break ;

                         case IDM_OTHER:
                              DoOtherInfo (hdc, hdcInfo, cxChar, cyChar) ;
                              break ;

                         case IDM_CURVE:
                         case IDM_LINE:
                         case IDM_POLY:
                         case IDM_TEXT:
                              DoBitCodedCaps (hdc, hdcInfo, cxChar, cyChar,
                                   nCurrentInfo - IDM_CURVE) ;
                              break ;

                         case IDM_ESC:
                              DoEscSupport (hdc, hdcInfo, cxChar, cyChar) ;
                              break ;
                         }
                    DeleteDC (hdcInfo) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               if (hLibrary >= 32)
                    FreeLibrary (hLibrary) ;

               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


DIGCLOCK.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP05\DIGCLOCK.C

/*-----------------------------------------
   DIGCLOCK.C -- Digital Clock Program
                 (c) Charles Petzold, 1990
  -----------------------------------------*/

#include <windows.h>
#include <time.h>
#define ID_TIMER    1

#define YEAR  (datetime->tm_year % 100)
#define MONTH (datetime->tm_mon  + 1)
#define MDAY  (datetime->tm_mday)
#define WDAY  (datetime->tm_wday)
#define HOUR  (datetime->tm_hour)
#define MIN   (datetime->tm_min)
#define SEC   (datetime->tm_sec)

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG);
void SizeTheWindow (short *, short *, short *, short *) ;

char  sDate [2], sTime [2], sAMPM [2][5] ;
int   iDate, iTime ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "DigClock" ;
     HWND        hwnd;
     MSG         msg;
     short       xStart, yStart, xClient, yClient ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

    RegisterClass (&wndclass) ;
          }

     SizeTheWindow (&xStart, &yStart, &xClient, &yClient) ;

     hwnd = CreateWindow (szAppName, szAppName,
                          WS_POPUP | WS_DLGFRAME | WS_SYSMENU,
                          xStart,  yStart,
                          xClient, yClient,
                          NULL, NULL, hInstance, NULL) ;

     if (!SetTimer (hwnd, ID_TIMER, 1000, NULL))
          {
          MessageBox (hwnd, "Too many clocks or timers!", szAppName,
                      MB_ICONEXCLAMATION | MB_OK) ;
          return FALSE ;
          }

     ShowWindow (hwnd, SW_SHOWNOACTIVATE) ;
     UpdateWindow (hwnd);

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

void SizeTheWindow (short *pxStart,  short *pyStart,
                    short *pxClient, short *pyClient)
     {
     HDC        hdc ;
     TEXTMETRIC tm ;

     hdc = CreateIC ("DISPLAY", NULL, NULL, NULL) ;
     GetTextMetrics (hdc, &tm) ;
     DeleteDC (hdc) ;

     *pxClient = 2 * GetSystemMetrics (SM_CXDLGFRAME) + 16*tm.tmAveCharWidth
     *pxStart  =     GetSystemMetrics (SM_CXSCREEN)   - *pxClient ;
     *pyClient = 2 * GetSystemMetrics (SM_CYDLGFRAME) + 2*tm.tmHeight ;
     *pyStart  =     GetSystemMetrics (SM_CYSCREEN)   - *pyClient ;
     }

void SetInternational (void)
     {
     static char cName [] = "intl" ;

     iDate = GetProfileInt (cName, "iDate", 0) ;
     iTime = GetProfileInt (cName, "iTime", 0) ;

     GetProfileString (cName, "sDate",  "/", sDate,     2) ;
     GetProfileString (cName, "sTime",  ":", sTime,     2) ;
     GetProfileString (cName, "s1159", "AM", sAMPM [0], 5) ;
     GetProfileString (cName, "s2359", "PM", sAMPM [1], 5) ;
     }

void WndPaint (HWND hwnd, HDC hdc)
     {
     static char szWday[] = "Sun\0Mon\0Tue\0Wed\0Thu\0Fri\0Sat" ;
     char        cBuffer[40] ;
     long        lTime ;
     RECT        rect ;
     short       nLength ;
     struct tm   *datetime ;

     time (&lTime) ;
     datetime = localtime (&lTime) ;

     nLength = wsprintf (cBuffer, "  %s  %d%s%02d%s%02d  \r\n",
               (LPSTR) szWday + 4 * WDAY,
               iDate == 1 ? MDAY  : iDate == 2 ? YEAR  : MONTH, (LPSTR) sDate
               iDate == 1 ? MONTH : iDate == 2 ? MONTH : MDAY,  (LPSTR) sDate
               iDate == 1 ? YEAR  : iDate == 2 ? MDAY  : YEAR) ;

     if (iTime == 1)
          nLength += wsprintf (cBuffer + nLength, "  %02d%s%02d%s%02d  ",
                               HOUR, (LPSTR) sTime, MIN, (LPSTR) sTime, SEC)
     else
          nLength += wsprintf (cBuffer + nLength, "  %d%s%02d%s%02d %s  ",
                               (HOUR % 12) ? (HOUR % 12) : 12,
                               (LPSTR) sTime, MIN, (LPSTR) sTime, SEC,
                               (LPSTR) sAMPM [HOUR / 12]) ;

     GetClientRect (hwnd, &rect) ;
     DrawText (hdc, cBuffer, -1, &rect, DT_CENTER | DT_NOCLIP) ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     HDC         hdc ;
     PAINTSTRUCT ps;

     switch (message)
          {
          case WM_CREATE :
               SetInternational () ;
               return 0 ;

          case WM_TIMER :
               InvalidateRect (hwnd, NULL, FALSE) ;
               return 0 ;

          case WM_PAINT :
               hdc = BeginPaint (hwnd, &ps) ;
               WndPaint (hwnd, hdc) ;
               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_WININICHANGE :
               SetInternational () ;
               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          case WM_DESTROY :
               KillTimer (hwnd, ID_TIMER) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


ENVIRON.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP06\ENVIRON.C

/*----------------------------------------
   ENVIRON.C -- Environment List Box
                (c) Charles Petzold, 1990
  ----------------------------------------*/

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#define  MAXENV  4096

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Environ" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = COLOR_WINDOW + 1 ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Environment List Box",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static char szBuffer [MAXENV + 1] ;
     static HWND hwndList, hwndText ;
     HDC         hdc ;
     TEXTMETRIC  tm ;
     WORD        n ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;
               GetTextMetrics (hdc, &tm) ;
               ReleaseDC (hwnd, hdc) ;

               hwndList = CreateWindow ("listbox", NULL,
                              WS_CHILD | WS_VISIBLE | LBS_STANDARD,
                              tm.tmAveCharWidth, tm.tmHeight * 3,
                              tm.tmAveCharWidth * 16 +
                                   GetSystemMetrics (SM_CXVSCROLL),
                              tm.tmHeight * 5,
                              hwnd, 1,
                              GetWindowWord (hwnd, GWW_HINSTANCE), NULL) ;

               hwndText = CreateWindow ("static", NULL,
                              WS_CHILD | WS_VISIBLE | SS_LEFT,
                              tm.tmAveCharWidth,          tm.tmHeight,
                              tm.tmAveCharWidth * MAXENV, tm.tmHeight,
                              hwnd, 2,
                              GetWindowWord (hwnd, GWW_HINSTANCE), NULL) ;

               for (n = 0 ; environ[n] ; n++)
                    {
                    if (strlen (environ [n]) > MAXENV)
                         continue ;
                    *strchr (strcpy (szBuffer, environ [n]), '=') = '\0' ;
                    SendMessage (hwndList, LB_ADDSTRING, 0,
                                 (LONG) (LPSTR) szBuffer) ;
                    }
               return 0 ;

          case WM_SETFOCUS:
               SetFocus (hwndList) ;
               return 0 ;

          case WM_COMMAND:
               if (wParam == 1 && HIWORD (lParam) == LBN_SELCHANGE)
                    {
                    n = (WORD) SendMessage (hwndList, LB_GETCURSEL, 0, 0L) ;
                    n = (WORD) SendMessage (hwndList, LB_GETTEXT, n,
                                            (LONG) (LPSTR) szBuffer) ;

                    strcpy (szBuffer + n + 1, getenv (szBuffer)) ;
                    *(szBuffer + n) = '=' ;

                    SetWindowText (hwndText, szBuffer) ;
                    }
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


FILEDLG.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP10\FILEDLG.C

/*-----------------------------------------------
   FILEDLG.C -- Open and Close File Dialog Boxes
  -----------------------------------------------*/

#include <windows.h>
#include "filedlg.h"

BOOL FAR PASCAL FileOpenDlgProc (HWND, WORD, WORD, LONG) ;
BOOL FAR PASCAL FileSaveDlgProc (HWND, WORD, WORD, LONG) ;

LPSTR lstrchr  (LPSTR str, char ch) ;
LPSTR lstrrchr (LPSTR str, char ch) ;

static char      szDefExt   [5]  ;
static char      szFileName [96] ;
static char      szFileSpec [16] ;
static POFSTRUCT pof ;
static WORD      wFileAttr, wStatus ;

int DoFileOpenDlg (HANDLE hInst, HWND hwnd, char *szFileSpecIn,
                   char *szDefExtIn, WORD wFileAttrIn,
                   char *szFileNameOut, POFSTRUCT pofIn)
     {
     FARPROC lpfnFileOpenDlgProc ;
     int     iReturn ;

     lstrcpy (szFileSpec, szFileSpecIn) ;
     lstrcpy (szDefExt,   szDefExtIn) ;
     wFileAttr = wFileAttrIn ;
     pof = pofIn ;

     lpfnFileOpenDlgProc = MakeProcInstance (FileOpenDlgProc, hInst) ;

     iReturn = DialogBox (hInst, "FileOpen", hwnd, lpfnFileOpenDlgProc) ;

     FreeProcInstance (lpfnFileOpenDlgProc) ;

     lstrcpy (szFileNameOut, szFileName) ;
     return iReturn ;
     }

int DoFileSaveDlg (HANDLE hInst, HWND hwnd, char *szFileSpecIn,
                   char *szDefExtIn, WORD *pwStatusOut,
                   char *szFileNameOut, POFSTRUCT pofIn)
     {
     FARPROC lpfnFileSaveDlgProc ;
     int     iReturn ;

     lstrcpy (szFileSpec, szFileSpecIn) ;
     lstrcpy (szDefExt,   szDefExtIn) ;
     pof = pofIn ;

     lpfnFileSaveDlgProc = MakeProcInstance (FileSaveDlgProc, hInst) ;

     iReturn = DialogBox (hInst, "FileSave", hwnd, lpfnFileSaveDlgProc) ;

     FreeProcInstance (lpfnFileSaveDlgProc) ;

     lstrcpy (szFileNameOut, szFileName) ;
     *pwStatusOut = wStatus ;
     return iReturn ;
     }

BOOL FAR PASCAL FileOpenDlgProc (HWND hDlg, WORD message,
                                 WORD wParam, LONG lParam)
     {
     char  cLastChar ;
     short nEditLen ;

     switch (message)
        {
        case WM_INITDIALOG:
           SendDlgItemMessage (hDlg, IDD_FNAME, EM_LIMITTEXT, 80, 0L) ;
           DlgDirList (hDlg, szFileSpec, IDD_FLIST, IDD_FPATH, wFileAttr) ;
           SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;
           return TRUE ;

        case WM_COMMAND:
           switch (wParam)
              {
              case IDD_FLIST:
                 switch (HIWORD (lParam))
                    {
                    case LBN_SELCHANGE:
                       if (DlgDirSelect (hDlg, szFileName, IDD_FLIST))
                          lstrcat (szFileName, szFileSpec) ;
                       SetDlgItemText (hDlg, IDD_FNAME, szFileName) ;
                       return TRUE ;

                    case LBN_DBLCLK:
                       if (DlgDirSelect (hDlg, szFileName, IDD_FLIST))
                          {
                          lstrcat (szFileName, szFileSpec) ;
                          DlgDirList (hDlg, szFileName, IDD_FLIST, IDD_FPATH,
                                                              wFileAttr) ;
                          SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;
                          }
                       else
                          {
                          SetDlgItemText (hDlg, IDD_FNAME, szFileName) ;
                          SendMessage (hDlg, WM_COMMAND, IDOK, 0L) ;
                          }
                       return TRUE ;
                    }
                 break ;

              case IDD_FNAME:
                 if (HIWORD (lParam) == EN_CHANGE)
                    EnableWindow (GetDlgItem (hDlg, IDOK),
                       (BOOL) SendMessage (LOWORD (lParam),
                                             WM_GETTEXTLENGTH, 0, 0L)) ;
                 return TRUE ;

              case IDOK:
                 GetDlgItemText (hDlg, IDD_FNAME, szFileName, 80) ;

                 nEditLen  = lstrlen (szFileName) ;
                 cLastChar = *AnsiPrev (szFileName, szFileName + nEditLen) ;

                 if (cLastChar == '\\' || cLastChar == ':')
                    lstrcat (szFileName, szFileSpec) ;

                 if (lstrchr (szFileName, '*') || lstrchr (szFileName, '?'))
                    {
                    if (DlgDirList (hDlg, szFileName, IDD_FLIST,
                                          IDD_FPATH, wFileAttr))
                       {
                       lstrcpy (szFileSpec, szFileName) ;
                       SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;
                       }
                    else
                       MessageBeep (0) ;

                    return TRUE ;
                    }

                 lstrcat (lstrcat (szFileName, "\\"), szFileSpec) ;

                 if (DlgDirList (hDlg, szFileName, IDD_FLIST,
                                                   IDD_FPATH, wFileAttr))
                    {
                    lstrcpy (szFileSpec, szFileName) ;
                    SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;
                    return TRUE ;
                    }

                 szFileName [nEditLen] = '\0' ;

                 if (-1 == OpenFile (szFileName, pof, OF_READ | OF_EXIST))
                    {
                    lstrcat (szFileName, szDefExt) ;
                    if (-1 == OpenFile (szFileName, pof, OF_READ | OF_EXIST))
                       {
                       MessageBeep (0) ;
                       return TRUE ;
                       }
                    }
                 lstrcpy (szFileName,
                          AnsiNext (lstrrchr (pof->szPathName, '\\'))) ;

                 OemToAnsi (szFileName, szFileName) ;
                 EndDialog (hDlg, TRUE) ;
                 return TRUE ;

              case IDCANCEL:
                 EndDialog (hDlg, FALSE) ;
                 return TRUE ;
              }
        }
     return FALSE ;
     }

BOOL FAR PASCAL FileSaveDlgProc (HWND hDlg, WORD message,
                                 WORD wParam, LONG lParam)
     {
     switch (message)
        {
        case WM_INITDIALOG:
           SendDlgItemMessage (hDlg, IDD_FNAME, EM_LIMITTEXT, 80, 0L) ;
           DlgDirList (hDlg, szFileSpec, 0, IDD_FPATH, 0) ;
           SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;
           return TRUE ;

        case WM_COMMAND:
           switch (wParam)
              {
              case IDD_FNAME:
                 if (HIWORD (lParam) == EN_CHANGE)
                    EnableWindow (GetDlgItem (hDlg, IDOK),
                       (BOOL) SendMessage (LOWORD (lParam),
                                             WM_GETTEXTLENGTH, 0, 0L)) ;
                 return TRUE ;

              case IDOK:
                 GetDlgItemText (hDlg, IDD_FNAME, szFileName, 80) ;

                 if (-1 == OpenFile (szFileName, pof, OF_PARSE))
                    {
                    MessageBeep (0) ;
                    return TRUE ;
                    }

                 if (!lstrchr (AnsiNext (lstrrchr (pof->szPathName, '\\')),
                               '.'))
                    lstrcat (szFileName, szDefExt) ;

                 if (-1 != OpenFile (szFileName, pof, OF_WRITE | OF_EXIST))
                    wStatus = 1 ;

                 else if (-1 != OpenFile (szFileName, pof,
                                                  OF_CREATE | OF_EXIST))
                    wStatus = 0 ;

                 else
                    {
                    MessageBeep (0) ;
                    return TRUE ;
                    }

                 lstrcpy (szFileName,
                          AnsiNext (lstrrchr (pof->szPathName, '\\'))) ;

                 OemToAnsi (szFileName, szFileName) ;
                 EndDialog (hDlg, TRUE) ;
                 return TRUE ;

              case IDCANCEL:
                 EndDialog (hDlg, FALSE) ;
                 return TRUE ;
              }
        }
     return FALSE ;
     }

LPSTR lstrchr (LPSTR str, char ch)
     {
     while (*str)
          {
          if (ch == *str)
               return str ;

          str = AnsiNext (str) ;
          }
     return NULL ;
     }

LPSTR lstrrchr (LPSTR str, char ch)
     {
     LPSTR strl = str + lstrlen (str) ;

     do
          {
          if (ch == *strl)
               return strl ;

          strl = AnsiPrev (str, strl) ;
          }
     while (strl > str) ;

     return NULL ;
     }


FILEDLG.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\FILEDLG.C

/*-----------------------------------------------
   FILEDLG.C -- Open and Close File Dialog Boxes
  -----------------------------------------------*/

#include <windows.h>
#include "filedlg.h"

BOOL FAR PASCAL FileOpenDlgProc (HWND, WORD, WORD, LONG) ;
BOOL FAR PASCAL FileSaveDlgProc (HWND, WORD, WORD, LONG) ;

LPSTR lstrchr  (LPSTR str, char ch) ;
LPSTR lstrrchr (LPSTR str, char ch) ;

static char      szDefExt   [5]  ;
static char      szFileName [96] ;
static char      szFileSpec [16] ;
static POFSTRUCT pof ;
static WORD      wFileAttr, wStatus ;

int DoFileOpenDlg (HANDLE hInst, HWND hwnd, char *szFileSpecIn,
                   char *szDefExtIn, WORD wFileAttrIn,
                   char *szFileNameOut, POFSTRUCT pofIn)
     {
     FARPROC lpfnFileOpenDlgProc ;
     int     iReturn ;

     lstrcpy (szFileSpec, szFileSpecIn) ;
     lstrcpy (szDefExt,   szDefExtIn) ;
     wFileAttr = wFileAttrIn ;
     pof = pofIn ;

     lpfnFileOpenDlgProc = MakeProcInstance (FileOpenDlgProc, hInst) ;

     iReturn = DialogBox (hInst, "FileOpen", hwnd, lpfnFileOpenDlgProc) ;

     FreeProcInstance (lpfnFileOpenDlgProc) ;

     lstrcpy (szFileNameOut, szFileName) ;
     return iReturn ;
     }

int DoFileSaveDlg (HANDLE hInst, HWND hwnd, char *szFileSpecIn,
                   char *szDefExtIn, WORD *pwStatusOut,
                   char *szFileNameOut, POFSTRUCT pofIn)
     {
     FARPROC lpfnFileSaveDlgProc ;
     int     iReturn ;

     lstrcpy (szFileSpec, szFileSpecIn) ;
     lstrcpy (szDefExt,   szDefExtIn) ;
     pof = pofIn ;

     lpfnFileSaveDlgProc = MakeProcInstance (FileSaveDlgProc, hInst) ;

     iReturn = DialogBox (hInst, "FileSave", hwnd, lpfnFileSaveDlgProc) ;

     FreeProcInstance (lpfnFileSaveDlgProc) ;

     lstrcpy (szFileNameOut, szFileName) ;
     *pwStatusOut = wStatus ;
     return iReturn ;
     }

BOOL FAR PASCAL FileOpenDlgProc (HWND hDlg, WORD message,
                                 WORD wParam, LONG lParam)
     {
     char  cLastChar ;
     short nEditLen ;

     switch (message)
        {
        case WM_INITDIALOG:
           SendDlgItemMessage (hDlg, IDD_FNAME, EM_LIMITTEXT, 80, 0L) ;
           DlgDirList (hDlg, szFileSpec, IDD_FLIST, IDD_FPATH, wFileAttr) ;
           SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;
           return TRUE ;

        case WM_COMMAND:
           switch (wParam)
              {
              case IDD_FLIST:
                 switch (HIWORD (lParam))
                    {
                    case LBN_SELCHANGE:
                       if (DlgDirSelect (hDlg, szFileName, IDD_FLIST))
                          lstrcat (szFileName, szFileSpec) ;
                       SetDlgItemText (hDlg, IDD_FNAME, szFileName) ;
                       return TRUE ;

                    case LBN_DBLCLK:
                       if (DlgDirSelect (hDlg, szFileName, IDD_FLIST))
                          {
                          lstrcat (szFileName, szFileSpec) ;
                          DlgDirList (hDlg, szFileName, IDD_FLIST, IDD_FPATH,
                                                              wFileAttr) ;
                          SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;
                          }
                       else
                          {
                          SetDlgItemText (hDlg, IDD_FNAME, szFileName) ;
                          SendMessage (hDlg, WM_COMMAND, IDOK, 0L) ;
                          }
                       return TRUE ;
                    }
                 break ;

              case IDD_FNAME:
                 if (HIWORD (lParam) == EN_CHANGE)
                    EnableWindow (GetDlgItem (hDlg, IDOK),
                       (BOOL) SendMessage (LOWORD (lParam),
                                             WM_GETTEXTLENGTH, 0, 0L)) ;
                 return TRUE ;

              case IDOK:
                 GetDlgItemText (hDlg, IDD_FNAME, szFileName, 80) ;

                 nEditLen  = lstrlen (szFileName) ;
                 cLastChar = *AnsiPrev (szFileName, szFileName + nEditLen) ;

                 if (cLastChar == '\\' || cLastChar == ':')
                    lstrcat (szFileName, szFileSpec) ;

                 if (lstrchr (szFileName, '*') || lstrchr (szFileName, '?'))
                    {
                    if (DlgDirList (hDlg, szFileName, IDD_FLIST,
                                          IDD_FPATH, wFileAttr))
                       {
                       lstrcpy (szFileSpec, szFileName) ;
                       SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;
                       }
                    else
                       MessageBeep (0) ;

                    return TRUE ;
                    }

                 lstrcat (lstrcat (szFileName, "\\"), szFileSpec) ;

                 if (DlgDirList (hDlg, szFileName, IDD_FLIST,
                                                   IDD_FPATH, wFileAttr))
                    {
                    lstrcpy (szFileSpec, szFileName) ;
                    SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;
                    return TRUE ;
                    }

                 szFileName [nEditLen] = '\0' ;

                 if (-1 == OpenFile (szFileName, pof, OF_READ | OF_EXIST))
                    {
                    lstrcat (szFileName, szDefExt) ;
                    if (-1 == OpenFile (szFileName, pof, OF_READ | OF_EXIST))
                       {
                       MessageBeep (0) ;
                       return TRUE ;
                       }
                    }
                    lstrcpy (szFileName,
                             AnsiNext (lstrrchr (pof->szPathName, '\\'))) ;

                 OemToAnsi (szFileName, szFileName) ;
                 EndDialog (hDlg, TRUE) ;
                 return TRUE ;

              case IDCANCEL:
                 EndDialog (hDlg, FALSE) ;
                 return TRUE ;
              }
        }
     return FALSE ;
     }

BOOL FAR PASCAL FileSaveDlgProc (HWND hDlg, WORD message,
                                 WORD wParam, LONG lParam)
     {
     switch (message)
        {
        case WM_INITDIALOG:
           SendDlgItemMessage (hDlg, IDD_FNAME, EM_LIMITTEXT, 80, 0L) ;
           DlgDirList (hDlg, szFileSpec, 0, IDD_FPATH, 0) ;
           SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;
           return TRUE ;

        case WM_COMMAND:
           switch (wParam)
              {
              case IDD_FNAME:
                 if (HIWORD (lParam) == EN_CHANGE)
                    EnableWindow (GetDlgItem (hDlg, IDOK),
                       (BOOL) SendMessage (LOWORD (lParam),
                                             WM_GETTEXTLENGTH, 0, 0L)) ;
                 return TRUE ;

              case IDOK:
                 GetDlgItemText (hDlg, IDD_FNAME, szFileName, 80) ;

                 if (-1 == OpenFile (szFileName, pof, OF_PARSE))
                    {
                    MessageBeep (0) ;
                    return TRUE ;
                    }

                 if (!lstrchr (AnsiNext (lstrrchr (pof->szPathName, '\\')),
                               '.'))
                    lstrcat (szFileName, szDefExt) ;

                 if (-1 != OpenFile (szFileName, pof, OF_WRITE | OF_EXIST))
                    wStatus = 1 ;

                 else if (-1 != OpenFile (szFileName, pof,
                                                  OF_CREATE | OF_EXIST))
                    wStatus = 0 ;

                 else
                    {
                    MessageBeep (0) ;
                    return TRUE ;
                    }

                 lstrcpy (szFileName,
                          AnsiNext (lstrrchr (pof->szPathName, '\\'))) ;

                 OemToAnsi (szFileName, szFileName) ;
                 EndDialog (hDlg, TRUE) ;
                 return TRUE ;

              case IDCANCEL:
                 EndDialog (hDlg, FALSE) ;
                 return TRUE ;
              }
        }
     return FALSE ;
     }

LPSTR lstrchr (LPSTR str, char ch)
     {
     while (*str)
          {
          if (ch == *str)
               return str ;

          str = AnsiNext (str) ;
          }
     return NULL ;
     }

LPSTR lstrrchr (LPSTR str, char ch)
     {
     LPSTR strl = str + lstrlen (str) ;

     do
          {
          if (ch == *strl)
               return strl ;

          strl = AnsiPrev (str, strl) ;
          }
     while (strl > str) ;

     return NULL ;
     }


FONTLIST.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP14\FONTLIST.C

/*-----------------------------------------
   FONTLIST.C -- Font Enumeration Program
                 (c) Charles Petzold, 1990
  -----------------------------------------*/

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

typedef struct
     {
     GLOBALHANDLE hGMem ;
     short        nCount ;
     }
     ENUMER ;

typedef struct
     {
     short        nFontType ;
     LOGFONT      lf ;
     TEXTMETRIC   tm ;
     }
     FONT ;

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
int  FAR PASCAL EnumAllFaces (LPLOGFONT, LPTEXTMETRIC, short, ENUMER FAR *) ;
int  FAR PASCAL EnumAllFonts (LPLOGFONT, LPTEXTMETRIC, short, ENUMER FAR *) ;

char szAppName[] = "FontList" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }
     hwnd = CreateWindow (szAppName, "Font Enumeration",
                          WS_OVERLAPPEDWINDOW | WS_VSCROLL,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

int FAR PASCAL EnumAllFaces (LPLOGFONT lf, LPTEXTMETRIC tm,
                             short nFontType, ENUMER FAR *enumer)
     {
     LPSTR lpFaces ;

     if (NULL == GlobalReAlloc (enumer->hGMem,
                         (DWORD) LF_FACESIZE * (1 + enumer->nCount),
                         GMEM_MOVEABLE))
          return 0 ;

     lpFaces = GlobalLock (enumer->hGMem) ;
     lstrcpy (lpFaces + enumer->nCount * LF_FACESIZE, lf->lfFaceName) ;
     GlobalUnlock (enumer->hGMem) ;
     enumer->nCount ++ ;
     return 1 ;
     }

int FAR PASCAL EnumAllFonts (LPLOGFONT lf, LPTEXTMETRIC tm,
                             short nFontType, ENUMER FAR *enumer)
     {
     FONT FAR *font ;

     if (NULL == GlobalReAlloc (enumer->hGMem,
                         (DWORD) sizeof (FONT) * (1 + enumer->nCount),
                         GMEM_MOVEABLE))
          return 0 ;

     font = (FONT FAR *) GlobalLock (enumer->hGMem) + enumer->nCount ;
     font->nFontType = nFontType ;
     font->lf = *lf ;
     font->tm = *tm ;

     GlobalUnlock (enumer->hGMem) ;
     enumer->nCount ++ ;
     return 1 ;
     }

void Display (HDC hdc, short cxChar, short cyChar, FONT FAR *font)
     {
     static FONT f ;

     static char *szYN [] = { "No",         "Yes" } ;
     static char *szCS [] = { "ANSI",       "?????",   "Kanji",    "OEM" } ;
     static char *szOP [] = { "Default",    "String",  "Char",    "Stroke" }
     static char *szCP [] = { "Default",    "Char",    "Stroke",   "?????" }
     static char *szQU [] = { "Draft",      "Default", "Proof",    "?????" }
     static char *szP1 [] = { "Default",    "Fixed",   "Variable", "?????" }
     static char *szP2 [] = { "Fixed",      "Variable" } ;
     static char *szFA [] = { "Don't Care", "Roman",      "Swiss", "Modern",
                              "Script",     "Decorative", "?????", "?????" }
     static char *szVR [] = { "Stroke",     "Raster" } ;
     static char *szGD [] = { "GDI",        "Device" } ;

     static struct
          {
          short x ;
          short y ;
          char  *szFmt ;
          short *pData ;
          }
          shorts [] =
          {
           1,  1, "LOGFONT",            NULL,
           1,  2, "-------",            NULL,
           1,  3, "Height:      %10d",  &f.lf.lfHeight,
           1,  4, "Width:       %10d",  &f.lf.lfWidth,
           1,  5, "Escapement:  %10d",  &f.lf.lfEscapement,
           1,  6, "Orientation: %10d",  &f.lf.lfOrientation,
           1,  7, "Weight:      %10d",  &f.lf.lfWeight,
          28,  1, "TEXTMETRIC",         NULL,
          28,  2, "----------",         NULL,
          28,  3, "Height:       %5d",  &f.tm.tmHeight,
          28,  4, "Ascent:       %5d",  &f.tm.tmAscent,
          28,  5, "Descent:      %5d",  &f.tm.tmDescent,
          28,  6, "Int. Leading: %5d",  &f.tm.tmInternalLeading,
          28,  7, "Ext. Leading: %5d",  &f.tm.tmExternalLeading,
          28,  8, "Ave. Width:   %5d",  &f.tm.tmAveCharWidth,
          28,  9, "Max. Width:   %5d",  &f.tm.tmMaxCharWidth,
          28, 10, "Weight:       %5d",  &f.tm.tmWeight,
          51, 10, "Overhang:     %10d", &f.tm.tmOverhang,
          51, 11, "Digitized X:  %10d", &f.tm.tmDigitizedAspectX,
          51, 12, "Digitized Y:  %10d", &f.tm.tmDigitizedAspectY
          } ;

     static struct
          {
          short x ;
          short y ;
          char  *szFmt ;
          BYTE  *pData ;
          }
          bytes [] =
          {
          51,  3, "First Char:   %10d", &f.tm.tmFirstChar,
          51,  4, "Last Char:    %10d", &f.tm.tmLastChar,
          51,  5, "Default Char: %10d", &f.tm.tmDefaultChar,
          51,  6, "Break Char:   %10d", &f.tm.tmBreakChar
          } ;

     static struct
          {
          short x ;
          short y ;
          char  *szFmt ;
          BYTE  *pData ;
          char  **szArray ;
          short sAnd ;
          short sShift ;
          }
          strings [] =
          {
           1,  8, "Italic:      %10s",  &f.lf.lfItalic,         szYN, 1,    0
           1,  9, "Underline:   %10s",  &f.lf.lfUnderline,      szYN, 1,    0
           1, 10, "Strike-Out:  %10s",  &f.lf.lfStrikeOut,      szYN, 1,    0
           1, 11, "Char Set:    %10s",  &f.lf.lfCharSet,        szCS, 0xC0, 6
           1, 12, "Out  Prec:   %10s",  &f.lf.lfOutPrecision,   szOP, 3,    0
           1, 13, "Clip Prec:   %10s",  &f.lf.lfClipPrecision,  szCP, 3,    0
           1, 14, "Quality:     %10s",  &f.lf.lfQuality,        szQU, 3,    0
           1, 15, "Pitch:       %10s",  &f.lf.lfPitchAndFamily, szP1, 3,    0
           1, 16, "Family:      %10s",  &f.lf.lfPitchAndFamily, szFA, 0x70, 4
          28, 11, "Italic:       %5s",  &f.tm.tmItalic,         szYN, 1,    0
          28, 12, "Underline:    %5s",  &f.tm.tmUnderlined,     szYN, 1,    0
          28, 13, "Strike-Out:   %5s",  &f.tm.tmStruckOut,      szYN, 1,    0
          51,  7, "Pitch:        %10s", &f.tm.tmPitchAndFamily, szP2, 1,    0
          51,  8, "Family:       %10s", &f.tm.tmPitchAndFamily, szFA, 0x70, 4
          51,  9, "Char Set:     %10s", &f.tm.tmCharSet,        szCS, 0xC0, 6
          36, 15, "Font Type:  %6s",    (BYTE *) &f.nFontType,  szVR, 1,    0
          55, 15, "%s",                 (BYTE *) &f.nFontType,  szGD, 2,    1
          } ;

     char szBuffer [80] ;
     int  i ;

     f = *font ;

     for (i = 0 ; i < sizeof shorts / sizeof shorts [0] ; i++)
          TextOut (hdc, cxChar * shorts[i].x, cyChar * shorts[i].y, szBuffer,
                   wsprintf (szBuffer, shorts[i].szFmt,
                             *shorts[i].pData)) ;

     for (i = 0 ; i < sizeof bytes / sizeof bytes [0] ; i++)
          TextOut (hdc, cxChar * bytes[i].x, cyChar * bytes[i].y, szBuffer,
                   wsprintf (szBuffer, bytes[i].szFmt,
                             *bytes[i].pData)) ;

     for (i = 0 ; i < sizeof strings / sizeof strings [0] ; i++)
          TextOut (hdc, cxChar * strings[i].x, cyChar * strings[i].y, szBuffe
                   wsprintf (szBuffer, strings[i].szFmt,
                             (LPSTR) ((strings[i].szArray)
                                  [(*strings[i].pData & strings[i].sAnd) >>
                                        strings[i].sShift]))) ;

     TextOut (hdc, cxChar, cyChar * 17, szBuffer,
              wsprintf (szBuffer, "Face Name:   %10s",
                        (LPSTR) f.lf.lfFaceName)) ;
     }

HDC GetPrinterIC ()
     {
     char szPrinter [64] ;
     char *szDevice, *szDriver, *szOutput ;

     GetProfileString ("windows", "device", "", szPrinter, 64) ;

     if ((szDevice = strtok (szPrinter, "," )) &&
         (szDriver = strtok (NULL,      ", ")) &&
         (szOutput = strtok (NULL,      ", ")))

               return CreateIC (szDriver, szDevice, szOutput, NULL) ;

     return NULL ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL    bHaveInfo = FALSE ;
     static ENUMER  enumer1, enumer2 ;
     static FARPROC lpfnEnumAllFaces, lpfnEnumAllFonts ;
     static short   cxChar, cyChar, nCurrent ;
     static WORD    wCurrentDC = IDM_SCREEN ;
     HANDLE         hInstance ;
     HDC            hdc ;
     HFONT          hFont ;
     HMENU          hMenu ;
     FONT FAR       *font ;
     LPSTR          lpFaces ;
     PAINTSTRUCT    ps ;
     short          i ;
     TEXTMETRIC     tm ;

     switch (message)
          {
          case WM_CREATE:
               hInstance = ((LPCREATESTRUCT) lParam)-> hInstance ;
               lpfnEnumAllFaces = MakeProcInstance (EnumAllFaces, hInstance)
               lpfnEnumAllFonts = MakeProcInstance (EnumAllFonts, hInstance)

               hdc = GetDC (hwnd) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

               GetTextMetrics (hdc, (LPTEXTMETRIC) &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;

               ReleaseDC (hwnd, hdc) ;
               return 0 ;

          case WM_COMMAND:
               if (wParam == IDM_EXIT)
                    {
                    SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
                    return 0 ;
                    }
               else if (wParam == wCurrentDC)
                    return 0 ;

               hMenu = GetMenu (hwnd) ;
               CheckMenuItem (hMenu, wCurrentDC, MF_UNCHECKED) ;
               CheckMenuItem (hMenu, wCurrentDC = wParam, MF_CHECKED) ;

                                        // fall through

          case WM_DEVMODECHANGE:
          case WM_FONTCHANGE:
               bHaveInfo = FALSE ;
               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          case WM_PAINT:
               if (!bHaveInfo)
                    {
                    if (enumer2.hGMem)
                         GlobalFree (enumer2.hGMem) ;

                    enumer1.hGMem  = GlobalAlloc (GHND, 1L) ;
                    enumer1.nCount = 0 ;

                    enumer2.hGMem  = GlobalAlloc (GHND, 1L) ;
                    enumer2.nCount = 0 ;

                    if (NULL == enumer1.hGMem || NULL == enumer2.hGMem)
                         goto MEMORY_ERROR ;

                    if (wCurrentDC == IDM_SCREEN)
                         hdc = CreateIC ("DISPLAY", NULL, NULL, NULL) ;
                    else
                         hdc = GetPrinterIC () ;

                    if (hdc)
                         {
                         if (0 == EnumFonts (hdc, NULL, lpfnEnumAllFaces,
                                                  (LPSTR) &enumer1))
                              goto MEMORY_ERROR ;

                         lpFaces = GlobalLock (enumer1.hGMem) ;

                         for (i = 0 ; i < enumer1.nCount ; i++)
                              if (0 == EnumFonts (hdc,
                                             lpFaces + i * LF_FACESIZE,
                                             lpfnEnumAllFonts,
                                             (LPSTR) &enumer2))
                                   goto MEMORY_ERROR ;

                         GlobalUnlock (enumer1.hGMem) ;
                         enumer2.nCount-- ;

                         DeleteDC (hdc) ;
                         bHaveInfo = TRUE ;
                         }
                    GlobalFree (enumer1.hGMem) ;
                    SetScrollRange (hwnd, SB_VERT, 0, enumer2.nCount, FALSE)
                    SetScrollPos   (hwnd, SB_VERT, nCurrent = 0, TRUE) ;
                    }

               hdc = BeginPaint (hwnd, &ps) ;

               if (bHaveInfo)
                    {
                    SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

                    font = (FONT FAR *) GlobalLock (enumer2.hGMem) + nCurrent
                    Display (hdc, cxChar, cyChar, font) ;

                    hFont = SelectObject (hdc, CreateFontIndirect (&font->lf)

                    TextOut (hdc, 1 * cxChar, 19 * cyChar,
                        "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz
                         52) ;

                    GlobalUnlock (enumer2.hGMem) ;
                    DeleteObject (SelectObject (hdc, hFont)) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_KEYDOWN:
               switch (wParam)
                    {
                    case VK_HOME:
                         SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0L) ;
                         break ;
                    case VK_END:
                         SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0L) ;
                         break ;
                    case VK_LEFT:
                    case VK_UP:
                    case VK_PRIOR:
                         SendMessage (hwnd, WM_VSCROLL, SB_LINEUP, 0L) ;
                         break ;
                    case VK_RIGHT:
                    case VK_DOWN:
                    case VK_NEXT:
                         SendMessage (hwnd, WM_VSCROLL, SB_LINEDOWN, 0L) ;
                         break ;
                    default:
                         return 0 ;
                    }
               return 0 ;

          case WM_VSCROLL:
               switch (wParam)
                    {
                    case SB_TOP:
                         nCurrent = 0 ;
                         break ;
                    case SB_BOTTOM:
                         nCurrent = enumer2.nCount ;
                         break ;
                    case SB_LINEUP:
                    case SB_PAGEUP:
                         nCurrent -- ;
                         break ;
                    case SB_LINEDOWN:
                    case SB_PAGEDOWN:
                         nCurrent ++ ;
                         break ;
                    case SB_THUMBPOSITION:
                         nCurrent = LOWORD (lParam) ;
                         break ;
                    default:
                         return 0 ;
                    }
               nCurrent = min (max (0, nCurrent), enumer2.nCount) ;
               SetScrollPos (hwnd, SB_VERT, nCurrent, TRUE) ;
               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          MEMORY_ERROR:
               MessageBox (hwnd, "Cannot allocate memory, must end.",
                    szAppName, MB_OK | MB_ICONSTOP | MB_SYSTEMMODAL) ;

                                             // fall through
          case WM_CLOSE:
               DestroyWindow (hwnd) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


FORMFEED.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\FORMFEED.C

/*---------------------------------------------
   FORMFEED.C -- Advances printer to next page
                 (c) Charles Petzold, 1990
  ---------------------------------------------*/

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

HDC  GetPrinterDC (void) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szMsg [] = "FormFeed" ;
     HDC         hdcPrint ;

     if (hdcPrint = GetPrinterDC ())
          {
          if (Escape (hdcPrint, STARTDOC, sizeof szMsg - 1, szMsg, NULL) > 0)
               if (Escape (hdcPrint, NEWFRAME, 0, NULL, NULL) > 0)
                    Escape (hdcPrint, ENDDOC, 0, NULL, NULL) ;

          DeleteDC (hdcPrint) ;
          }
     return FALSE ;
     }

HDC GetPrinterDC (void)
     {
     static char szPrinter [80] ;
     char        *szDevice, *szDriver, *szOutput ;

     GetProfileString ("windows", "device", ",,,", szPrinter, 80) ;

     if ((szDevice = strtok (szPrinter, "," )) &&
         (szDriver = strtok (NULL,      ", ")) &&
         (szOutput = strtok (NULL,      ", ")))

               return CreateDC (szDriver, szDevice, szOutput, NULL) ;

     return 0 ;
     }


FREEMEM.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP05\FREEMEM.C

/*------------------------------------------
   FREEMEM.C -- Free Memory Display Program
                (c) Charles Petzold, 1990
  ------------------------------------------*/

#include <windows.h>
#include <stdio.h>
#define ID_TIMER    1

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "FreeMem" ;
     HDC         hdc ;
     HWND        hwnd ;
     MSG         msg ;
     TEXTMETRIC  tm ;
     WNDCLASS    wndclass ;

     if (hPrevInstance)
          return FALSE ;

     wndclass.style         = CS_HREDRAW | CS_VREDRAW;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = NULL ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;

     !RegisterClass (&wndclass) ;

     hwnd = CreateWindow (szAppName, "Free Memory",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     hdc = GetDC (hwnd) ;
     GetTextMetrics (hdc, &tm) ;
     ReleaseDC (hwnd, hdc) ;

     if (4 * tm.tmAveCharWidth > GetSystemMetrics (SM_CXICON) ||
               2 * tm.tmHeight > GetSystemMetrics (SM_CYICON))
          {
          MessageBox (hwnd, "Icon size too small for display!",
                      szAppName, MB_ICONEXCLAMATION | MB_OK) ;
          return FALSE ;
          }

     if (!SetTimer (hwnd, ID_TIMER, 1000, NULL))
          {
          MessageBox (hwnd, "Too many clocks or timers!",
                      szAppName, MB_ICONEXCLAMATION | MB_OK) ;
          return FALSE ;
          }

     ShowWindow (hwnd, SW_SHOWMINNOACTIVE) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static DWORD  dwFreeMem, dwPrevMem ;
     static RECT   rect ;
     char          cBuffer [20] ;
     HDC           hdc ;
     PAINTSTRUCT   ps ;

     switch (message)
          {
          case WM_TIMER:
               dwFreeMem = GetFreeSpace (0) ;

               if (dwFreeMem != dwPrevMem)
                    InvalidateRect (hwnd, NULL, TRUE) ;

               dwPrevMem = dwFreeMem ;
               return 0 ;

          case WM_SIZE:
               GetClientRect (hwnd, &rect) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               DrawText (hdc, cBuffer,
                         sprintf (cBuffer, "%.2f megs",
                                  dwFreeMem / 1024.0 / 1024.0),
                         &rect, DT_WORDBREAK) ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_QUERYOPEN:
               return 0 ;

          case WM_DESTROY:
               KillTimer (hwnd, ID_TIMER) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


GRAFMENU.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP09\GRAFMENU.C

/*----------------------------------------------
   GRAFMENU.C -- Demonstrates Bitmap Menu Items
                 (c) Charles Petzold, 1990
  ----------------------------------------------*/

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

long FAR PASCAL WndProc  (HWND, WORD, WORD, LONG) ;
HBITMAP StretchBitmap (HBITMAP) ;
HBITMAP GetBitmapFont (int) ;

char szAppName [] = "GrafMenu" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HBITMAP  hBitmapHelp, hBitmapFile, hBitmapEdit,
              hBitmapFont, hBitmapPopFont [3] ;
     HMENU    hMenu, hMenuPopup ;
     HWND     hwnd ;
     int      i ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hMenu = CreateMenu () ;

     hMenuPopup = LoadMenu (hInstance, "MenuFile") ;
     hBitmapFile = StretchBitmap (LoadBitmap (hInstance, "BitmapFile")) ;
     AppendMenu (hMenu, MF_BITMAP | MF_POPUP, hMenuPopup,
                 (LPSTR) (LONG) hBitmapFile);

     hMenuPopup = LoadMenu (hInstance, "MenuEdit") ;
     hBitmapEdit = StretchBitmap (LoadBitmap (hInstance, "BitmapEdit")) ;
     AppendMenu (hMenu, MF_BITMAP | MF_POPUP, hMenuPopup,
                 (LPSTR) (LONG) hBitmapEdit);

     hMenuPopup = CreateMenu () ;

     for (i = 0 ; i < 3 ; i++)
          {
          hBitmapPopFont [i] = GetBitmapFont (i) ;
          AppendMenu (hMenuPopup, MF_BITMAP, IDM_COUR + i,
                      (LPSTR) (LONG) hBitmapPopFont [i]) ;
          }

     hBitmapFont = StretchBitmap (LoadBitmap (hInstance, "BitmapFont")) ;
     AppendMenu (hMenu, MF_BITMAP | MF_POPUP, hMenuPopup,
                 (LPSTR) (LONG) hBitmapFont);

     hwnd = CreateWindow (szAppName, "Bitmap Menu Demonstration",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, hMenu, hInstance, NULL) ;

     hMenu = GetSystemMenu (hwnd, FALSE);
     hBitmapHelp = StretchBitmap (LoadBitmap (hInstance, "BitmapHelp")) ;
     AppendMenu (hMenu, MF_SEPARATOR, NULL,     NULL) ;
     AppendMenu (hMenu, MF_BITMAP,    IDM_HELP, (LPSTR) (LONG) hBitmapHelp) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

     DeleteObject (hBitmapHelp) ;
     DeleteObject (hBitmapEdit) ;
     DeleteObject (hBitmapFile) ;
     DeleteObject (hBitmapFont) ;

     for (i = 0 ; i < 3 ; i++)
          DeleteObject (hBitmapPopFont [i]) ;

     return msg.wParam ;
     }

HBITMAP StretchBitmap (HBITMAP hBitmap1)
     {
     BITMAP     bm1, bm2 ;
     HBITMAP    hBitmap2 ;
     HDC        hdc, hdcMem1, hdcMem2 ;
     TEXTMETRIC tm ;

     hdc = CreateIC ("DISPLAY", NULL, NULL, NULL) ;
     GetTextMetrics (hdc, &tm) ;
     hdcMem1 = CreateCompatibleDC (hdc) ;
     hdcMem2 = CreateCompatibleDC (hdc) ;
     DeleteDC (hdc) ;

     GetObject (hBitmap1, sizeof (BITMAP), (LPSTR) &bm1) ;

     bm2 = bm1 ;
     bm2.bmWidth      = (tm.tmAveCharWidth * bm2.bmWidth)  / 4 ;
     bm2.bmHeight     = (tm.tmHeight       * bm2.bmHeight) / 8 ;
     bm2.bmWidthBytes = ((bm2.bmWidth + 15) / 16) * 2 ;

     hBitmap2 = CreateBitmapIndirect (&bm2) ;

     SelectObject (hdcMem1, hBitmap1) ;
     SelectObject (hdcMem2, hBitmap2) ;

     StretchBlt (hdcMem2, 0, 0, bm2.bmWidth, bm2.bmHeight,
                 hdcMem1, 0, 0, bm1.bmWidth, bm1.bmHeight, SRCCOPY) ;

     DeleteDC (hdcMem1) ;
     DeleteDC (hdcMem2) ;
     DeleteObject (hBitmap1) ;

     return hBitmap2 ;
     }

HBITMAP GetBitmapFont (int i)
     {
     static  struct
          {
          BYTE lfPitchAndFamily ;
          BYTE lfFaceName [LF_FACESIZE] ;
          char *szMenuText ;
          }
          lfSet [3] =
          {
          FIXED_PITCH    | FF_MODERN, "Courier",   "Courier",
          VARIABLE_PITCH | FF_SWISS,  "Helvetica", "Helvetica",
          VARIABLE_PITCH | FF_ROMAN,  "Tms Rmn",   "Times Roman"
          } ;
     DWORD   dwSize ;
     HBITMAP hBitmap ;
     HDC     hdc, hdcMem ;
     HFONT   hFont ;
     LOGFONT lf ;

     hFont = GetStockObject (SYSTEM_FONT) ;
     GetObject (hFont, sizeof (LOGFONT), (LPSTR) &lf) ;

     lf.lfHeight *= 2 ;
     lf.lfWidth  *= 2 ;
     lf.lfPitchAndFamily = lfSet[i].lfPitchAndFamily ;
     strcpy (lf.lfFaceName, lfSet[i].lfFaceName) ;

     hdc = CreateIC ("DISPLAY", NULL, NULL, NULL) ;
     hdcMem = CreateCompatibleDC (hdc) ;
     SelectObject (hdcMem, CreateFontIndirect (&lf)) ;
     dwSize = GetTextExtent (hdcMem, lfSet[i].szMenuText,
                             strlen (lfSet[i].szMenuText)) ;

     hBitmap = CreateBitmap (LOWORD (dwSize)-1, HIWORD (dwSize), 1, 1, NULL)
     SelectObject (hdcMem, hBitmap) ;


     TextOut (hdcMem, 0, 0, lfSet[i].szMenuText,
                            strlen (lfSet[i].szMenuText)) ;

     DeleteObject (SelectObject (hdcMem, hFont)) ;
     DeleteDC (hdcMem) ;
     DeleteDC (hdc) ;

     return hBitmap ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     HMENU  hMenu ;
     static short nCurrentFont = IDM_COUR ;

     switch (message)
          {
          case WM_CREATE:
               CheckMenuItem (GetMenu (hwnd), nCurrentFont, MF_CHECKED) ;
               return 0 ;

          case WM_SYSCOMMAND:
               switch (wParam)
                    {
                    case IDM_HELP:
                         MessageBox (hwnd, "Help not yet implemented.",
                                   szAppName, MB_OK | MB_ICONEXCLAMATION) ;
                         return 0 ;
                    }
               break ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDM_NEW:
                    case IDM_OPEN:
                    case IDM_SAVE:
                    case IDM_SAVEAS:
                    case IDM_UNDO:
                    case IDM_CUT:
                    case IDM_COPY:
                    case IDM_PASTE:
                    case IDM_CLEAR:
                         MessageBeep (0) ;
                         return 0 ;

                    case IDM_COUR:
                    case IDM_HELV:
                    case IDM_TMSRMN:
                         hMenu = GetMenu (hwnd) ;
                         CheckMenuItem (hMenu, nCurrentFont, MF_UNCHECKED) ;
                         nCurrentFont = wParam ;
                         CheckMenuItem (hMenu, nCurrentFont, MF_CHECKED) ;
                         return 0 ;
                    }
               break ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


HEAD.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP06\HEAD.C

/*---------------------------------------------
   HEAD.C -- Displays beginning (head) of file
             (c) Charles Petzold, 1990
  ---------------------------------------------*/

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

#define  MAXPATH     100
#define  MAXREAD    2048

long FAR PASCAL WndProc  (HWND, WORD, WORD, LONG) ;
long FAR PASCAL ListProc (HWND, WORD, WORD, LONG) ;

char    sReadBuffer [MAXREAD] ;
FARPROC lpfnOldList ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName [] = "Head" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = COLOR_WINDOW + 1 ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "File Head",
                          WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL     bValidFile ;
     static char     szFile [16] ;
     static HWND     hwndList, hwndText ;
     static OFSTRUCT ofs ;
     static RECT     rect ;
     char            szBuffer [MAXPATH + 1] ;
     HDC             hdc ;
     int             iHandle, i, iCount ;
     PAINTSTRUCT     ps ;
     TEXTMETRIC      tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
               GetTextMetrics (hdc, &tm) ;
               ReleaseDC (hwnd, hdc) ;

               rect.left = 20 * tm.tmAveCharWidth ;
               rect.top  =  3 * tm.tmHeight ;

               hwndList = CreateWindow ("listbox", NULL,
                              WS_CHILDWINDOW | WS_VISIBLE | LBS_STANDARD,
                              tm.tmAveCharWidth, tm.tmHeight * 3,
                              tm.tmAveCharWidth * 13 +
                                   GetSystemMetrics (SM_CXVSCROLL),
                              tm.tmHeight * 10,
                              hwnd, 1,
                              GetWindowWord (hwnd, GWW_HINSTANCE), NULL) ;

               hwndText = CreateWindow ("static", getcwd (szBuffer, MAXPATH),
                              WS_CHILDWINDOW | WS_VISIBLE | SS_LEFT,
                              tm.tmAveCharWidth,           tm.tmHeight,
                              tm.tmAveCharWidth * MAXPATH, tm.tmHeight,
                              hwnd, 2,
                              GetWindowWord (hwnd, GWW_HINSTANCE), NULL) ;

               lpfnOldList = (FARPROC) GetWindowLong (hwndList, GWL_WNDPROC)

               SetWindowLong (hwndList, GWL_WNDPROC,
                         (LONG) MakeProcInstance ((FARPROC) ListProc,
                                   GetWindowWord (hwnd, GWW_HINSTANCE))) ;

               SendMessage (hwndList, LB_DIR, 0x37, (LONG) (LPSTR) "*.*") ;
               return 0 ;

          case WM_SIZE:
               rect.right  = LOWORD (lParam) ;
               rect.bottom = HIWORD (lParam) ;
               return 0 ;

          case WM_SETFOCUS:
               SetFocus (hwndList) ;
               return 0 ;

          case WM_COMMAND:
               if (wParam == 1 && HIWORD (lParam) == LBN_DBLCLK)
                    {
                    if (LB_ERR == (i = (WORD) SendMessage (hwndList,
                                                  LB_GETCURSEL, 0, 0L)))
                         break ;

                    SendMessage (hwndList, LB_GETTEXT, i,
                                        (LONG) (char far *) szBuffer) ;

                    if (-1 != OpenFile (szBuffer, &ofs, OF_EXIST | OF_READ))
                         {
                         bValidFile = TRUE ;
                         strcpy (szFile, szBuffer) ;
                         getcwd (szBuffer, MAXPATH) ;
                         if (szBuffer [strlen (szBuffer) - 1] != '\\')
                              strcat (szBuffer, "\\") ;
                         SetWindowText (hwndText, strcat (szBuffer, szFile))
                         }
                    else
                         {
                         bValidFile = FALSE ;
                         szBuffer [strlen (szBuffer) - 1] = '\0' ;
                         chdir (szBuffer + 1) ;
                         getcwd (szBuffer, MAXPATH) ;
                         SetWindowText (hwndText, szBuffer) ;
                         SendMessage (hwndList, LB_RESETCONTENT, 0, 0L) ;
                         SendMessage (hwndList, LB_DIR, 0x37,
                                      (LONG) (LPSTR) "*.*") ;
                         }
                    InvalidateRect (hwnd, NULL, TRUE) ;
                    }
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
               SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT)) ;
               SetBkColor   (hdc, GetSysColor (COLOR_WINDOW)) ;

               if (bValidFile && -1 != (iHandle =
                         OpenFile (szFile, &ofs, OF_REOPEN | OF_READ)))
                    {
                    i = read (iHandle, sReadBuffer, MAXREAD) ;
                    close (iHandle) ;
                    DrawText (hdc, sReadBuffer, i, &rect, DT_WORDBREAK |
                                   DT_EXPANDTABS | DT_NOCLIP | DT_NOPREFIX) ;
                    }
               else
                    bValidFile = FALSE ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }

long FAR PASCAL ListProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     if (message == WM_KEYDOWN && wParam == VK_RETURN)

          SendMessage (GetParent (hwnd), WM_COMMAND, 1,
                         MAKELONG (hwnd, LBN_DBLCLK)) ;

     return CallWindowProc (lpfnOldList, hwnd, message, wParam, lParam) ;
     }


HELLOWIN.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP01\HELLOWIN.C

/*--------------------------------------------------------
   HELLOWIN.C -- Displays "Hello, Windows" in client area
                 (c) Charles Petzold, 1990
  --------------------------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdParam, int nCmdShow)
     {
     static char szAppName[] = "HelloWin" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
    }

     hwnd = CreateWindow (szAppName,         // window class name
        "The Hello Program",     // window caption
                    WS_OVERLAPPEDWINDOW,     // window style
                    CW_USEDEFAULT,           // initial x position
                    CW_USEDEFAULT,           // initial y position
                    CW_USEDEFAULT,           // initial x size
                    CW_USEDEFAULT,           // initial y size
                    NULL,                    // parent window handle
                    NULL,                    // window menu handle
                    hInstance,               // program instance handle
        NULL) ;         // creation parameters

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     HDC         hdc ;
     PAINTSTRUCT ps ;
     RECT   rect ;

     switch (message)
          {
          case WM_PAINT:
         hdc = BeginPaint (hwnd, &ps) ;

               GetClientRect (hwnd, &rect) ;

         DrawText (hdc, "Hello, Windows!", -1, &rect,
       DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

         EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }

     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


HEXCALC.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP10\HEXCALC.C

/*----------------------------------------
   HEXCALC.C -- Hexadecimal Calculator
                (c) Charles Petzold, 1990
  ----------------------------------------*/

#include <windows.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName [] = "HexCalc" ;
     HWND        hwnd ;
     MSG         msg;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style          = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc    = WndProc ;
          wndclass.cbClsExtra     = 0 ;
          wndclass.cbWndExtra     = DLGWINDOWEXTRA ;
          wndclass.hInstance      = hInstance ;
          wndclass.hIcon          = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground  = COLOR_WINDOW + 1 ;
          wndclass.lpszMenuName   = NULL ;
          wndclass.lpszClassName  = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateDialog (hInstance, szAppName, 0, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;

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

void ShowNumber (HWND hwnd, DWORD dwNumber)
     {
     char szBuffer [20] ;

     SetDlgItemText (hwnd, VK_ESCAPE, strupr (ltoa (dwNumber, szBuffer, 16)))
     }

DWORD CalcIt (DWORD dwFirstNum, short nOperation, DWORD dwNum)
     {
     switch (nOperation)
          {
          case '=' : return dwNum ;
          case '+' : return dwFirstNum +  dwNum ;
          case '-' : return dwFirstNum -  dwNum ;
          case '*' : return dwFirstNum *  dwNum ;
          case '&' : return dwFirstNum &  dwNum ;
          case '|' : return dwFirstNum |  dwNum ;
          case '^' : return dwFirstNum ^  dwNum ;
          case '<' : return dwFirstNum << dwNum ;
          case '>' : return dwFirstNum >> dwNum ;
          case '/' : return dwNum ? dwFirstNum / dwNum : ULONG_MAX ;
          case '%' : return dwNum ? dwFirstNum % dwNum : ULONG_MAX ;
          default  : return 0L ;
          }
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL  bNewNumber = TRUE ;
     static DWORD dwNumber, dwFirstNum ;
     static short nOperation = '=' ;
     HWND         hButton ;

     switch (message)
          {
          case WM_KEYDOWN:                   // left arrow --> backspace
               if (wParam != VK_LEFT)
                    break ;
               wParam = VK_BACK ;
                                             // fall through
          case WM_CHAR:
               if ((wParam = toupper (wParam)) == VK_RETURN)
                    wParam = '=' ;

               if (hButton = GetDlgItem (hwnd, wParam))
                    {
                    SendMessage (hButton, BM_SETSTATE, 1, 0L) ;
                    SendMessage (hButton, BM_SETSTATE, 0, 0L) ;
                    }
               else
                    {
                    MessageBeep (0) ;
                    break ;
                    }
                                             // fall through
          case WM_COMMAND:
               SetFocus (hwnd) ;

               if (wParam == VK_BACK)                  // backspace
                    ShowNumber (hwnd, dwNumber /= 16) ;

               else if (wParam == VK_ESCAPE)           // escape
                    ShowNumber (hwnd, dwNumber = 0L) ;

               else if (isxdigit (wParam))             // hex digit
                    {
                    if (bNewNumber)
                         {
                         dwFirstNum = dwNumber ;
                         dwNumber = 0L ;
                         }
                    bNewNumber = FALSE ;

                    if (dwNumber <= ULONG_MAX >> 4)
                         ShowNumber (hwnd, dwNumber = 16 * dwNumber + wParam
                              (isdigit (wParam) ? '0' : 'A' - 10)) ;
                    else
                         MessageBeep (0) ;
                    }
               else                                    // operation
                    {
                    if (!bNewNumber)
                         ShowNumber (hwnd, dwNumber =
                              CalcIt (dwFirstNum, nOperation, dwNumber)) ;
                    bNewNumber = TRUE ;
                    nOperation = wParam ;
                    }
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


JUSTIFY.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP14\JUSTIFY.C

/*----------------------------------------
   JUSTIFY.C -- Justified Type Program
                (c) Charles Petzold, 1990
  ----------------------------------------*/

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

typedef struct
     {
     short nNumFaces ;
     char  szFaceNames [MAX_FACES] [LF_FACESIZE] ;
     }
     ENUMFACE ;

typedef struct
     {
     short      nNumSizes ;
     short      xLogPixPerInch ;
     short      yLogPixPerInch ;
     LOGFONT    lf [MAX_SIZES] ;
     TEXTMETRIC tm [MAX_SIZES] ;
     }
     ENUMSIZE ;

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
int  FAR PASCAL EnumAllFaces (LPLOGFONT, LPTEXTMETRIC, short, ENUMFACE FAR *)
int  FAR PASCAL EnumAllSizes (LPLOGFONT, LPTEXTMETRIC, short, ENUMSIZE FAR *)

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static   char szAppName[] = "Justify" ;
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }
     hwnd = CreateWindow (szAppName, "Justified Type",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

int FAR PASCAL EnumAllFaces (LPLOGFONT lplf, LPTEXTMETRIC lptm,
                             short nFontType, ENUMFACE FAR *lpef)
     {
     if (nFontType & RASTER_FONTTYPE)
          {
          lstrcpy (lpef->szFaceNames[lpef->nNumFaces], lplf->lfFaceName) ;
          if (++lpef->nNumFaces == MAX_FACES)
               return 0 ;
          }
     return 1 ;
     }

int FAR PASCAL EnumAllSizes (LPLOGFONT lplf, LPTEXTMETRIC lptm,
                             short nFontType, ENUMSIZE FAR *lpes)
     {
     if (lpes->xLogPixPerInch == lptm->tmDigitizedAspectX &&
         lpes->yLogPixPerInch == lptm->tmDigitizedAspectY)
          {
          lpes->lf [lpes->nNumSizes] = *lplf ;
          lpes->tm [lpes->nNumSizes] = *lptm ;
          if (++lpes->nNumSizes == MAX_SIZES)
               return 0 ;
          }
     return 1 ;
     }

short MakeSizeMenu (HWND hwnd, FARPROC lpfnEnumAllSizes,
                    ENUMSIZE *pes, char *szFaceName)
     {
     static LOGFONT lfBlank ;
     char           szBuffer[20] ;
     HDC            hdc ;
     HMENU          hPopup ;
     short          i ;

     hdc = GetDC (hwnd) ;
     hPopup = GetSubMenu (GetMenu (hwnd), SIZE_MENU) ;

     pes->nNumSizes = 0 ;
     EnumFonts (hdc, szFaceName, lpfnEnumAllSizes, (LPSTR) pes) ;
     ReleaseDC (hwnd, hdc) ;

     while (GetMenuItemCount (hPopup) > 0)
          DeleteMenu (hPopup, 0, MF_BYPOSITION) ;

     if (pes->nNumSizes)
          for (i = 0 ; i < pes->nNumSizes ; i++)
               {
               wsprintf (szBuffer, "%i  %2d / %2d", i + 1,
                    (pes->tm[i].tmHeight - pes->tm[i].tmInternalLeading + 10)
                                                                        / 20,
                    (pes->tm[i].tmHeight + 10) / 20) ;
               AppendMenu (hPopup, 0, IDM_ISIZE + i, szBuffer) ;
               }
     else           /* no fonts found that match aspect ratio of display */
          {
          pes->lf[0] = lfBlank ;
          strcpy (pes->lf[0].lfFaceName, szFaceName) ;
          AppendMenu (hPopup, 0, IDM_ISIZE, "Default") ;
          }

     CheckMenuItem (hPopup, IDM_ISIZE, MF_CHECKED) ;
     return 0 ;
     }

void DrawRuler (HDC hdc, POINT ptClient)
     {
     static short nRuleSize [16] = { 360, 72, 144, 72, 216, 72, 144, 72,
                                     288, 72, 144, 72, 216, 72, 144, 72 } ;
     short        i, j ;

     MoveTo (hdc, 0,          -360) ;
     LineTo (hdc, ptClient.x, -360) ;
     MoveTo (hdc, -360,          0) ;
     LineTo (hdc, -360, ptClient.y) ;

     for (i = 0, j = 0 ; i <= ptClient.x ; i += 1440 / 16, j++)
          {
          MoveTo (hdc, i, -360) ;
          LineTo (hdc, i, -360 - nRuleSize [j % 16]) ;
          }
     for (i = 0, j = 0 ; i <= ptClient.y ; i += 1440 / 16, j++)
          {
          MoveTo (hdc, -360, i) ;
          LineTo (hdc, -360 - nRuleSize [j % 16], i) ;
          }
     }

void Justify (HDC hdc, HANDLE hResource, POINT ptClient, short nCurAlign)
     {
     DWORD  dwExtent ;
     LPSTR  lpText, lpBegin, lpEnd ;
     short  i, xStart, yStart, nBreakCount ;

     lpText = LockResource (hResource) ;

     yStart = 0 ;
     do                            // for each text line
          {
          nBreakCount = 0 ;
          while (*lpText == ' ')   // skip over leading blanks
               lpText++ ;
          lpBegin = lpText ;

          do                       // until the line is known
               {
               lpEnd = lpText ;

               while (*lpText != '\0' && *lpText++ != ' ') ;
               if (*lpText == '\0')
                    break ;
                                   // for each space, calculate extents
               nBreakCount++ ;
               SetTextJustification (hdc, 0, 0) ;
               dwExtent = GetTextExtent (hdc, lpBegin, lpText - lpBegin - 1)
               }
          while (LOWORD (dwExtent) < ptClient.x) ;

          nBreakCount-- ;
          while (*(lpEnd - 1) == ' ')   // eliminate trailing blanks
               {
               lpEnd-- ;
               nBreakCount-- ;
               }

          if (*lpText == '\0' || nBreakCount <= 0)
               lpEnd = lpText ;

          SetTextJustification (hdc, 0, 0) ;
          dwExtent = GetTextExtent (hdc, lpBegin, lpEnd - lpBegin) ;

          if (nCurAlign == IDM_LEFT)         // use alignment for xStart
               xStart = 0 ;

          else if (nCurAlign == IDM_RIGHT)
               xStart = ptClient.x - LOWORD (dwExtent) ;

          else if (nCurAlign == IDM_CENTER)
               xStart = (ptClient.x - LOWORD (dwExtent)) / 2 ;

          else
               {
               if (*lpText != '\0' && nBreakCount > 0)
                    SetTextJustification (hdc, ptClient.x - LOWORD (dwExtent)
                                                  nBreakCount) ;
               xStart = 0 ;
               }

          TextOut (hdc, xStart, yStart, lpBegin, lpEnd - lpBegin) ;
          yStart += HIWORD (dwExtent) ;
          lpText = lpEnd ;
          }
     while (*lpText && yStart < ptClient.y) ;

     GlobalUnlock (hResource) ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static ENUMFACE ef ;
     static ENUMSIZE es ;
     static FARPROC  lpfnEnumAllFaces, lpfnEnumAllSizes ;
     static HANDLE   hResource ;
     static POINT    ptClient ;
     static short    nCurSize, nCurFace, nCurAttr, nCurAlign = IDM_LEFT ;
     HANDLE          hInstance ;
     HDC             hdc ;
     HFONT           hFont ;
     HMENU           hMenu, hPopup ;
     PAINTSTRUCT     ps ;
     short           i ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;
               es.xLogPixPerInch = GetDeviceCaps (hdc, LOGPIXELSX) ;
               es.yLogPixPerInch = GetDeviceCaps (hdc, LOGPIXELSY) ;

                              // Set Map Mode

               SetMapMode (hdc, MM_ANISOTROPIC) ;
               SetWindowExt (hdc, 1440, 1440) ;
               SetViewportExt (hdc, es.xLogPixPerInch, es.yLogPixPerInch) ;
               SetWindowOrg (hdc, -720, -720) ;

                              // MakeProcInstance for 2 routines

               hInstance = ((LPCREATESTRUCT) lParam)-> hInstance ;
               lpfnEnumAllFaces = MakeProcInstance (EnumAllFaces, hInstance)
               lpfnEnumAllSizes = MakeProcInstance (EnumAllSizes, hInstance)

                              // Enumerate the Font Faces

               EnumFonts (hdc, NULL, lpfnEnumAllFaces, (LPSTR) &ef) ;
               ReleaseDC (hwnd, hdc) ;

                              // Initialize the Menus

               hMenu  = GetMenu (hwnd) ;
               hPopup = CreateMenu () ;

               for (i = 0 ; i < ef.nNumFaces ; i++)
                    AppendMenu (hPopup, 0, IDM_IFACE + i, ef.szFaceNames[i])

               ModifyMenu (hMenu, IDM_FACE, MF_POPUP, hPopup, "&FaceName") ;
               CheckMenuItem (hMenu, IDM_IFACE, MF_CHECKED) ;

               nCurSize = MakeSizeMenu (hwnd, lpfnEnumAllSizes, &es,
                                   ef.szFaceNames [nCurFace]) ;

                              // Load the Text Resource

               hResource = LoadResource (hInstance,
                           FindResource (hInstance, "Ismael", "TEXT")) ;
               return 0 ;

          case WM_SIZE:
               hdc = GetDC (hwnd) ;
               ptClient = MAKEPOINT (lParam) ;
               DPtoLP (hdc, &ptClient, 1) ;
               ptClient.x -= 360 ;
               ReleaseDC (hwnd, hdc) ;
               return 0 ;

          case WM_COMMAND:
               hMenu = GetMenu (hwnd) ;

               if (wParam >= IDM_IFACE && wParam < IDM_IFACE + MAX_FACES)
                    {
                    CheckMenuItem (hMenu, nCurFace + IDM_IFACE, MF_UNCHECKED)
                    CheckMenuItem (hMenu, wParam, MF_CHECKED) ;
                    nCurFace = wParam - IDM_IFACE ;

                    nCurSize = MakeSizeMenu (hwnd, lpfnEnumAllSizes, &es,
                                        ef.szFaceNames [nCurFace]) ;
                    }

               else if (wParam >= IDM_ISIZE && wParam < IDM_ISIZE + MAX_SIZES
                    {
                    CheckMenuItem (hMenu, nCurSize + IDM_ISIZE, MF_UNCHECKED)
                    CheckMenuItem (hMenu, wParam, MF_CHECKED) ;
                    nCurSize = wParam - IDM_ISIZE ;
                    }

               else switch (wParam)
                    {
                    case IDM_BOLD:
                    case IDM_ITALIC:
                    case IDM_STRIKE:
                    case IDM_UNDER:
                         CheckMenuItem (hMenu, wParam, MF_CHECKED &
                              GetMenuState (hMenu, wParam, MF_BYCOMMAND) ?
                                   MF_UNCHECKED : MF_CHECKED) ;
                         nCurAttr ^= wParam ;
                         break ;

                    case IDM_NORM:
                         nCurAttr = 0 ;
                         CheckMenuItem (hMenu, IDM_BOLD,   MF_UNCHECKED) ;
                         CheckMenuItem (hMenu, IDM_ITALIC, MF_UNCHECKED) ;
                         CheckMenuItem (hMenu, IDM_STRIKE, MF_UNCHECKED) ;
                         CheckMenuItem (hMenu, IDM_UNDER,  MF_UNCHECKED) ;
                         break ;

                    case IDM_LEFT:
                    case IDM_RIGHT:
                    case IDM_CENTER:
                    case IDM_JUST:
                         CheckMenuItem (hMenu, nCurAlign, MF_UNCHECKED) ;
                         nCurAlign = wParam ;
                         CheckMenuItem (hMenu, nCurAlign, MF_CHECKED) ;
                         break ;
                    }
               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               es.lf[nCurSize].lfWeight    = nCurAttr & IDM_BOLD ? 700 : 400
               es.lf[nCurSize].lfItalic    = (BYTE) (nCurAttr & IDM_ITALIC) ;
               es.lf[nCurSize].lfUnderline = (BYTE) (nCurAttr & IDM_UNDER) ;
               es.lf[nCurSize].lfStrikeOut = (BYTE) (nCurAttr & IDM_STRIKE) ;

               hFont = CreateFontIndirect (&es.lf[nCurSize]) ;
               hFont = SelectObject (hdc, hFont) ;

               DrawRuler (hdc, ptClient) ;
               Justify (hdc, hResource, ptClient, nCurAlign) ;

               DeleteObject (SelectObject (hdc, hFont)) ;
               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               FreeResource (hResource) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


KEYLOOK.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP03\KEYLOOK.C

/*-------------------------------------------------------
   KEYLOOK.C -- Displays Keyboard and Character Messages
                (c) Charles Petzold, 1990
  -------------------------------------------------------*/

#include <windows.h>
#include <stdio.h>

long  FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

RECT  rect ;
short cxChar, cyChar ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "KeyLook" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Keyboard Message Looker",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

void ShowKey (HWND hwnd, int iType, char *szMessage, WORD wParam, LONG lParam
     {
     static char *szFormat[2] = { "%-14s %3d    %c %6u %4d %3s %3s %4s %4s",
                                  "%-14s    %3d %c %6u %4d %3s %3s %4s %4s" }
     char        szBuffer[80] ;
     HDC         hdc ;

     ScrollWindow (hwnd, 0, -cyChar, &rect, &rect) ;
     hdc = GetDC (hwnd) ;

     SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

     TextOut (hdc, cxChar, rect.bottom - cyChar, szBuffer,
              wsprintf (szBuffer, szFormat [iType],
                        (LPSTR) szMessage, wParam,
                        (BYTE) (iType ? wParam : ' '),
                        LOWORD (lParam),
                        HIWORD (lParam) & 0xFF,
                        (LPSTR) (0x01000000 & lParam ? "Yes"  : "No"),
                        (LPSTR) (0x20000000 & lParam ? "Yes"  : "No"),
                        (LPSTR) (0x40000000 & lParam ? "Down" : "Up"),
                        (LPSTR) (0x80000000 & lParam ? "Up"   : "Down"))) ;

     ReleaseDC (hwnd, hdc) ;
     ValidateRect (hwnd, NULL) ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static char szTop[] =
                    "Message        Key Char Repeat Scan Ext ALT Prev Tran";
     static char szUnd[]=
                    "_______        ___ ____ ______ ____ ___ ___ ____ ____";
     HDC         hdc ;
     PAINTSTRUCT ps ;
     TEXTMETRIC  tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;

               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight ;

               ReleaseDC (hwnd, hdc) ;

               rect.top = 3 * cyChar / 2 ;
               return 0 ;

          case WM_SIZE:
               rect.right  = LOWORD (lParam) ;
               rect.bottom = HIWORD (lParam) ;
               UpdateWindow (hwnd) ;
               return 0 ;

          case WM_PAINT:
               InvalidateRect (hwnd, NULL, TRUE) ;
               hdc = BeginPaint (hwnd, &ps) ;

               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

               SetBkMode (hdc, TRANSPARENT) ;
               TextOut (hdc, cxChar, cyChar / 2, szTop, (sizeof szTop) - 1) ;
               TextOut (hdc, cxChar, cyChar / 2, szUnd, (sizeof szUnd) - 1) ;
               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_KEYDOWN:
               ShowKey (hwnd, 0, "WM_KEYDOWN", wParam, lParam) ;
               return 0 ;

          case WM_KEYUP:
               ShowKey (hwnd, 0, "WM_KEYUP", wParam, lParam) ;
               return 0 ;

          case WM_CHAR:
               ShowKey (hwnd, 1, "WM_CHAR", wParam, lParam) ;
               return 0 ;

          case WM_DEADCHAR:
               ShowKey (hwnd, 1, "WM_DEADCHAR", wParam, lParam) ;
               return 0 ;

          case WM_SYSKEYDOWN:
               ShowKey (hwnd, 0, "WM_SYSKEYDOWN", wParam, lParam) ;
               break ;        // ie, call DefWindowProc

          case WM_SYSKEYUP:
               ShowKey (hwnd, 0, "WM_SYSKEYUP", wParam, lParam) ;
               break ;        // ie, call DefWindowProc

          case WM_SYSCHAR:
               ShowKey (hwnd, 1, "WM_SYSCHAR", wParam, lParam) ;
               break ;        // ie, call DefWindowProc

          case WM_SYSDEADCHAR:
               ShowKey (hwnd, 1, "WM_SYSDEADCHAR", wParam, lParam) ;
               break ;        // ie, call DefWindowProc

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


LINEDDA.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP12\LINEDDA.C

/*----------------------------------------
   LINEDDA.C -- LineDDA Demonstration
                (c) Charles Petzold, 1990
  ----------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
void FAR PASCAL LineProc (short, short, LPSTR) ;

HANDLE hInst ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "LineDDA" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hInst = hInstance ;

     hwnd = CreateWindow (szAppName, "LineDDA Demonstration",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static FARPROC lpfnLineProc ;
     static short   cxClient, cyClient, xL, xR, yT, yB ;
     HDC            hdc ;
     PAINTSTRUCT    ps ;

     switch (message)
          {
          case WM_CREATE:
               lpfnLineProc = MakeProcInstance (LineProc, hInst) ;
               return 0 ;

          case WM_SIZE:
               xR = 3 * (xL = (cxClient = LOWORD (lParam)) / 4) ;
               yB = 3 * (yT = (cyClient = HIWORD (lParam)) / 4) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               LineDDA (xL, yT, xR, yT, lpfnLineProc, (LPSTR) &hdc) ;
               LineDDA (xR, yT, xR, yB, lpfnLineProc, (LPSTR) &hdc) ;
               LineDDA (xR, yB, xL, yB, lpfnLineProc, (LPSTR) &hdc) ;
               LineDDA (xL, yB, xL, yT, lpfnLineProc, (LPSTR) &hdc) ;

               LineDDA (0,       0,       xL, yT, lpfnLineProc, (LPSTR) &hdc)
               LineDDA (cxClient, 0,       xR, yT, lpfnLineProc, (LPSTR) &hdc
               LineDDA (cxClient, cyClient, xR, yB, lpfnLineProc, (LPSTR) &hd
               LineDDA (0,       cyClient, xL, yB, lpfnLineProc, (LPSTR) &hdc

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }

void FAR PASCAL LineProc (short x, short y, LPSTR lpData)
     {
     static short nCounter = 0 ;

     if (nCounter == 2)
          Ellipse (* (HDC far *) lpData, x - 2, y - 2, x + 3, y + 3) ;

     nCounter = (nCounter + 1) % 4 ;
     }


MDIDEMO.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP18\MDIDEMO.C

/*--------------------------------------------------------
   MDIDEMO.C -- Multiple Document Interface Demonstration
                (c) Charles Petzold, 1990
  --------------------------------------------------------*/

#include <windows.h>
#include <stdlib.h>
#include "mdidemo.h"

long FAR PASCAL FrameWndProc  (HWND, WORD, WORD, LONG) ;
BOOL FAR PASCAL CloseEnumProc (HWND, LONG) ;
long FAR PASCAL HelloWndProc  (HWND, WORD, WORD, LONG) ;
long FAR PASCAL RectWndProc   (HWND, WORD, WORD, LONG) ;

          // structure for storing data unique to each Hello child window

typedef struct
     {
     short    nColor ;
     COLORREF clrText ;
     }
     HELLODATA ;

typedef HELLODATA NEAR *NPHELLODATA ;

          // structure for storing data unique to each Rect child window

typedef struct
     {
     short cxClient ;
     short cyClient ;
     }
     RECTDATA ;

typedef RECTDATA NEAR *NPRECTDATA ;

          // global variables

char   szFrameClass [] = "MdiFrame" ;
char   szHelloClass [] = "MdiHelloChild" ;
char   szRectClass  [] = "MdiRectChild" ;
HANDLE hInst ;
HMENU  hMenuInit, hMenuHello, hMenuRect ;
HMENU  hMenuInitWindow, hMenuHelloWindow, hMenuRectWindow ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HANDLE   hAccel ;
     HWND     hwndFrame, hwndClient ;
     MSG      msg ;
     WNDCLASS wndclass ;

     hInst = hInstance ;

     if (!hPrevInstance)
          {
                    // Register the frame window class

          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = FrameWndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = COLOR_APPWORKSPACE + 1 ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szFrameClass ;

          RegisterClass (&wndclass) ;

                    // Register the Hello child window class

          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = HelloWndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = sizeof (LOCALHANDLE) ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szHelloClass ;

          RegisterClass (&wndclass) ;

                    // Register the Rect child window class

          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = RectWndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = sizeof (LOCALHANDLE) ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szRectClass ;

          RegisterClass (&wndclass) ;
          }
               // Obtain handles to three possible menus & submenus

     hMenuInit  = LoadMenu (hInst, "MdiMenuInit") ;
     hMenuHello = LoadMenu (hInst, "MdiMenuHello") ;
     hMenuRect  = LoadMenu (hInst, "MdiMenuRect") ;

     hMenuInitWindow  = GetSubMenu (hMenuInit,   INIT_MENU_POS) ;
     hMenuHelloWindow = GetSubMenu (hMenuHello, HELLO_MENU_POS) ;
     hMenuRectWindow  = GetSubMenu (hMenuRect,   RECT_MENU_POS) ;

               // Load accelerator table

     hAccel = LoadAccelerators (hInst, "MdiAccel") ;

               // Create the frame window

     hwndFrame = CreateWindow (szFrameClass, "MDI Demonstration",
                               WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                               CW_USEDEFAULT, CW_USEDEFAULT,
                               CW_USEDEFAULT, CW_USEDEFAULT,
                               NULL, hMenuInit, hInstance, NULL) ;

     hwndClient = GetWindow (hwndFrame, GW_CHILD) ;

     ShowWindow (hwndFrame, nCmdShow) ;
     UpdateWindow (hwndFrame) ;

               // Enter the modified message loop

     while (GetMessage (&msg, NULL, 0, 0))
          {
          if (!TranslateMDISysAccel (hwndClient, &msg) &&
              !TranslateAccelerator (hwndFrame, hAccel, &msg))
               {
               TranslateMessage (&msg) ;
               DispatchMessage (&msg) ;
               }
          }
     return msg.wParam ;
     }

long FAR PASCAL FrameWndProc (HWND hwnd, WORD message, WORD wParam, LONG lPar
     {
     static HWND        hwndClient ;
     CLIENTCREATESTRUCT clientcreate ;
     FARPROC            lpfnEnum ;
     HWND               hwndChild, hwndNext ;
     MDICREATESTRUCT    mdicreate ;

     switch (message)
          {
          case WM_CREATE:          // Create the client window

               clientcreate.hWindowMenu  = hMenuInitWindow ;
               clientcreate.idFirstChild = IDM_FIRSTCHILD ;

               hwndClient = CreateWindow ("MDICLIENT", NULL,
                              WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,
                              0, 0, 0, 0, hwnd, 1, hInst,
                              (LPSTR) &clientcreate) ;
               return 0 ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDM_NEWHELLO:       // Create a Hello child window

                         mdicreate.szClass = szHelloClass ;
                         mdicreate.szTitle = "Hello" ;
                         mdicreate.hOwner  = hInst ;
                         mdicreate.x       = CW_USEDEFAULT ;
                         mdicreate.y       = CW_USEDEFAULT ;
                         mdicreate.cx      = CW_USEDEFAULT ;
                         mdicreate.cy      = CW_USEDEFAULT ;
                         mdicreate.style   = 0 ;
                         mdicreate.lParam  = NULL ;

                         hwndChild = SendMessage (hwndClient, WM_MDICREATE, 0
                                        (LONG) (LPMDICREATESTRUCT) &mdicreate
                         return 0 ;

                    case IDM_NEWRECT:        // Create a Rect child window

                         mdicreate.szClass = szRectClass ;
                         mdicreate.szTitle = "Rectangles" ;
                         mdicreate.hOwner  = hInst ;
                         mdicreate.x       = CW_USEDEFAULT ;
                         mdicreate.y       = CW_USEDEFAULT ;
                         mdicreate.cx      = CW_USEDEFAULT ;
                         mdicreate.cy      = CW_USEDEFAULT ;
                         mdicreate.style   = 0 ;
                         mdicreate.lParam  = NULL ;

                         hwndChild = SendMessage (hwndClient,  WM_MDICREATE,
                                        (LONG) (LPMDICREATESTRUCT) &mdicreate
                         return 0 ;

                    case IDM_CLOSE:          // Close the active window

                         hwndChild = LOWORD (SendMessage (hwndClient,
                                                  WM_MDIGETACTIVE, 0, 0L)) ;

                         if (SendMessage (hwndChild, WM_QUERYENDSESSION, 0, 0
                              SendMessage (hwndClient, WM_MDIDESTROY,
                                           hwndChild, 0L) ;
                         return 0 ;

                    case IDM_EXIT:           // Exit the program

                         SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
                         return 0 ;

                                   // Messages for arranging windows
                    case IDM_TILE:
                         SendMessage (hwndClient, WM_MDITILE, 0, 0L) ;
                         return 0 ;

                    case IDM_CASCADE:
                         SendMessage (hwndClient, WM_MDICASCADE, 0, 0L) ;
                         return 0 ;

                    case IDM_ARRANGE:
                         SendMessage (hwndClient, WM_MDIICONARRANGE, 0, 0L) ;
                         return 0 ;

                    case IDM_CLOSEALL:       // Attempt to close all children

                         lpfnEnum = MakeProcInstance (CloseEnumProc, hInst) ;
                         EnumChildWindows (hwndClient, lpfnEnum, 0L) ;
                         FreeProcInstance (lpfnEnum) ;
                         return 0 ;

                    default:            // Pass to active child

                         hwndChild = LOWORD (SendMessage (hwndClient,
                                                WM_MDIGETACTIVE, 0, 0L)) ;

                        if (IsWindow (hwndChild))
                             SendMessage (hwndChild, WM_COMMAND,
                                          wParam, lParam) ;

                        break ;        // and then to DefFrameProc
                    }
               break ;

          case WM_QUERYENDSESSION:
          case WM_CLOSE:                     // Attempt to close all children

               SendMessage (hwnd, WM_COMMAND, IDM_CLOSEALL, 0L) ;

               if (NULL != GetWindow (hwndClient, GW_CHILD))
                    return 0 ;

               break ;   // ie, call DefFrameProc ;

          case WM_DESTROY :
               PostQuitMessage (0) ;
               return 0 ;
          }
               // Pass unprocessed messages to DefFrameProc (not DefWindowPro

     return DefFrameProc (hwnd, hwndClient, message, wParam, lParam) ;
     }

BOOL FAR PASCAL CloseEnumProc (HWND hwnd, LONG lParam)
     {
     if (GetWindow (hwnd, GW_OWNER))         // check for icon title
          return 1 ;

     SendMessage (GetParent (hwnd), WM_MDIRESTORE, hwnd, 0L) ;

     if (!SendMessage (hwnd, WM_QUERYENDSESSION, 0, 0L))
          return 1 ;

     SendMessage (GetParent (hwnd), WM_MDIDESTROY, hwnd, 0L) ;
          return 1 ;
     }

long FAR PASCAL HelloWndProc (HWND hwnd, WORD message, WORD wParam, LONG lPar
     {
     static COLORREF clrTextArray [] = { RGB (0,   0, 0), RGB (255, 0,   0),
                                         RGB (0, 255, 0), RGB (  0, 0, 255),
                                         RGB (255, 255, 255) } ;
     static HWND     hwndClient, hwndFrame ;
     HDC             hdc ;
     HMENU           hMenu ;
     LOCALHANDLE     hHelloData ;
     NPHELLODATA     npHelloData ;
     PAINTSTRUCT     ps ;
     RECT            rect ;

     switch (message)
          {
          case WM_CREATE:
                         // Allocate memory for window private data

               hHelloData = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT,
                                        sizeof (HELLODATA)) ;

               npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
               npHelloData->nColor  = IDM_BLACK ;
               npHelloData->clrText = RGB (0, 0, 0) ;
               LocalUnlock (hHelloData) ;
               SetWindowWord (hwnd, 0, hHelloData) ;

                         // Save some window handles

               hwndClient = GetParent (hwnd) ;
               hwndFrame  = GetParent (hwndClient) ;
               return 0 ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDM_BLACK:
                    case IDM_RED:
                    case IDM_GREEN:
                    case IDM_BLUE:
                    case IDM_WHITE:
                                   // Change the text color

                         hHelloData  = GetWindowWord (hwnd, 0) ;
                         npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;

                         hMenu = GetMenu (hwndFrame) ;

                         CheckMenuItem (hMenu, npHelloData->nColor,
                                               MF_UNCHECKED) ;
                         npHelloData->nColor = wParam ;
                         CheckMenuItem (hMenu, npHelloData->nColor,
                                               MF_CHECKED) ;

                         npHelloData->clrText =
                               clrTextArray [wParam - IDM_BLACK] ;

                         LocalUnlock (hHelloData) ;
                         InvalidateRect (hwnd, NULL, FALSE) ;
                    }
               return 0 ;

          case WM_PAINT:
                         // Paint the window

         hdc = BeginPaint (hwnd, &ps) ;

               hHelloData  = GetWindowWord (hwnd, 0) ;
               npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
               SetTextColor (hdc, npHelloData->clrText) ;
               LocalUnlock (hHelloData) ;

               GetClientRect (hwnd, &rect) ;

               DrawText (hdc, "Hello, World!", -1, &rect,
                         DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_MDIACTIVATE:

                         // Set the Hello menu if gaining focus

               if (wParam == TRUE)
                    SendMessage (hwndClient, WM_MDISETMENU, 0,
                                 MAKELONG (hMenuHello, hMenuHelloWindow)) ;

                         // check or uncheck menu item

               hHelloData  = GetWindowWord (hwnd, 0) ;
               npHelloData = (NPHELLODATA) LocalLock (hHelloData) ;
               CheckMenuItem (hMenuHello, npHelloData->nColor,
                              wParam ? MF_CHECKED : MF_UNCHECKED) ;
               LocalUnlock (hHelloData) ;

                         // Set the Init menu if losing focus

               if (wParam == FALSE)
                    SendMessage (hwndClient, WM_MDISETMENU, 0,
                                 MAKELONG (hMenuInit, hMenuInitWindow)) ;

               DrawMenuBar (hwndFrame) ;
               return 0 ;

          case WM_QUERYENDSESSION:
          case WM_CLOSE:
               if (IDOK != MessageBox (hwnd, "OK to close window?", "Hello",
                                       MB_ICONQUESTION | MB_OKCANCEL))
                    return 0 ;

               break ;   // ie, call DefMDIChildProc

          case WM_DESTROY:
               hHelloData = GetWindowWord (hwnd, 0) ;
               LocalFree (hHelloData) ;
               return 0 ;
          }
               // Pass unprocessed message to DefMDIChildProc

     return DefMDIChildProc (hwnd, message, wParam, lParam) ;
     }

long FAR PASCAL RectWndProc (HWND hwnd, WORD message, WORD wParam, LONG lPara
     {
     static HWND hwndClient, hwndFrame ;
     HPEN        hBrush ;
     HDC         hdc ;
     LOCALHANDLE hRectData ;
     NPRECTDATA  npRectData ;
     PAINTSTRUCT ps ;
     short       xLeft, xRight, yTop, yBottom, nRed, nGreen, nBlue ;

     switch (message)
          {
          case WM_CREATE:
                         // Allocate memory for window private data

               hRectData = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT,
                                       sizeof (RECTDATA)) ;

               SetWindowWord (hwnd, 0, hRectData) ;

                         // Start the timer going

               SetTimer (hwnd, 1, 250, NULL) ;

                         // Save some window handles

               hwndClient = GetParent (hwnd) ;
               hwndFrame  = GetParent (hwndClient) ;
               return 0 ;

          case WM_SIZE:            // Save the window size

               hRectData  = GetWindowWord (hwnd, 0) ;
               npRectData = (NPRECTDATA) LocalLock (hRectData) ;

               npRectData->cxClient = LOWORD (lParam) ;
               npRectData->cyClient = HIWORD (lParam) ;

               LocalUnlock (hRectData) ;

               break ;        // WM_SIZE must be processed by DefMDIChildProc

          case WM_TIMER:           // Display a random rectangle

               hRectData  = GetWindowWord (hwnd, 0) ;
               npRectData = (NPRECTDATA) LocalLock (hRectData) ;

               xLeft   = rand () % npRectData->cxClient ;
               xRight  = rand () % npRectData->cxClient ;
               yTop    = rand () % npRectData->cyClient ;
               yBottom = rand () % npRectData->cyClient ;
               nRed    = rand () & 255 ;
               nGreen  = rand () & 255 ;
               nBlue   = rand () & 255 ;

               hdc = GetDC (hwnd) ;
               hBrush = CreateSolidBrush (RGB (nRed, nGreen, nBlue)) ;
               SelectObject (hdc, hBrush) ;

               Rectangle (hdc, min (xLeft, xRight), min (yTop, yBottom),
                               max (xLeft, xRight), max (yTop, yBottom)) ;

               ReleaseDC (hwnd, hdc) ;
               DeleteObject (hBrush) ;
               LocalUnlock (hRectData) ;
               return 0 ;

          case WM_PAINT:           // Clear the window

               InvalidateRect (hwnd, NULL, TRUE) ;
               hdc = BeginPaint (hwnd, &ps) ;
               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_MDIACTIVATE:     // Set the appropriate menu
               if (wParam == TRUE)
                    SendMessage (hwndClient, WM_MDISETMENU, 0,
                                 MAKELONG (hMenuRect, hMenuRectWindow)) ;
               else
                    SendMessage (hwndClient, WM_MDISETMENU, 0,
                                 MAKELONG (hMenuInit, hMenuInitWindow)) ;

               DrawMenuBar (hwndFrame) ;
               return 0 ;

          case WM_DESTROY:
               hRectData = GetWindowWord (hwnd, 0) ;
               LocalFree (hRectData) ;
               KillTimer (hwnd, 1) ;
               return 0 ;
          }
               // Pass unprocessed message to DefMDIChildProc

     return DefMDIChildProc (hwnd, message, wParam, lParam) ;
     }


MENUDEMO.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP09\MENUDEMO.C

/*-----------------------------------------
   MENUDEMO.C -- Menu Demonstration
                 (c) Charles Petzold, 1990
  -----------------------------------------*/

#include <windows.h>
#include "menudemo.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

char szAppName [] = "MenuDemo" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Menu Demonstration",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static int  wColorID [5] = { WHITE_BRUSH,  LTGRAY_BRUSH, GRAY_BRUSH,
                                  DKGRAY_BRUSH, BLACK_BRUSH } ;
     static WORD wSelection = IDM_WHITE ;
     HMENU       hMenu ;

     switch (message)
          {
          case WM_COMMAND:
               hMenu = GetMenu (hwnd) ;

               switch (wParam)
                    {
                    case IDM_NEW:
                    case IDM_OPEN:
                    case IDM_SAVE:
                    case IDM_SAVEAS:
                         MessageBeep (0) ;
                         return 0 ;

                    case IDM_EXIT:
                         SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
                         return 0 ;

                    case IDM_UNDO:
                    case IDM_CUT:
                    case IDM_COPY:
                    case IDM_PASTE:
                    case IDM_CLEAR:
                         MessageBeep (0) ;
                         return 0 ;

                    case IDM_WHITE:          // Note: Logic below
                    case IDM_LTGRAY:         //   assumes that IDM_WHITE
                    case IDM_GRAY:           //   through IDM_BLACK are
                    case IDM_DKGRAY:         //   consecutive numbers in
                    case IDM_BLACK:          //   the order shown here.

                         CheckMenuItem (hMenu, wSelection, MF_UNCHECKED) ;
                         wSelection = wParam ;
                         CheckMenuItem (hMenu, wSelection, MF_CHECKED) ;

                         SetClassWord (hwnd, GCW_HBRBACKGROUND,
                              GetStockObject (wColorID [wParam - IDM_WHITE]))

                         InvalidateRect (hwnd, NULL, TRUE) ;
                         return 0 ;

                    case IDM_START:
                         if (SetTimer (hwnd, 1, 1000, NULL))
                              {
                              EnableMenuItem (hMenu, IDM_START, MF_GRAYED) ;
                              EnableMenuItem (hMenu, IDM_STOP,  MF_ENABLED) ;
                              }
                         return 0 ;

                    case IDM_STOP:
                         KillTimer (hwnd, 1) ;
                         EnableMenuItem (hMenu, IDM_START, MF_ENABLED) ;
                         EnableMenuItem (hMenu, IDM_STOP,  MF_GRAYED) ;
                         return 0 ;

                    case IDM_HELP:
                         MessageBox (hwnd, "Help not yet implemented.",
                                     szAppName, MB_ICONINFORMATION | MB_OK) ;
                         return 0 ;

                    case IDM_ABOUT:
                         MessageBox (hwnd, "Menu Demonstration Program.",
                                     szAppName, MB_ICONINFORMATION | MB_OK) ;
                         return 0 ;
                    }
               break ;

          case WM_TIMER:
               MessageBeep (0) ;
               return 0 ;

          case WM_DESTROY :
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


MFCREATE.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP13\MFCREATE.C

/*-----------------------------------------
   MFCREATE.C -- Metafile Creation Program
                 (c) Charles Petzold, 1990
  -----------------------------------------*/

#include <windows.h>

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HBRUSH hBrush  = CreateSolidBrush (RGB (0, 0, 255)) ;
     HDC    hdcMeta = CreateMetaFile ("MYLOGO.WMF") ;

     Rectangle (hdcMeta, 0, 0, 100, 100) ;
     MoveTo (hdcMeta, 0, 0) ;
     LineTo (hdcMeta, 100, 100) ;
     MoveTo (hdcMeta, 0, 100) ;
     LineTo (hdcMeta, 100, 0) ;
     SelectObject (hdcMeta, hBrush) ;
     Ellipse (hdcMeta, 20, 20, 80, 80) ;

     DeleteMetaFile (CloseMetaFile (hdcMeta)) ;
     DeleteObject (hBrush) ;

     MessageBeep (0) ;

     return FALSE ;
     }


MFRESORC.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP13\MFRESORC.C

/*-----------------------------------------
   MFRESORC.C -- Metafile Resource Program
                 (c) Charles Petzold, 1990
  -----------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName [] = "MFResorc" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Metafile Resource Program",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HANDLE hmf ;
     static short  cxClient, cyClient ;
     HANDLE        hInstance, hResource ;
     HDC           hdc ;
     PAINTSTRUCT   ps ;
     short         x, y ;

     switch (message)
          {
          case WM_CREATE:
               hInstance = ((LPCREATESTRUCT) lParam) -> hInstance ;
               hResource = LoadResource (hInstance,
                           FindResource (hInstance, "MyLogo", "METAFILE")) ;

               LockResource (hResource) ;
               hmf = SetMetaFileBits (hResource) ;
               UnlockResource (hResource) ;
               return 0 ;

          case WM_SIZE:
               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               SetMapMode (hdc, MM_ANISOTROPIC) ;
               SetWindowExt (hdc, 1000, 1000) ;
               SetViewportExt (hdc, cxClient, cyClient) ;

               for (x = 0 ; x < 10 ; x++)
                    for (y = 0 ; y < 10 ; y++)
                         {
                         SetWindowOrg (hdc, -100 * x, -100 * y) ;
                         PlayMetaFile (hdc, hmf) ;
                         }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               DeleteMetaFile (hmf) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


NOPOPUPS.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP09\NOPOPUPS.C

/*-------------------------------------------------
   NOPOPUPS.C -- Demonstrates No-Popup Nested Menu
                 (c) Charles Petzold, 1990
  -------------------------------------------------*/

#include <windows.h>
#include "nopopups.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName [] = "NoPopUps" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "No-Popup Nested Menu Demonstration",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HMENU hMenuMain, hMenuEdit, hMenuFile ;
     HANDLE       hInstance ;

     switch (message)
          {
          case WM_CREATE:
               hInstance = GetWindowWord (hwnd, GWW_HINSTANCE) ;

               hMenuMain = LoadMenu (hInstance, "MenuMain") ;
               hMenuFile = LoadMenu (hInstance, "MenuFile") ;
               hMenuEdit = LoadMenu (hInstance, "MenuEdit") ;

               SetMenu (hwnd, hMenuMain) ;
               return 0 ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDM_MAIN:
                         SetMenu (hwnd, hMenuMain) ;
                         return 0 ;

                    case IDM_FILE:
                         SetMenu (hwnd, hMenuFile) ;
                         return 0 ;

                    case IDM_EDIT:
                         SetMenu (hwnd, hMenuEdit) ;
                         return 0 ;

                    case IDM_NEW:
                    case IDM_OPEN:
                    case IDM_SAVE:
                    case IDM_SAVEAS:
                    case IDM_UNDO:
                    case IDM_CUT:
                    case IDM_COPY:
                    case IDM_PASTE:
                    case IDM_CLEAR:
                         MessageBeep (0) ;
                         return 0 ;
                    }
               break ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


PICKFONT.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP14\PICKFONT.C

/*-----------------------------------------
   PICKFONT.C -- Font Picker Program
                 (c) Charles Petzold, 1990
  -----------------------------------------*/

#include <windows.h>
#include "pickfont.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
BOOL FAR PASCAL DlgProc (HWND, WORD, WORD, LONG) ;

char    szAppName [] = "PickFont" ;
DWORD   dwAspectMatch = 0L ;
HWND    hDlg ;
LOGFONT lf ;
short   nMapMode = IDD_TEXT ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Font Picker",
                          WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

     while (GetMessage (&msg, NULL, 0, 0))
          {
          if (hDlg == 0 || !IsDialogMessage (hDlg, &msg))
               {
               TranslateMessage (&msg) ;
               DispatchMessage  (&msg) ;
               }
          }
     return msg.wParam ;
     }

void MySetMapMode (HDC hdc)
     {
     if (nMapMode == IDD_LTWPS)
          {
          SetMapMode (hdc, MM_ANISOTROPIC) ;
          SetWindowExt (hdc, 1440, 1440) ;
          SetViewportExt (hdc, GetDeviceCaps (hdc, LOGPIXELSX),
                               GetDeviceCaps (hdc, LOGPIXELSY)) ;
          }
     else
          SetMapMode (hdc, MM_TEXT + nMapMode - IDD_TEXT) ;
     }

void ShowMetrics (HWND hDlg)
     {
     static TEXTMETRIC tm ;
     static struct
          {
          short nDlgID ;
          short *pData ;
          }
          shorts [] =
          {
          TM_HEIGHT,     &tm.tmHeight,
          TM_ASCENT,     &tm.tmAscent,
          TM_DESCENT,    &tm.tmDescent,
          TM_INTLEAD,    &tm.tmInternalLeading,
          TM_EXTLEAD,    &tm.tmExternalLeading,
          TM_AVEWIDTH,   &tm.tmAveCharWidth,
          TM_MAXWIDTH,   &tm.tmMaxCharWidth,
          TM_WEIGHT,     &tm.tmWeight,
          TM_OVER,       &tm.tmOverhang,
          TM_DIGX,       &tm.tmDigitizedAspectX,
          TM_DIGY,       &tm.tmDigitizedAspectY
          } ;
     static char    *szFamily [] = { "Don't Care", "Roman",  "Swiss",
                                     "Modern",     "Script", "Decorative" } ;
     BOOL           bTrans ;
     char           szFaceName [LF_FACESIZE] ;
     HDC            hdc ;
     HFONT          hFont ;
     short          i ;

     lf.lfHeight    = GetDlgItemInt (hDlg, IDD_HEIGHT, &bTrans, TRUE) ;
     lf.lfWidth     = GetDlgItemInt (hDlg, IDD_WIDTH,  &bTrans, FALSE) ;
     lf.lfWeight    = GetDlgItemInt (hDlg, IDD_WEIGHT, &bTrans, FALSE) ;

     lf.lfItalic    = (BYTE) (IsDlgButtonChecked (hDlg, IDD_ITALIC) ? 1 : 0)
     lf.lfUnderline = (BYTE) (IsDlgButtonChecked (hDlg, IDD_UNDER)  ? 1 : 0)
     lf.lfStrikeOut = (BYTE) (IsDlgButtonChecked (hDlg, IDD_STRIKE) ? 1 : 0)

     GetDlgItemText (hDlg, IDD_FACE, lf.lfFaceName, LF_FACESIZE) ;

     dwAspectMatch = IsDlgButtonChecked (hDlg, IDD_ASPECT) ? 1L : 0L ;

     hdc = GetDC (hDlg) ;
     MySetMapMode (hdc) ;
     SetMapperFlags (hdc, dwAspectMatch) ;

     hFont = SelectObject (hdc, CreateFontIndirect (&lf)) ;
     GetTextMetrics (hdc, &tm) ;
     GetTextFace (hdc, sizeof szFaceName, szFaceName) ;

     DeleteObject (SelectObject (hdc, hFont)) ;
     ReleaseDC (hDlg, hdc) ;

     for (i = 0 ; i < sizeof shorts / sizeof shorts [0] ; i++)
          SetDlgItemInt (hDlg, shorts[i].nDlgID, *shorts[i].pData, TRUE) ;

     SetDlgItemText (hDlg, TM_PITCH, tm.tmPitchAndFamily & 1 ?
                                                      "VARIABLE":"FIXED") ;

     SetDlgItemText (hDlg, TM_FAMILY, szFamily [tm.tmPitchAndFamily >> 4]) ;
     SetDlgItemText (hDlg, TM_CHARSET, tm.tmCharSet ? "OEM" : "ANSI") ;
     SetDlgItemText (hDlg, TF_NAME, szFaceName) ;
     }

BOOL FAR PASCAL DlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam)
     {
     switch (message)
          {
          case WM_INITDIALOG:
               CheckRadioButton (hDlg, IDD_TEXT,   IDD_LTWPS,  IDD_TEXT) ;
               CheckRadioButton (hDlg, IDD_ANSI,   IDD_OEM,    IDD_ANSI) ;
               CheckRadioButton (hDlg, IDD_QDRAFT, IDD_QPROOF, IDD_QDRAFT) ;
               CheckRadioButton (hDlg, IDD_PDEF,   IDD_PVAR,   IDD_PDEF) ;
               CheckRadioButton (hDlg, IDD_DONT,   IDD_DEC,    IDD_DONT) ;

               lf.lfEscapement    = 0 ;
               lf.lfOrientation   = 0 ;
               lf.lfOutPrecision  = OUT_DEFAULT_PRECIS ;
               lf.lfClipPrecision = CLIP_DEFAULT_PRECIS ;

               ShowMetrics (hDlg) ;
                                        /* fall through */
          case WM_SETFOCUS:
               SetFocus (GetDlgItem (hDlg, IDD_HEIGHT)) ;
               return FALSE ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDD_TEXT:
                    case IDD_LOMET:
                    case IDD_HIMET:
                    case IDD_LOENG:
                    case IDD_HIENG:
                    case IDD_TWIPS:
                    case IDD_LTWPS:
                         CheckRadioButton (hDlg, IDD_TEXT, IDD_LTWPS, wParam)
                         nMapMode = wParam ;
                         break ;

                    case IDD_ASPECT:
                    case IDD_ITALIC:
                    case IDD_UNDER:
                    case IDD_STRIKE:
                         CheckDlgButton (hDlg, wParam,
                              IsDlgButtonChecked (hDlg, wParam) ? 0 : 1) ;
                         break ;

                    case IDD_ANSI:
                    case IDD_OEM:
                         CheckRadioButton (hDlg, IDD_ANSI, IDD_OEM, wParam) ;
                         lf.lfCharSet = (BYTE) (wParam == IDD_ANSI ? 0 : 255)
                         break ;

                    case IDD_QDRAFT:
                    case IDD_QDEF:
                    case IDD_QPROOF:
                         CheckRadioButton (hDlg, IDD_QDRAFT, IDD_QPROOF,
                                                                      wParam)
                         lf.lfQuality = (BYTE) (wParam - IDD_QDRAFT) ;
                         break ;

                    case IDD_PDEF:
                    case IDD_PFIXED:
                    case IDD_PVAR:
                         CheckRadioButton (hDlg, IDD_PDEF, IDD_PVAR, wParam)
                         lf.lfPitchAndFamily &= 0xF0 ;
                         lf.lfPitchAndFamily |= (BYTE) (wParam - IDD_PDEF) ;
                         break ;

                    case IDD_DONT:
                    case IDD_ROMAN:
                    case IDD_SWISS:
                    case IDD_MODERN:
                    case IDD_SCRIPT:
                    case IDD_DEC:
                         CheckRadioButton (hDlg, IDD_DONT, IDD_DEC, wParam) ;
                         lf.lfPitchAndFamily &= 0x0F ;
                         lf.lfPitchAndFamily |= (BYTE) (wParam-IDD_DONT << 4)
                         break ;

                    case IDD_OK:
                         ShowMetrics (hDlg) ;
                         InvalidateRect (GetParent (hDlg), NULL, TRUE) ;
                         break ;
                    }
               break ;

          default:
               return FALSE ;
          }
     return TRUE ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static char  szText [] =
                      "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPqQqRrSsTtUuVvWwXxYyZz"
     static short cxClient, cyClient ;
     HANDLE       hInstance ;
     HDC          hdc ;
     HFONT        hFont ;
     FARPROC      lpfnDlgProc ;
     PAINTSTRUCT  ps ;
     RECT         rect ;

     switch (message)
          {
          case WM_CREATE :
               hInstance = ((LPCREATESTRUCT) lParam)->hInstance ;
               lpfnDlgProc = MakeProcInstance (DlgProc, hInstance) ;
               hDlg = CreateDialog (hInstance, szAppName, hwnd, lpfnDlgProc)
               return 0 ;

          case WM_SETFOCUS:
               SetFocus (hDlg) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;
               MySetMapMode (hdc) ;
               SetMapperFlags (hdc, dwAspectMatch) ;
               GetClientRect (hDlg, &rect) ;
               rect.bottom += 1 ;
               DPtoLP (hdc, (LPPOINT) &rect, 2) ;

               hFont = SelectObject (hdc, CreateFontIndirect (&lf)) ;

               TextOut (hdc, rect.left, rect.bottom, szText, 52) ;

               DeleteObject (SelectObject (hdc, hFont)) ;
               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


POEPOEM.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP08\POEPOEM.C

/*-------------------------------------------------
   POEPOEM.C -- Demonstrates User-Defined Resource
                (c) Charles Petzold, 1990
  -------------------------------------------------*/

#include <windows.h>
#include "poepoem.h"

long FAR PASCAL WndProc  (HWND, WORD, WORD, LONG) ;

char   szAppName [10] ;
char   szCaption [35] ;
HANDLE hInst ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          LoadString (hInstance, IDS_APPNAME, szAppName, sizeof szAppName) ;
          LoadString (hInstance, IDS_CAPTION, szCaption, sizeof szCaption) ;

          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }
     else
          {
          GetInstanceData (hPrevInstance, szAppName, sizeof szAppName) ;
          GetInstanceData (hPrevInstance, szCaption, sizeof szCaption) ;
          }

     hInst = hInstance ;

     hwnd = CreateWindow (szAppName, szCaption,
                          WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HANDLE hResource ;
     static HWND   hScroll ;
     static short  nPosition, cxChar, cyChar, cyClient, nNumLines, xScroll ;
     char          szPoemRes [15] ;
     char far      *lpText ;
     HDC           hdc ;
     PAINTSTRUCT   ps ;
     RECT          rect ;
     TEXTMETRIC    tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;
               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;
               ReleaseDC (hwnd, hdc) ;

               xScroll = GetSystemMetrics (SM_CXVSCROLL) ;

               hScroll = CreateWindow ("scrollbar", NULL,
                              WS_CHILD | WS_VISIBLE | SBS_VERT,
                              0, 0, 0, 0,
                              hwnd, 1, hInst, NULL) ;

               LoadString (hInst, IDS_POEMRES, szPoemRes, sizeof szPoemRes) ;
               hResource = LoadResource (hInst,
                           FindResource (hInst, szPoemRes, "TEXT")) ;

               lpText = LockResource (hResource) ;

               nNumLines = 0 ;

               while (*lpText != '\\' && *lpText != '\0')
                    {
                    if (*lpText == '\n')
                         nNumLines ++ ;
                    lpText = AnsiNext (lpText) ;
                    }
               *lpText = '\0' ;

               GlobalUnlock (hResource) ;

               SetScrollRange (hScroll, SB_CTL, 0, nNumLines, FALSE) ;
               SetScrollPos   (hScroll, SB_CTL, 0, FALSE) ;
               return 0 ;

          case WM_SIZE:
               MoveWindow (hScroll, LOWORD (lParam) - xScroll, 0,
                    xScroll, cyClient = HIWORD (lParam), TRUE) ;
               SetFocus (hwnd) ;
               return 0 ;

          case WM_SETFOCUS:
               SetFocus (hScroll) ;
               return 0 ;

          case WM_VSCROLL:
               switch (wParam)
                    {
                    case SB_TOP:
                         nPosition = 0 ;
                         break ;
                    case SB_BOTTOM:
                         nPosition = nNumLines ;
                         break ;
                    case SB_LINEUP:
                         nPosition -= 1 ;
                         break ;
                    case SB_LINEDOWN:
                         nPosition += 1 ;
                         break ;
                    case SB_PAGEUP:
                         nPosition -= cyClient / cyChar ;
                         break ;
                    case SB_PAGEDOWN:
                         nPosition += cyClient / cyChar ;
                         break ;
                    case SB_THUMBPOSITION:
                         nPosition = LOWORD (lParam) ;
                         break ;
                    }
               nPosition = max (0, min (nPosition, nNumLines)) ;

               if (nPosition != GetScrollPos (hScroll, SB_CTL))
                    {
                    SetScrollPos (hScroll, SB_CTL, nPosition, TRUE) ;
                    InvalidateRect (hwnd, NULL, TRUE) ;
                    }
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               lpText = LockResource (hResource) ;

               GetClientRect (hwnd, &rect) ;
               rect.left += cxChar ;
               rect.top  += cyChar * (1 - nPosition) ;
               DrawText (hdc, lpText, -1, &rect, DT_EXTERNALLEADING) ;

               GlobalUnlock (hResource) ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               FreeResource (hResource) ;
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


POORMENU.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP09\POORMENU.C

/*-----------------------------------------
   POORMENU.C -- The Poor Person's Menu
                 (c) Charles Petzold, 1990
  -----------------------------------------*/

#include <windows.h>

#define IDM_ABOUT   1
#define IDM_HELP    2
#define IDM_REMOVE  3

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

static char szAppName [] = "PoorMenu" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HMENU    hMenu ;
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "The Poor-Person's Menu",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     hMenu = GetSystemMenu (hwnd, FALSE) ;

     AppendMenu (hMenu, MF_SEPARATOR, 0,          NULL) ;
     AppendMenu (hMenu, MF_STRING,    IDM_ABOUT,  "About...") ;
     AppendMenu (hMenu, MF_STRING,    IDM_HELP,   "Help...") ;
     AppendMenu (hMenu, MF_STRING,    IDM_REMOVE, "Remove Additions") ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     switch (message)
          {
          case WM_SYSCOMMAND:
               switch (wParam)
                    {
                    case IDM_ABOUT:
                         MessageBox (hwnd, "A Poor-Person's Menu Program.",
                                     szAppName, MB_OK | MB_ICONEXCLAMATION) ;
                         return 0 ;

                    case IDM_HELP:
                         MessageBox (hwnd, "Help not yet implemented.",
                                     szAppName, MB_OK | MB_ICONEXCLAMATION) ;
                         return 0 ;

                    case IDM_REMOVE:
                         GetSystemMenu (hwnd, TRUE) ;
                         return 0 ;
                    }
               break ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


POPMENU.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP09\POPMENU.C

/*----------------------------------------
   POPMENU.C -- Popup Menu Demonstration
                (c) Charles Petzold, 1990
  ----------------------------------------*/

#include <windows.h>
#include "popmenu.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

char   szAppName [] = "PopMenu" ;
HANDLE hInst ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hInst = hInstance ;

     hwnd = CreateWindow (szAppName, "Popup Menu Demonstration",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HMENU hMenu ;
     static int   wColorID [5] = { WHITE_BRUSH,  LTGRAY_BRUSH, GRAY_BRUSH,
                                   DKGRAY_BRUSH, BLACK_BRUSH } ;
     static WORD  wSelection = IDM_WHITE ;
     POINT        point ;

     switch (message)
          {
          case WM_CREATE:
               hMenu = LoadMenu (hInst, szAppName) ;
               hMenu = GetSubMenu (hMenu, 0) ;
               return 0 ;

          case WM_RBUTTONDOWN:
               point = MAKEPOINT (lParam) ;
               ClientToScreen (hwnd, &point) ;

               TrackPopupMenu (hMenu, 0, point.x, point.y, 0, hwnd, NULL) ;
               return 0 ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDM_NEW:
                    case IDM_OPEN:
                    case IDM_SAVE:
                    case IDM_SAVEAS:
                    case IDM_UNDO:
                    case IDM_CUT:
                    case IDM_COPY:
                    case IDM_PASTE:
                    case IDM_CLEAR:
                         MessageBeep (0) ;
                         return 0 ;

                    case IDM_WHITE:          // Note: Logic below
                    case IDM_LTGRAY:         //   assumes that IDM_WHITE
                    case IDM_GRAY:           //   through IDM_BLACK are
                    case IDM_DKGRAY:         //   consecutive numbers in
                    case IDM_BLACK:          //   the order shown here.

                         CheckMenuItem (hMenu, wSelection, MF_UNCHECKED) ;
                         wSelection = wParam ;
                         CheckMenuItem (hMenu, wSelection, MF_CHECKED) ;

                         SetClassWord (hwnd, GCW_HBRBACKGROUND,
                              GetStockObject (wColorID [wParam - IDM_WHITE]))

                         InvalidateRect (hwnd, NULL, TRUE) ;
                         return 0 ;

                    case IDM_ABOUT:
                         MessageBox (hwnd, "Popup Menu Demonstration Program.
                                     szAppName, MB_ICONINFORMATION | MB_OK) ;
                         return 0 ;

                    case IDM_EXIT:
                         SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
                         return 0 ;

                    case IDM_HELP:
                         MessageBox (hwnd, "Help not yet implemented.",
                                     szAppName, MB_ICONINFORMATION | MB_OK) ;
                         return 0 ;
                    }
               break ;

          case WM_DESTROY :
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


POPPAD.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP10\POPPAD.C

/*---------------------------------------
   POPPAD.C -- Popup Editor
               (c) Charles Petzold, 1990
  ---------------------------------------*/

#include <windows.h>
#include "poppad.h"
#define  EDITID 1

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG);

BOOL ReadFile  (HANDLE, HWND, HWND, POFSTRUCT, char *, BOOL) ;
BOOL WriteFile (HANDLE, HWND, HWND, POFSTRUCT, char *, BOOL) ;
BOOL PrintFile (HANDLE, HWND, HWND, char *) ;

LPSTR lstrrchr (LPSTR, char) ;

char szAppName  [] = "PopPad" ;
char szFileSpec [] = "*.TXT"  ;
char szUntitled [] = "(untitled)" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     MSG      msg;
     HWND     hwnd ;
     HANDLE   hAccel ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, NULL,
                          WS_OVERLAPPEDWINDOW,
                          GetSystemMetrics (SM_CXSCREEN) / 4,
                          GetSystemMetrics (SM_CYSCREEN) / 4,
                          GetSystemMetrics (SM_CXSCREEN) / 2,
                          GetSystemMetrics (SM_CYSCREEN) / 2,
                          NULL, NULL, hInstance, lpszCmdLine) ;

     ShowWindow (hwnd, nCmdShow) ;

     UpdateWindow (hwnd);

     hAccel = LoadAccelerators (hInstance, szAppName) ;

     while (GetMessage (&msg, NULL, 0, 0))
          {
          if (!TranslateAccelerator (hwnd, hAccel, &msg))
               {
               TranslateMessage (&msg) ;
               DispatchMessage (&msg) ;
               }
          }
     return msg.wParam ;
     }

BOOL FAR PASCAL AboutDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lPar
     {
     switch (message)
          {
          case WM_INITDIALOG:
               return TRUE ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDOK:
                         EndDialog (hDlg, 0) ;
                         return TRUE ;
                    }
               break ;
          }
     return FALSE ;
     }

void DoCaption (HWND hwnd, char *szFileName)
     {
     char szCaption [40] ;

     wsprintf (szCaption, "%s - %s", (LPSTR) szAppName,
               (LPSTR) (szFileName [0] ? szFileName : szUntitled)) ;

     SetWindowText (hwnd, szCaption) ;
     }

short AskAboutSave (HWND hwnd, char *szFileName)
     {
     char  szBuffer [40] ;
     short nReturn ;

     wsprintf (szBuffer, "Save current changes: %s",
               (LPSTR) (szFileName [0] ? szFileName : szUntitled)) ;

     if (IDYES == (nReturn = MessageBox (hwnd, szBuffer, szAppName,
                                    MB_YESNOCANCEL | MB_ICONQUESTION)))

          if (!SendMessage (hwnd, WM_COMMAND, IDM_SAVE, 0L))
               return IDCANCEL ;

     return nReturn ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL    bNeedSave = FALSE ;
     static char    szRealFileName [16] ;
     static FARPROC lpfnAboutDlgProc ;
     static HANDLE  hInst ;
     static HWND    hwndEdit ;
     char           szFileName [16] ;
     LONG           lSelect ;
     OFSTRUCT       of ;
     WORD           wEnable ;

     switch (message)
          {
          case WM_CREATE:
               hInst = ((LPCREATESTRUCT) lParam)->hInstance ;
               lpfnAboutDlgProc = MakeProcInstance (AboutDlgProc, hInst) ;

               hwndEdit = CreateWindow ("edit", NULL,
                         WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
                              WS_BORDER | ES_LEFT | ES_MULTILINE |
                              ES_AUTOHSCROLL | ES_AUTOVSCROLL,
                         0, 0, 0, 0,
                         hwnd, EDITID, hInst, NULL) ;

               SendMessage (hwndEdit, EM_LIMITTEXT, 32000, 0L) ;

               if (lstrlen (((LPCREATESTRUCT) lParam)->lpCreateParams))
                    {
                    OpenFile (((LPCREATESTRUCT) lParam)->lpCreateParams,
                                        &of, OF_PARSE) ;
                    lstrcpy (szFileName,
                              AnsiNext (lstrrchr (of.szPathName, '\\'))) ;

                    if (ReadFile (hInst, hwnd, hwndEdit, &of,
                              szFileName, FALSE))
                         lstrcpy (szRealFileName, szFileName) ;
                    }
               DoCaption (hwnd, szRealFileName) ;
               return 0 ;

          case WM_SETFOCUS:
               SetFocus (hwndEdit) ;
               return 0 ;

          case WM_SIZE:
               MoveWindow (hwndEdit, 0, 0, LOWORD (lParam),
                                           HIWORD (lParam), TRUE) ;
               return 0 ;

          case WM_INITMENUPOPUP:
               if (lParam == 1)
                    {
                    EnableMenuItem (wParam, IDM_UNDO,
                         SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?
                              MF_ENABLED : MF_GRAYED) ;

                    EnableMenuItem (wParam, IDM_PASTE,
                         IsClipboardFormatAvailable (CF_TEXT) ?
                              MF_ENABLED : MF_GRAYED) ;

                    lSelect = SendMessage (hwndEdit, EM_GETSEL, 0, 0L) ;

                    if (HIWORD (lSelect) == LOWORD (lSelect))
                         wEnable = MF_GRAYED ;
                    else
                         wEnable = MF_ENABLED ;

                    EnableMenuItem (wParam, IDM_CUT,   wEnable) ;
                    EnableMenuItem (wParam, IDM_COPY,  wEnable) ;
                    EnableMenuItem (wParam, IDM_CLEAR, wEnable) ;
                    }
               return 0 ;

          case WM_COMMAND :
               if (LOWORD (lParam) && wParam == EDITID)
                    {
                    switch (HIWORD (lParam))
                         {
                         case EN_UPDATE:
                              bNeedSave = TRUE ;
                              return 0 ;

                         case EN_ERRSPACE:
                              MessageBox (hwnd, "Edit control out of space.",
                                        szAppName, MB_OK | MB_ICONSTOP) ;
                              return 0 ;
                         }
                    break ;
                    }

               switch (wParam)
                    {
                    case IDM_NEW:
                         if (bNeedSave && IDCANCEL ==
                                   AskAboutSave (hwnd, szRealFileName))
                              return 0 ;

                         SetWindowText (hwndEdit, "\0") ;
                         szRealFileName [0] = '\0' ;
                         DoCaption (hwnd, szRealFileName) ;
                         bNeedSave = FALSE ;
                         return 0 ;

                    case IDM_OPEN:
                         if (bNeedSave && IDCANCEL ==
                                   AskAboutSave (hwnd, szRealFileName))
                              return 0 ;

                         if (ReadFile (hInst, hwnd, hwndEdit, &of,
                                        szFileName, TRUE))
                              {
                              lstrcpy (szRealFileName, szFileName) ;
                              DoCaption (hwnd, szRealFileName) ;
                              bNeedSave = FALSE ;
                              }

                         return 0 ;

                    case IDM_SAVE:
                         if (szRealFileName [0])
                              {
                              if (WriteFile (hInst, hwnd, hwndEdit, &of,
                                             szRealFileName, FALSE))
                                   {
                                   bNeedSave = FALSE ;
                                   return 1 ;
                                   }
                              return 0 ;
                              }
                                                  // fall through
                    case IDM_SAVEAS:
                         if (WriteFile (hInst, hwnd, hwndEdit, &of,
                                        szFileName, TRUE))
                              {
                              lstrcpy (szRealFileName, szFileName) ;
                              DoCaption (hwnd, szFileName) ;
                              bNeedSave = FALSE ;
                              return 1 ;
                              }
                         return 0 ;

                    case IDM_PRINT:
                         PrintFile (hInst, hwnd, hwndEdit,
                              szRealFileName [0] ? szRealFileName :
                                                   szUntitled) ;
                         return 0 ;

                    case IDM_EXIT:
                         SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
                         return 0 ;

                    case IDM_ABOUT:
                         DialogBox (hInst, "AboutBox", hwnd,
                                   lpfnAboutDlgProc) ;
                         return 0 ;

                    case IDM_UNDO:
                         SendMessage (hwndEdit, WM_UNDO, 0, 0L) ;
                         return 0 ;

                    case IDM_CUT:
                         SendMessage (hwndEdit, WM_CUT, 0, 0L) ;
                         return 0 ;

                    case IDM_COPY:
                         SendMessage (hwndEdit, WM_COPY, 0, 0L) ;
                         return 0 ;

                    case IDM_PASTE:
                         SendMessage (hwndEdit, WM_PASTE, 0, 0L) ;
                         return 0 ;

                    case IDM_CLEAR:
                         SendMessage (hwndEdit, WM_CLEAR, 0, 0L) ;
                         return 0 ;

                    case IDM_SELALL:
                         SendMessage (hwndEdit, EM_SETSEL, 0,
                                        MAKELONG (0, 32767)) ;
                         return 0 ;
                    }
               break ;

          case WM_CLOSE:
               if (!bNeedSave || IDCANCEL !=
                         AskAboutSave (hwnd, szRealFileName))
                    DestroyWindow (hwnd) ;

               return 0 ;

          case WM_QUERYENDSESSION:
               if (!bNeedSave || IDCANCEL !=
                         AskAboutSave (hwnd, szRealFileName))
                    return 1L ;

               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


POPPAD.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\POPPAD.C

/*---------------------------------------
   POPPAD.C -- Popup Editor
               (c) Charles Petzold, 1990
  ---------------------------------------*/

#include <windows.h>
#include "poppad.h"
#define  EDITID 1

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG);

BOOL ReadFile  (HANDLE, HWND, HWND, POFSTRUCT, char *, BOOL) ;
BOOL WriteFile (HANDLE, HWND, HWND, POFSTRUCT, char *, BOOL) ;
BOOL PrintFile (HANDLE, HWND, HWND, char *) ;

LPSTR lstrrchr (LPSTR, char) ;

char szAppName  [] = "PopPad" ;
char szFileSpec [] = "*.TXT"  ;
char szUntitled [] = "(untitled)" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     MSG      msg;
     HWND     hwnd ;
     HANDLE   hAccel ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, NULL,
                          WS_OVERLAPPEDWINDOW,
                          GetSystemMetrics (SM_CXSCREEN) / 4,
                          GetSystemMetrics (SM_CYSCREEN) / 4,
                          GetSystemMetrics (SM_CXSCREEN) / 2,
                          GetSystemMetrics (SM_CYSCREEN) / 2,
                          NULL, NULL, hInstance, lpszCmdLine) ;

     ShowWindow (hwnd, nCmdShow) ;

     UpdateWindow (hwnd);

     hAccel = LoadAccelerators (hInstance, szAppName) ;

     while (GetMessage (&msg, NULL, 0, 0))
          {
          if (!TranslateAccelerator (hwnd, hAccel, &msg))
               {
               TranslateMessage (&msg) ;
               DispatchMessage (&msg) ;
               }
          }
     return msg.wParam ;
     }

BOOL FAR PASCAL AboutDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lPar
     {
     switch (message)
          {
          case WM_INITDIALOG:
               return TRUE ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDOK:
                         EndDialog (hDlg, 0) ;
                         return TRUE ;
                    }
               break ;
          }
     return FALSE ;
     }

void DoCaption (HWND hwnd, char *szFileName)
     {
     char szCaption [40] ;

     wsprintf (szCaption, "%s - %s", (LPSTR) szAppName,
               (LPSTR) (szFileName [0] ? szFileName : szUntitled)) ;

     SetWindowText (hwnd, szCaption) ;
     }

short AskAboutSave (HWND hwnd, char *szFileName)
     {
     char  szBuffer [40] ;
     short nReturn ;

     wsprintf (szBuffer, "Save current changes: %s",
               (LPSTR) (szFileName [0] ? szFileName : szUntitled)) ;

     if (IDYES == (nReturn = MessageBox (hwnd, szBuffer, szAppName,
                                    MB_YESNOCANCEL | MB_ICONQUESTION)))

          if (!SendMessage (hwnd, WM_COMMAND, IDM_SAVE, 0L))
               return IDCANCEL ;

     return nReturn ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL    bNeedSave = FALSE ;
     static char    szRealFileName [16] ;
     static FARPROC lpfnAboutDlgProc ;
     static HANDLE  hInst ;
     static HWND    hwndEdit ;
     char           szFileName [16] ;
     LONG           lSelect ;
     OFSTRUCT       of ;
     WORD           wEnable ;

     switch (message)
          {
          case WM_CREATE:
               hInst = ((LPCREATESTRUCT) lParam)->hInstance ;
               lpfnAboutDlgProc = MakeProcInstance (AboutDlgProc, hInst) ;

               hwndEdit = CreateWindow ("edit", NULL,
                         WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
                              WS_BORDER | ES_LEFT | ES_MULTILINE |
                              ES_AUTOHSCROLL | ES_AUTOVSCROLL,
                         0, 0, 0, 0,
                         hwnd, EDITID, hInst, NULL) ;

               SendMessage (hwndEdit, EM_LIMITTEXT, 32000, 0L) ;

               if (lstrlen (((LPCREATESTRUCT) lParam)->lpCreateParams))
                    {
                    OpenFile (((LPCREATESTRUCT) lParam)->lpCreateParams,
                                        &of, OF_PARSE) ;
                    lstrcpy (szFileName,
                              AnsiNext (lstrrchr (of.szPathName, '\\'))) ;

                    if (ReadFile (hInst, hwnd, hwndEdit, &of,
                              szFileName, FALSE))
                         lstrcpy (szRealFileName, szFileName) ;
                    }
               DoCaption (hwnd, szRealFileName) ;
               return 0 ;

          case WM_SETFOCUS:
               SetFocus (hwndEdit) ;
               return 0 ;

          case WM_SIZE:
               MoveWindow (hwndEdit, 0, 0, LOWORD (lParam),
                                           HIWORD (lParam), TRUE) ;
               return 0 ;

          case WM_INITMENUPOPUP:
               if (lParam == 1)
                    {
                    EnableMenuItem (wParam, IDM_UNDO,
                         SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?
                              MF_ENABLED : MF_GRAYED) ;

                    EnableMenuItem (wParam, IDM_PASTE,
                         IsClipboardFormatAvailable (CF_TEXT) ?
                              MF_ENABLED : MF_GRAYED) ;

                    lSelect = SendMessage (hwndEdit, EM_GETSEL, 0, 0L) ;

                    if (HIWORD (lSelect) == LOWORD (lSelect))
                         wEnable = MF_GRAYED ;
                    else
                         wEnable = MF_ENABLED ;

                    EnableMenuItem (wParam, IDM_CUT,   wEnable) ;
                    EnableMenuItem (wParam, IDM_COPY,  wEnable) ;
                    EnableMenuItem (wParam, IDM_CLEAR, wEnable) ;
                    }
               return 0 ;

          case WM_COMMAND :
               if (LOWORD (lParam) && wParam == EDITID)
                    {
                    switch (HIWORD (lParam))
                         {
                         case EN_UPDATE:
                              bNeedSave = TRUE ;
                              return 0 ;

                         case EN_ERRSPACE:
                              MessageBox (hwnd, "Edit control out of space.",
                                        szAppName, MB_OK | MB_ICONSTOP) ;
                              return 0 ;
                         }
                    break ;
                    }

               switch (wParam)
                    {
                    case IDM_NEW:
                         if (bNeedSave && IDCANCEL ==
                                   AskAboutSave (hwnd, szRealFileName))
                              return 0 ;

                         SetWindowText (hwndEdit, "\0") ;
                         szRealFileName [0] = '\0' ;
                         DoCaption (hwnd, szRealFileName) ;
                         bNeedSave = FALSE ;
                         return 0 ;

                    case IDM_OPEN:
                         if (bNeedSave && IDCANCEL ==
                                   AskAboutSave (hwnd, szRealFileName))
                              return 0 ;

                         if (ReadFile (hInst, hwnd, hwndEdit, &of,
                                        szFileName, TRUE))
                              {
                              lstrcpy (szRealFileName, szFileName) ;
                              DoCaption (hwnd, szRealFileName) ;
                              bNeedSave = FALSE ;
                              }

                         return 0 ;

                    case IDM_SAVE:
                         if (szRealFileName [0])
                              {
                              if (WriteFile (hInst, hwnd, hwndEdit, &of,
                                             szRealFileName, FALSE))
                                   {
                                   bNeedSave = FALSE ;
                                   return 1 ;
                                   }
                              return 0 ;
                              }
                                                  // fall through
                    case IDM_SAVEAS:
                         if (WriteFile (hInst, hwnd, hwndEdit, &of,
                                        szFileName, TRUE))
                              {
                              lstrcpy (szRealFileName, szFileName) ;
                              DoCaption (hwnd, szFileName) ;
                              bNeedSave = FALSE ;
                              return 1 ;
                              }
                         return 0 ;

                    case IDM_PRINT:
                         PrintFile (hInst, hwnd, hwndEdit,
                              szRealFileName [0] ? szRealFileName :
                                                   szUntitled) ;
                         return 0 ;

                    case IDM_EXIT:
                         SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
                         return 0 ;

                    case IDM_ABOUT:
                         DialogBox (hInst, "AboutBox", hwnd,
                                   lpfnAboutDlgProc) ;
                         return 0 ;

                    case IDM_UNDO:
                         SendMessage (hwndEdit, WM_UNDO, 0, 0L) ;
                         return 0 ;

                    case IDM_CUT:
                         SendMessage (hwndEdit, WM_CUT, 0, 0L) ;
                         return 0 ;

                    case IDM_COPY:
                         SendMessage (hwndEdit, WM_COPY, 0, 0L) ;
                         return 0 ;

                    case IDM_PASTE:
                         SendMessage (hwndEdit, WM_PASTE, 0, 0L) ;
                         return 0 ;

                    case IDM_CLEAR:
                         SendMessage (hwndEdit, WM_CLEAR, 0, 0L) ;
                         return 0 ;

                    case IDM_SELALL:
                         SendMessage (hwndEdit, EM_SETSEL, 0,
                                        MAKELONG (0, 32767)) ;
                         return 0 ;
                    }
               break ;

          case WM_CLOSE:
               if (!bNeedSave || IDCANCEL !=
                         AskAboutSave (hwnd, szRealFileName))
                    DestroyWindow (hwnd) ;

               return 0 ;

          case WM_QUERYENDSESSION:
               if (!bNeedSave || IDCANCEL !=
                         AskAboutSave (hwnd, szRealFileName))
                    return 1L ;

               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


POPPAD1.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP06\POPPAD1.C

/*-------------------------------------------------------
   POPPAD1.C -- Popup Editor using child window edit box
                (c) Charles Petzold, 1990
  -------------------------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG);

char szAppName[] = "PopPad1" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, szAppName,
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          GetSystemMetrics (SM_CXSCREEN) / 2,
                          GetSystemMetrics (SM_CYSCREEN) / 2,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd);

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HWND hwndEdit ;

     switch (message)
          {
          case WM_CREATE:
               hwndEdit = CreateWindow ("edit", NULL,
                         WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
                              WS_BORDER | ES_LEFT | ES_MULTILINE |
                              ES_AUTOHSCROLL | ES_AUTOVSCROLL,
                         0, 0, 0, 0,
                         hwnd, 1,
                         ((LPCREATESTRUCT) lParam) -> hInstance, NULL) ;
               return 0 ;

          case WM_SETFOCUS:
               SetFocus (hwndEdit) ;
               return 0 ;

          case WM_SIZE:
               MoveWindow (hwndEdit, 0, 0, LOWORD (lParam),
                                           HIWORD (lParam), TRUE) ;
               return 0 ;

          case WM_COMMAND :
               if (wParam == 1 && HIWORD (lParam) == EN_ERRSPACE)
                    MessageBox (hwnd, "Edit control out of space.",
                              szAppName, MB_OK | MB_ICONSTOP) ;
               return 0 ;

          case WM_DESTROY :
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


POPPAD2.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP09\POPPAD2.C

/*-----------------------------------------------------
   POPPAD2.C -- Popup Editor Version 2 (includes menu)
                (c) Charles Petzold, 1990
  -----------------------------------------------------*/

#include <windows.h>
#include "poppad2.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG);

char szAppName [] = "PopPad2" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HANDLE   hAccel ;
     HWND     hwnd ;
     MSG      msg;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, szAppName,
                          WS_OVERLAPPEDWINDOW,
                          GetSystemMetrics (SM_CXSCREEN) / 4,
                          GetSystemMetrics (SM_CYSCREEN) / 4,
                          GetSystemMetrics (SM_CXSCREEN) / 2,
                          GetSystemMetrics (SM_CYSCREEN) / 2,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd);

     hAccel = LoadAccelerators (hInstance, szAppName) ;

     while (GetMessage (&msg, NULL, 0, 0))
          {
          if (!TranslateAccelerator (hwnd, hAccel, &msg))
               {
               TranslateMessage (&msg) ;
               DispatchMessage (&msg) ;
               }
          }
     return msg.wParam ;
     }

AskConfirmation (HWND hwnd)
     {
     return MessageBox (hwnd, "Really want to close PopPad2?",
                        szAppName, MB_YESNO | MB_ICONQUESTION) ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HWND hwndEdit ;
     LONG        lSelect ;
     WORD        wEnable ;

     switch (message)
          {
          case WM_CREATE:
               hwndEdit = CreateWindow ("edit", NULL,
                         WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |
                              WS_BORDER | ES_LEFT | ES_MULTILINE |
                              ES_AUTOHSCROLL | ES_AUTOVSCROLL,
                         0, 0, 0, 0,
                         hwnd, 1, ((LPCREATESTRUCT) lParam)->hInstance, NULL)
               return 0 ;

          case WM_SETFOCUS:
               SetFocus (hwndEdit) ;
               return 0 ;

          case WM_SIZE:
               MoveWindow (hwndEdit, 0, 0, LOWORD (lParam),
                                           HIWORD (lParam), TRUE) ;
               return 0 ;

          case WM_INITMENUPOPUP:
               if (lParam == 1)
                    {
                    EnableMenuItem (wParam, IDM_UNDO,
                         SendMessage (hwndEdit, EM_CANUNDO, 0, 0L) ?
                              MF_ENABLED : MF_GRAYED) ;

                    EnableMenuItem (wParam, IDM_PASTE,
                         IsClipboardFormatAvailable (CF_TEXT) ?
                              MF_ENABLED : MF_GRAYED) ;

                    lSelect = SendMessage (hwndEdit, EM_GETSEL, 0, 0L) ;

                    if (HIWORD (lSelect) == LOWORD (lSelect))
                         wEnable = MF_GRAYED ;
                    else
                         wEnable = MF_ENABLED ;

                    EnableMenuItem (wParam, IDM_CUT,   wEnable) ;
                    EnableMenuItem (wParam, IDM_COPY,  wEnable) ;
                    EnableMenuItem (wParam, IDM_CLEAR, wEnable) ;

                    return 0 ;
                    }
               break ;

          case WM_COMMAND :
               if (LOWORD (lParam))
                    {
                    if (wParam == 1 && HIWORD (lParam) == EN_ERRSPACE)
                         MessageBox (hwnd, "Edit control out of space.",
                                     szAppName, MB_OK | MB_ICONSTOP) ;

                    return 0 ;
                    }

               else switch (wParam)
                         {
                         case IDM_NEW:
                         case IDM_OPEN:
                         case IDM_SAVE:
                         case IDM_SAVEAS:
                         case IDM_PRINT:
                              MessageBeep (0) ;
                              return 0 ;

                         case IDM_EXIT:
                              SendMessage (hwnd, WM_CLOSE, 0, 0L) ;
                              return 0 ;

                         case IDM_ABOUT:
                              MessageBox (hwnd,
                                   "POPPAD2 (c) Charles Petzold, 1990",
                                   szAppName, MB_OK | MB_ICONINFORMATION) ;
                              return 0 ;

                         case IDM_UNDO:
                              SendMessage (hwndEdit, WM_UNDO, 0, 0L) ;
                              return 0 ;

                         case IDM_CUT:
                              SendMessage (hwndEdit, WM_CUT, 0, 0L) ;
                              return 0 ;

                         case IDM_COPY:
                              SendMessage (hwndEdit, WM_COPY, 0, 0L) ;
                              return 0 ;

                         case IDM_PASTE:
                              SendMessage (hwndEdit, WM_PASTE, 0, 0L) ;
                              return 0 ;

                         case IDM_CLEAR:
                              SendMessage (hwndEdit, WM_CLEAR, 0, 0L) ;
                              return 0 ;

                         case IDM_SELALL:
                              SendMessage (hwndEdit, EM_SETSEL, 0,
                                           MAKELONG (0, 32767)) ;

                              return 0 ;
                         }
               break ;

          case WM_CLOSE:
               if (IDYES == AskConfirmation (hwnd))
                    DestroyWindow (hwnd) ;
               return 0 ;

          case WM_QUERYENDSESSION:
               if (IDYES == AskConfirmation (hwnd))
                    return 1L ;
               else
                    return 0 ;

          case WM_DESTROY :
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


POPPADF.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP10\POPPADF.C

/*-----------------------------------
   POPPADF -- Popup Notepad File I/O
  -----------------------------------*/

#include <windows.h>
                                        // in FILEDLG.C

int DoFileOpenDlg (HANDLE, WORD, char *, char *, WORD,   char *, POFSTRUCT) ;
int DoFileSaveDlg (HANDLE, WORD, char *, char *, WORD *, char *, POFSTRUCT) ;

extern char szAppName  [] ;             // in POPPAD.C
extern char szFileSpec [] ;

long FileLength (HANDLE hFile)
     {
     long   lCurrentPos = _llseek (hFile, 0L, 1) ;
     long   lFileLength = _llseek (hFile, 0L, 2) ;

     _llseek (hFile, lCurrentPos, 0) ;

     return lFileLength ;
     }

void OkMessageBox (HWND hwnd, char *szString, char *szFileName)
     {
     char szBuffer [40] ;

     wsprintf (szBuffer, szString, (LPSTR) szFileName) ;

     MessageBox (hwnd, szBuffer, szAppName, MB_OK | MB_ICONEXCLAMATION) ;
     }

BOOL ReadFile (HANDLE hInstance, HWND hwnd, HWND hwndEdit, POFSTRUCT pof,
         char *szFileName, BOOL bAskName)
     {
     DWORD  dwLength ;
     HANDLE hFile, hTextBuffer ;
     LPSTR  lpTextBuffer ;

     if (bAskName)
          {
          if (!DoFileOpenDlg (hInstance, hwnd, szFileSpec, szFileSpec + 1,
                                        0x4010, szFileName, pof))
               return FALSE ;
          }

     if (-1 == (hFile = OpenFile (szFileName, pof, OF_READ | OF_REOPEN)))
          {
          OkMessageBox (hwnd, "Cannot open file %s", szFileName) ;
          return FALSE ;
          }

     if ((dwLength = FileLength (hFile)) >= 32000)
          {
          _lclose (hFile) ;
          OkMessageBox (hwnd, "File %s too large", szFileName) ;
          return FALSE ;
          }

     if (NULL == (hTextBuffer = GlobalAlloc (GHND, (DWORD) dwLength + 1)))
          {
          _lclose (hFile) ;
          OkMessageBox (hwnd, "Cannot allocate memory for %s", szFileName) ;
          return FALSE ;
          }

     lpTextBuffer = GlobalLock (hTextBuffer) ;
     _lread (hFile, lpTextBuffer, (WORD) dwLength) ;
     _lclose (hFile) ;
     lpTextBuffer [(WORD) dwLength] = '\0' ;

     SetWindowText (hwndEdit, lpTextBuffer) ;
     GlobalUnlock (hTextBuffer) ;
     GlobalFree (hTextBuffer) ;

     return TRUE ;
     }

BOOL WriteFile (HANDLE hInstance, HWND hwnd, HWND hwndEdit, POFSTRUCT pof,
    char *szFileName, BOOL bAskName)
     {
     char      szBuffer [40] ;
     HANDLE    hFile, hTextBuffer ;
     NPSTR     npTextBuffer ;
     WORD      wStatus, wLength ;

     if (bAskName)
          {
          if (!DoFileSaveDlg (hInstance, hwnd, szFileSpec, szFileSpec + 1,
                                   &wStatus, szFileName, pof))
               return FALSE ;

          if (wStatus == 1)
               {
               wsprintf (szBuffer, "Replace existing %s", (LPSTR) szFileName)
               if (IDNO == MessageBox (hwnd, szBuffer, szAppName,
                                             MB_YESNO | MB_ICONQUESTION))
                    return FALSE ;
               }
          }
     else
          OpenFile (szFileName, pof, OF_PARSE) ;

     if (-1 == (hFile = OpenFile (szFileName, pof, OF_CREATE | OF_REOPEN)))
          {
          OkMessageBox (hwnd, "Cannot create file %s", szFileName) ;
          return FALSE ;
          }

     wLength = GetWindowTextLength (hwndEdit) ;
     hTextBuffer = (HANDLE) SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L) ;
     npTextBuffer = LocalLock (hTextBuffer) ;

     if (wLength != _lwrite (hFile, npTextBuffer, wLength))
          {
          _lclose (hFile) ;
          OkMessageBox (hwnd, "Cannot write file %s to disk", szFileName) ;
          return FALSE ;
          }

     _lclose (hFile) ;
     LocalUnlock (hTextBuffer) ;

     return TRUE ;
     }


POPPADF.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\POPPADF.C

/*-----------------------------------
   POPPADF -- Popup Notepad File I/O
  -----------------------------------*/

#include <windows.h>
                                        // in FILEDLG.C

int DoFileOpenDlg (HANDLE, WORD, char *, char *, WORD,   char *, POFSTRUCT) ;
int DoFileSaveDlg (HANDLE, WORD, char *, char *, WORD *, char *, POFSTRUCT) ;

extern char szAppName  [] ;             // in POPPAD.C
extern char szFileSpec [] ;

long FileLength (HANDLE hFile)
     {
     long   lCurrentPos = _llseek (hFile, 0L, 1) ;
     long   lFileLength = _llseek (hFile, 0L, 2) ;

     _llseek (hFile, lCurrentPos, 0) ;

     return lFileLength ;
     }

void OkMessageBox (HWND hwnd, char *szString, char *szFileName)
     {
     static char szBuffer [40] ;

     wsprintf (szBuffer, szString, (LPSTR) szFileName) ;

     MessageBox (hwnd, szBuffer, szAppName, MB_OK | MB_ICONEXCLAMATION) ;
     }

BOOL ReadFile (HANDLE hInstance, HWND hwnd, HWND hwndEdit, POFSTRUCT pof,
         char *szFileName, BOOL bAskName)
     {
     DWORD  dwLength ;
     HANDLE hFile, hTextBuffer ;
     LPSTR  lpTextBuffer ;

     if (bAskName)
          {
          if (!DoFileOpenDlg (hInstance, hwnd, szFileSpec, szFileSpec + 1,
                                        0x4010, szFileName, pof))
               return FALSE ;
          }

     if (-1 == (hFile = OpenFile (szFileName, pof, OF_READ | OF_REOPEN)))
          {
          OkMessageBox (hwnd, "Cannot open file %s", szFileName) ;
          return FALSE ;
          }

     if ((dwLength = FileLength (hFile)) >= 32000)
          {
          _lclose (hFile) ;
          OkMessageBox (hwnd, "File %s too large", szFileName) ;
          return FALSE ;
          }

     if (NULL == (hTextBuffer = GlobalAlloc (GHND, (DWORD) dwLength + 1)))
          {
          _lclose (hFile) ;
          OkMessageBox (hwnd, "Cannot allocate memory for %s", szFileName) ;
          return FALSE ;
          }

     lpTextBuffer = GlobalLock (hTextBuffer) ;
     _lread (hFile, lpTextBuffer, (WORD) dwLength) ;
     _lclose (hFile) ;
     lpTextBuffer [(WORD) dwLength] = '\0' ;

     SetWindowText (hwndEdit, lpTextBuffer) ;
     GlobalUnlock (hTextBuffer) ;
     GlobalFree (hTextBuffer) ;

     return TRUE ;
     }

BOOL WriteFile (HANDLE hInstance, HWND hwnd, HWND hwndEdit, POFSTRUCT pof,
    char *szFileName, BOOL bAskName)
     {
     char      szBuffer [40] ;
     HANDLE    hFile, hTextBuffer ;
     NPSTR     npTextBuffer ;
     WORD      wStatus, wLength ;

     if (bAskName)
          {
          if (!DoFileSaveDlg (hInstance, hwnd, szFileSpec, szFileSpec + 1,
                                   &wStatus, szFileName, pof))
               return FALSE ;

          if (wStatus == 1)
               {
               wsprintf (szBuffer, "Replace existing %s", (LPSTR) szFileName)
               if (IDNO == MessageBox (hwnd, szBuffer, szAppName,
                                             MB_YESNO | MB_ICONQUESTION))
                    return FALSE ;
               }
          }
     else
          OpenFile (szFileName, pof, OF_PARSE) ;

     if (-1 == (hFile = OpenFile (szFileName, pof, OF_CREATE | OF_REOPEN)))
          {
          OkMessageBox (hwnd, "Cannot create file %s", szFileName) ;
          return FALSE ;
          }

     wLength = GetWindowTextLength (hwndEdit) ;
     hTextBuffer = (HANDLE) SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L) ;
     npTextBuffer = LocalLock (hTextBuffer) ;

     if (wLength != _lwrite (hFile, npTextBuffer, wLength))
          {
          _lclose (hFile) ;
          OkMessageBox (hwnd, "Cannot write file %s to disk", szFileName) ;
          return FALSE ;
          }

     _lclose (hFile) ;
     LocalUnlock (hTextBuffer) ;

     return TRUE ;
     }


POPPADP.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\POPPADP.C

/*----------------------------------------------
   POPPADP.C -- Popup Editor Printing Functions
  ----------------------------------------------*/

#include <windows.h>
#include <string.h>
#include "filedlg.h"                    // for IDD_FNAME definition

extern char szAppName [] ;              // in POPPAD.C

BOOL bUserAbort ;
HWND hDlgPrint ;

BOOL FAR PASCAL PrintDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lPar
     {
     switch (message)
          {
          case WM_INITDIALOG:
               EnableMenuItem (GetSystemMenu (hDlg, FALSE), SC_CLOSE,
                                                            MF_GRAYED) ;
               return TRUE ;

          case WM_COMMAND:
               bUserAbort = TRUE ;
               EnableWindow (GetParent (hDlg), TRUE) ;
               DestroyWindow (hDlg) ;
               hDlgPrint = 0 ;
               return TRUE ;
          }
     return FALSE ;
     }

BOOL FAR PASCAL AbortProc (HDC hPrinterDC, short nCode)
     {
     MSG   msg ;

     while (!bUserAbort && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
          {
          if (!hDlgPrint || !IsDialogMessage (hDlgPrint, &msg))
               {
               TranslateMessage (&msg) ;
               DispatchMessage (&msg) ;
               }
          }
     return !bUserAbort ;
     }

HDC GetPrinterDC (void)
     {
     static char szPrinter [80] ;
     char        *szDevice, *szDriver, *szOutput ;

     GetProfileString ("windows", "device", ",,,", szPrinter, 80) ;

     if ((szDevice = strtok (szPrinter, "," )) &&
         (szDriver = strtok (NULL,      ", ")) &&
         (szOutput = strtok (NULL,      ", ")))

               return CreateDC (szDriver, szDevice, szOutput, NULL) ;

     return 0 ;
     }

BOOL PrintFile (HANDLE hInst, HWND hwnd, HWND hwndEdit, char *szFileName)
     {
     BOOL       bError = FALSE ;
     char       szMsg [40] ;
     FARPROC    lpfnAbortProc, lpfnPrintDlgProc ;
     HDC        hdcPrn ;
     NPSTR      psBuffer ;
     RECT       rect ;
     short      yChar, nCharsPerLine, nLinesPerPage,
                nTotalLines, nTotalPages, nPage, nLine, nLineNum = 0 ;
     TEXTMETRIC tm ;

     if (0 == (nTotalLines = (short) SendMessage (hwndEdit,
                                             EM_GETLINECOUNT, 0, 0L)))
          return FALSE ;

     if (NULL == (hdcPrn = GetPrinterDC ()))
          return TRUE ;

     GetTextMetrics (hdcPrn, &tm) ;
     yChar = tm.tmHeight + tm.tmExternalLeading ;

     nCharsPerLine = GetDeviceCaps (hdcPrn, HORZRES) / tm.tmAveCharWidth ;
     nLinesPerPage = GetDeviceCaps (hdcPrn, VERTRES) / yChar ;
     nTotalPages   = (nTotalLines + nLinesPerPage - 1) / nLinesPerPage ;

     psBuffer = (NPSTR) LocalAlloc (LPTR, nCharsPerLine) ;

     EnableWindow (hwnd, FALSE) ;

     bUserAbort = FALSE ;
     lpfnPrintDlgProc = MakeProcInstance (PrintDlgProc, hInst) ;
     hDlgPrint = CreateDialog (hInst, "PrintDlgBox", hwnd, lpfnPrintDlgProc)
     SetDlgItemText (hDlgPrint, IDD_FNAME, szFileName) ;

     lpfnAbortProc = MakeProcInstance (AbortProc, hInst) ;
     Escape (hdcPrn, SETABORTPROC, 0, (LPSTR) lpfnAbortProc, NULL) ;

     strcat (strcat (strcpy (szMsg, szAppName), " - "), szFileName) ;

     if (Escape (hdcPrn, STARTDOC, strlen (szMsg), szMsg, NULL) > 0)
          {
          for (nPage = 0 ; nPage < nTotalPages ; nPage++)
               {
               for (nLine = 0 ; nLine < nLinesPerPage &&
                                nLineNum < nTotalLines ; nLine++, nLineNum++)
                    {
                    *(short *) psBuffer = nCharsPerLine ;

                    TextOut (hdcPrn, 0, yChar * nLine, psBuffer,
                         (short) SendMessage (hwndEdit, EM_GETLINE,
                                        nLineNum, (LONG) (LPSTR) psBuffer)) ;
                    }

               if (Escape (hdcPrn, NEWFRAME, 0, NULL, (LPSTR) &rect) < 0)
                    {
                    bError = TRUE ;
                    break ;
                    }

               if (bUserAbort)
                    break ;
               }
          }
     else
          bError = TRUE ;

     if (!bError)
          Escape (hdcPrn, ENDDOC, 0, NULL, NULL) ;

     if (!bUserAbort)
          {
          EnableWindow (hwnd, TRUE) ;
          DestroyWindow (hDlgPrint) ;
          }

     if (bError || bUserAbort)
          {
          strcat (strcpy (szMsg, "Could not print: "), szFileName) ;
          MessageBox (hwnd, szMsg, szAppName, MB_OK | MB_ICONEXCLAMATION) ;
          }

     LocalFree ((LOCALHANDLE) psBuffer) ;
     FreeProcInstance (lpfnPrintDlgProc) ;
     FreeProcInstance (lpfnAbortProc) ;
     DeleteDC (hdcPrn) ;

     return bError || bUserAbort ;
     }


POPPADP0.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP10\POPPADP0.C

/*---------------------------------------------------------
   POPPADP0.C -- Popup Notepad Printing -- dummy functions
  ---------------------------------------------------------*/

#include <windows.h>

extern char szAppName [] ;              // in POPPAD.C

BOOL FAR PASCAL PrintDlgProc (HWND hDlg, WORD message,
                              WORD wParam, LONG lParam)
     {
     return FALSE ;
     }

BOOL FAR PASCAL AbortProc (HDC hPrinterDC, short nCode)
     {
     return FALSE ;
     }

BOOL PrintFile (HANDLE hInstance, HWND hwnd, HWND hwndEdit, char *szFileName)
     {
     MessageBox (hwnd, "Printing not yet implemented", szAppName,
                       MB_OK | MB_ICONEXCLAMATION) ;
     return FALSE ;
     }


PRINT.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\PRINT.C

/*-------------------------------------------------------------------
   PRINT.C -- Common Routines for Print1, Print2, Print3, and Print4
  -------------------------------------------------------------------*/

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

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
BOOL PrintMyPage (HWND) ;

extern HANDLE hInst ;
extern char szAppName [] ;
extern char szCaption [] ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hInst = hInstance ;

     hwnd = CreateWindow (szAppName, szCaption,
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     HMENU hMenu ;

     switch (message)
          {
          case WM_CREATE:
               hMenu = GetSystemMenu (hwnd, FALSE);
               AppendMenu (hMenu, MF_SEPARATOR, 0, NULL) ;
               AppendMenu (hMenu, 0, 1, "&Print") ;
               return 0 ;

          case WM_SYSCOMMAND:
               if (wParam == 1)
                    {
                    if (PrintMyPage (hwnd))
                         MessageBox (hwnd, "Could not print page",
                              szAppName, MB_OK | MB_ICONEXCLAMATION) ;
                    return 0 ;
                    }
               break ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }

HDC GetPrinterDC (void)
     {
     static char szPrinter [80] ;
     char        *szDevice, *szDriver, *szOutput ;

     GetProfileString ("windows", "device", ",,,", szPrinter, 80) ;

     if ((szDevice = strtok (szPrinter, "," )) &&
         (szDriver = strtok (NULL,      ", ")) &&
         (szOutput = strtok (NULL,      ", ")))

               return CreateDC (szDriver, szDevice, szOutput, NULL) ;

     return 0 ;
     }

void PageGDICalls (HDC hdcPrn, short cxPage, short cyPage)
     {
     static char szTextStr [] = "Hello Printer!" ;
     DWORD       dwExtent ;

     Rectangle (hdcPrn, 0, 0, cxPage, cyPage) ;

     MoveTo (hdcPrn, 0, 0) ;
     LineTo (hdcPrn, cxPage, cyPage) ;
     MoveTo (hdcPrn, cxPage, 0) ;
     LineTo (hdcPrn, 0, cyPage) ;

     SaveDC (hdcPrn) ;

     SetMapMode (hdcPrn, MM_ISOTROPIC) ;
     SetWindowExt   (hdcPrn, 1000, 1000) ;
     SetViewportExt (hdcPrn, cxPage / 2, -cyPage / 2) ;
     SetViewportOrg (hdcPrn, cxPage / 2,  cyPage / 2) ;

     Ellipse (hdcPrn, -500, 500, 500, -500) ;

     dwExtent = GetTextExtent (hdcPrn, szTextStr, sizeof szTextStr - 1) ;
     TextOut (hdcPrn, LOWORD (dwExtent) / 2, HIWORD (dwExtent) / 2,
              szTextStr, sizeof szTextStr - 1) ;

     RestoreDC (hdcPrn, -1) ;
     }


PRINT1.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\PRINT1.C

/*---------------------------------------
   PRINT1.C -- Bare Bones Printing
               (c) Charles Petzold, 1990
  ---------------------------------------*/

#include <windows.h>

HDC  GetPrinterDC (void) ;              // in PRINT.C
void PageGDICalls (HDC, short, short) ;

HANDLE hInst ;
char   szAppName [] = "Print1" ;
char   szCaption [] = "Print Program 1" ;

BOOL PrintMyPage (HWND hwnd)
     {
     static char szMessage [] = "Print1: Printing" ;
     BOOL        bError = FALSE ;
     HDC         hdcPrn ;
     short       xPage, yPage ;

     if (NULL == (hdcPrn = GetPrinterDC ()))
          return TRUE ;

     xPage = GetDeviceCaps (hdcPrn, HORZRES) ;
     yPage = GetDeviceCaps (hdcPrn, VERTRES) ;

     if (Escape (hdcPrn, STARTDOC, sizeof szMessage - 1, szMessage, NULL) > 0
          {
          PageGDICalls (hdcPrn, xPage, yPage) ;

          if (Escape (hdcPrn, NEWFRAME, 0, NULL, NULL) > 0)
               Escape (hdcPrn, ENDDOC, 0, NULL, NULL) ;
          else
               bError = TRUE ;
          }
     else
          bError = TRUE ;

     DeleteDC (hdcPrn) ;
     return bError ;
     }


PRINT2.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\PRINT2.C

/*------------------------------------------
   PRINT2.C -- Printing with Abort Function
               (c) Charles Petzold, 1990
  ------------------------------------------*/

#include <windows.h>

HDC  GetPrinterDC (void) ;              // in PRINT.C
void PageGDICalls (HDC, short, short) ;

HANDLE hInst ;
char   szAppName [] = "Print2" ;
char   szCaption [] = "Print Program 2 (Abort Function)" ;

BOOL FAR PASCAL AbortProc (HDC hdcPrn, short nCode)
     {
     MSG   msg ;

     while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
          {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
          }
     return TRUE ;
     }

BOOL PrintMyPage (HWND hwnd)
     {
     static char szMessage [] = "Print2: Printing" ;
     BOOL        bError = FALSE ;
     FARPROC     lpfnAbortProc ;
     HDC         hdcPrn ;
     RECT        rect ;
     short       xPage, yPage ;

     if (NULL == (hdcPrn = GetPrinterDC ()))
          return TRUE ;

     xPage = GetDeviceCaps (hdcPrn, HORZRES) ;
     yPage = GetDeviceCaps (hdcPrn, VERTRES) ;

     EnableWindow (hwnd, FALSE) ;

     lpfnAbortProc = MakeProcInstance (AbortProc, hInst) ;
     Escape (hdcPrn, SETABORTPROC, 0, (LPSTR) lpfnAbortProc, NULL) ;

     if (Escape (hdcPrn, STARTDOC, sizeof szMessage - 1, szMessage, NULL) > 0
          {
          PageGDICalls (hdcPrn, xPage, yPage) ;

          if (Escape (hdcPrn, NEWFRAME, 0, NULL, NULL) > 0)
               Escape (hdcPrn, ENDDOC, 0, NULL, NULL) ;
          else
               bError = TRUE ;
          }
     else
          bError = TRUE ;

     if (!bError)
          Escape (hdcPrn, ENDDOC, 0, NULL, NULL) ;

     FreeProcInstance (lpfnAbortProc) ;
     EnableWindow (hwnd, TRUE) ;
     DeleteDC (hdcPrn) ;
     return bError ;
     }


PRINT3.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\PRINT3.C

/*---------------------------------------
   PRINT3.C -- Printing with Dialog Box
               (c) Charles Petzold, 1990
  ---------------------------------------*/

#include <windows.h>

HDC  GetPrinterDC (void) ;              // in PRINT.C
void PageGDICalls (HDC, short, short) ;

HANDLE hInst ;
char   szAppName [] = "Print3" ;
char   szCaption [] = "Print Program 3 (Dialog Box)" ;

BOOL   bUserAbort ;
HWND   hDlgPrint ;

BOOL FAR PASCAL PrintDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lPar
     {
     switch (message)
          {
          case WM_INITDIALOG:
               SetWindowText (hDlg, szAppName) ;
               EnableMenuItem (GetSystemMenu (hDlg, FALSE), SC_CLOSE,
                                                            MF_GRAYED) ;
               return TRUE ;

          case WM_COMMAND:
               bUserAbort = TRUE ;
               EnableWindow (GetParent (hDlg), TRUE) ;
               DestroyWindow (hDlg) ;
               hDlgPrint = 0 ;
               return TRUE ;
          }
     return FALSE ;
     }

BOOL FAR PASCAL AbortProc (HDC hdcPrn, short nCode)
     {
     MSG   msg ;

     while (!bUserAbort && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
          {
          if (!hDlgPrint || !IsDialogMessage (hDlgPrint, &msg))
               {
               TranslateMessage (&msg) ;
               DispatchMessage (&msg) ;
               }
          }
     return !bUserAbort ;
     }

BOOL PrintMyPage (HWND hwnd)
     {
     static char szMessage [] = "Print3: Printing" ;
     BOOL        bError = FALSE ;
     FARPROC     lpfnAbortProc, lpfnPrintDlgProc ;
     HDC         hdcPrn ;
     RECT        rect ;
     short       xPage, yPage ;

     if (NULL == (hdcPrn = GetPrinterDC ()))
          return TRUE ;

     xPage = GetDeviceCaps (hdcPrn, HORZRES) ;
     yPage = GetDeviceCaps (hdcPrn, VERTRES) ;

     EnableWindow (hwnd, FALSE) ;

     bUserAbort = FALSE ;
     lpfnPrintDlgProc = MakeProcInstance (PrintDlgProc, hInst) ;
     hDlgPrint = CreateDialog (hInst, "PrintDlgBox", hwnd, lpfnPrintDlgProc)

     lpfnAbortProc = MakeProcInstance (AbortProc, hInst) ;
     Escape (hdcPrn, SETABORTPROC, 0, (LPSTR) lpfnAbortProc, NULL) ;

     if (Escape (hdcPrn, STARTDOC, sizeof szMessage - 1, szMessage, NULL) > 0
          {
          PageGDICalls (hdcPrn, xPage, yPage) ;

          if (Escape (hdcPrn, NEWFRAME, 0, NULL, NULL) > 0)
               Escape (hdcPrn, ENDDOC, 0, NULL, NULL) ;
          else
               bError = TRUE ;
          }
     else
          bError = TRUE ;

     if (!bUserAbort)
          {
          EnableWindow (hwnd, TRUE) ;
          DestroyWindow (hDlgPrint) ;
          }

     FreeProcInstance (lpfnPrintDlgProc) ;
     FreeProcInstance (lpfnAbortProc) ;
     DeleteDC (hdcPrn) ;

     return bError || bUserAbort ;
     }


PRINT4.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP15\PRINT4.C

/*---------------------------------------
   PRINT4.C -- Printing with Banding
               (c) Charles Petzold, 1990
  ---------------------------------------*/

#include <windows.h>

HDC  GetPrinterDC (void) ;              // in PRINT.C

typedef BOOL (FAR PASCAL * ABORTPROC) (HDC, short) ;

HANDLE hInst ;
char   szAppName [] = "Print4" ;
char   szCaption [] = "Print Program 4 (Banding)" ;

BOOL   bUserAbort ;
HWND   hDlgPrint ;

BOOL FAR PASCAL PrintDlgProc (HWND hDlg, WORD message, WORD wParam, LONG lPar
     {
     switch (message)
          {
          case WM_INITDIALOG:
               SetWindowText (hDlg, szAppName) ;
               EnableMenuItem (GetSystemMenu (hDlg, FALSE), SC_CLOSE,
                                                            MF_GRAYED) ;
               return TRUE ;

          case WM_COMMAND:
               bUserAbort = TRUE ;
               EnableWindow (GetParent (hDlg), TRUE) ;
               DestroyWindow (hDlg) ;
               hDlgPrint = 0 ;
               return TRUE ;
          }
     return FALSE ;
     }

BOOL FAR PASCAL AbortProc (HDC hdcPrn, short nCode)
     {
     MSG   msg ;

     while (!bUserAbort && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
          {
          if (!hDlgPrint || !IsDialogMessage (hDlgPrint, &msg))
               {
               TranslateMessage (&msg) ;
               DispatchMessage (&msg) ;
               }
          }
     return !bUserAbort ;
     }

BOOL PrintMyPage (HWND hwnd)
     {
     static char szSpMsg [] = "Print4: Printing" ;
     static char szText  [] = "Hello Printer!" ;
     ABORTPROC   lpfnAbortProc ;
     BOOL        bError = FALSE ;
     DWORD       dwExtent ;
     FARPROC     lpfnPrintDlgProc ;
     HDC         hdcPrn ;
     POINT       ptExtent ;
     RECT        rect ;
     short       xPage, yPage ;

     if (NULL == (hdcPrn = GetPrinterDC ()))
          return TRUE ;

     xPage = GetDeviceCaps (hdcPrn, HORZRES) ;
     yPage = GetDeviceCaps (hdcPrn, VERTRES) ;

     EnableWindow (hwnd, FALSE) ;

     bUserAbort = FALSE ;
     lpfnPrintDlgProc = MakeProcInstance (PrintDlgProc, hInst) ;
     hDlgPrint = CreateDialog (hInst, "PrintDlgBox", hwnd, lpfnPrintDlgProc)

     lpfnAbortProc = MakeProcInstance (AbortProc, hInst) ;
     Escape (hdcPrn, SETABORTPROC, 0, (LPSTR) lpfnAbortProc, NULL) ;

     if (Escape (hdcPrn, STARTDOC, sizeof szSpMsg - 1, szSpMsg, NULL) > 0 &&
         Escape (hdcPrn, NEXTBAND, 0, NULL, (LPSTR) &rect) > 0)
          {
          while (!IsRectEmpty (&rect) && !bUserAbort)
               {
               (*lpfnAbortProc) (hdcPrn, 0) ;

               Rectangle (hdcPrn, rect.left, rect.top, rect.right,
                                                       rect.bottom) ;
               (*lpfnAbortProc) (hdcPrn, 0) ;

               MoveTo (hdcPrn, 0, 0) ;
               LineTo (hdcPrn, xPage, yPage) ;

               (*lpfnAbortProc) (hdcPrn, 0) ;

               MoveTo (hdcPrn, xPage, 0) ;
               LineTo (hdcPrn, 0, yPage) ;

               SaveDC (hdcPrn) ;

               SetMapMode (hdcPrn, MM_ISOTROPIC) ;
               SetWindowExt   (hdcPrn, 1000, 1000) ;
               SetViewportExt (hdcPrn, xPage / 2, -yPage / 2) ;
               SetViewportOrg (hdcPrn, xPage / 2,  yPage / 2) ;

               (*lpfnAbortProc) (hdcPrn, 0) ;

               Ellipse (hdcPrn, -500, 500, 500, -500) ;

               (*lpfnAbortProc) (hdcPrn, 0) ;

               dwExtent = GetTextExtent (hdcPrn, szText, sizeof szText - 1) ;
               ptExtent = MAKEPOINT (dwExtent) ;
               TextOut (hdcPrn, -ptExtent.x / 2, ptExtent.y / 2, szText,
                                                  sizeof szText - 1) ;

               RestoreDC (hdcPrn, -1) ;

               (*lpfnAbortProc) (hdcPrn, 0) ;

               if (Escape (hdcPrn, NEXTBAND, 0, NULL, (LPSTR) &rect) < 0)
                    {
                    bError = TRUE ;
                    break ;
                    }
               }
          }
     else
          bError = TRUE ;

     if (!bError)
          {
          if (bUserAbort)
               Escape (hdcPrn, ABORTDOC, 0, NULL, NULL) ;
          else
               Escape (hdcPrn, ENDDOC, 0, NULL, NULL) ;
          }

     if (!bUserAbort)
          {
          EnableWindow (hwnd, TRUE) ;
          DestroyWindow (hDlgPrint) ;
          }

     FreeProcInstance (lpfnPrintDlgProc) ;
     FreeProcInstance (lpfnAbortProc) ;
     DeleteDC (hdcPrn) ;

     return bError || bUserAbort ;
     }


RANDRECT.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP12\RANDRECT.C

/*------------------------------------------
   RANDRECT.C -- Displays Random Rectangles
                 (c) Charles Petzold, 1990
  ------------------------------------------*/

#include <windows.h>
#include <stdlib.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;
void DrawRectangle (HWND) ;

short cxClient, cyClient ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "RandRect" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          !RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Random Rectangles",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

     while (TRUE)
          {
          if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
               {
               if (msg.message == WM_QUIT)
                    break ;

               TranslateMessage (&msg) ;
               DispatchMessage (&msg) ;
               }
          else
               DrawRectangle (hwnd) ;
          }
     return msg.wParam ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     switch (message)
          {
          case WM_SIZE:
               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }

void DrawRectangle (HWND hwnd)
     {
     HBRUSH hBrush ;
     HDC    hdc ;
     short  xLeft, xRight, yTop, yBottom, nRed, nGreen, nBlue ;

     xLeft   = rand () % cxClient ;
     xRight  = rand () % cxClient ;
     yTop    = rand () % cyClient ;
     yBottom = rand () % cyClient ;
     nRed    = rand () & 255 ;
     nGreen  = rand () & 255 ;
     nBlue   = rand () & 255 ;

     hdc = GetDC (hwnd) ;
     hBrush = CreateSolidBrush (RGB (nRed, nGreen, nBlue)) ;
     SelectObject (hdc, hBrush) ;

     Rectangle (hdc, min (xLeft, xRight), min (yTop, yBottom),
                     max (xLeft, xRight), max (yTop, yBottom)) ;

     ReleaseDC (hwnd, hdc) ;
     DeleteObject (hBrush) ;
     }


RESOURC1.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP08\RESOURC1.C

/*-----------------------------------------------------------
   RESOURC1.C -- Icon and Cursor Demonstration Program No. 1
                 (c) Charles Petzold, 1990
  -----------------------------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc  (HWND, WORD, WORD, LONG) ;

char   szAppName [] = "Resourc1" ;
HANDLE hInst ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (hInstance, szAppName) ;
          wndclass.hbrBackground = COLOR_WINDOW + 1 ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hInst = hInstance ;

     hwnd = CreateWindow (szAppName, "Icon and Cursor Demo",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HICON hIcon ;
     static short cxIcon, cyIcon, cxClient, cyClient ;
     HDC          hdc ;
     RECT         rect ;
     PAINTSTRUCT  ps ;
     short        x, y ;

     switch (message)
          {
          case WM_CREATE:
               hIcon = LoadIcon (hInst, szAppName) ;
               cxIcon = GetSystemMetrics (SM_CXICON) ;
               cyIcon = GetSystemMetrics (SM_CYICON) ;
               return 0 ;

          case WM_SIZE:
               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               for (y = cyIcon ; y < cyClient ; y += 2 * cyIcon)
                    for (x = cxIcon ; x < cxClient ; x += 2 * cxIcon)
                         DrawIcon (hdc, x, y, hIcon) ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


RESOURC2.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP08\RESOURC2.C

/*-----------------------------------------------------------
   RESOURC2.C -- Icon and Cursor Demonstration Program No. 2
                 (c) Charles Petzold, 1990
  -----------------------------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc  (HWND, WORD, WORD, LONG) ;

char   szAppName[] = "Resourc2" ;
HANDLE hInst ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HBITMAP  hBitmap ;
     HBRUSH   hBrush ;
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     hBitmap = LoadBitmap (hInstance, szAppName) ;
     hBrush = CreatePatternBrush (hBitmap) ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (hInstance, szAppName) ;
          wndclass.hbrBackground = hBrush ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hInst = hInstance ;

     hwnd = CreateWindow (szAppName, "Icon and Cursor Demo",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

     DeleteObject (hBrush) ;       // clean-up
     DeleteObject (hBitmap) ;

     return msg.wParam ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HICON hIcon ;
     static short cxIcon, cyIcon, cxClient, cyClient ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     RECT         rect ;
     short        x, y ;

     switch (message)
          {
          case WM_CREATE:
               hIcon = LoadIcon (hInst, szAppName) ;
               cxIcon = GetSystemMetrics (SM_CXICON) ;
               cyIcon = GetSystemMetrics (SM_CYICON) ;
               return 0 ;

          case WM_SIZE:
               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               for (y = cyIcon ; y < cyClient ; y += 2 * cyIcon)
                    for (x = cxIcon ; x < cxClient ; x += 2 * cxIcon)
                         DrawIcon (hdc, x, y, hIcon) ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


ROP2LOOK.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP12\ROP2LOOK.C

/*------------------------------------------
   ROP2LOOK.C -- ROP2 Demonstration Program
                 (c) Charles Petzold, 1990
  ------------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Rop2Look" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "ROP2 Demonstration Program",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static LOGPEN lpBlack = { PS_SOLID, 1, 1, RGB (  0,   0,   0) },
                   lpWhite = { PS_SOLID, 1, 1, RGB (255, 255, 255) } ;
     static short  nDrawingMode = R2_COPYPEN ;
     HDC           hdc ;
     HMENU         hMenu ;
     HPEN          hPenBlack, hPenWhite ;
     PAINTSTRUCT   ps ;
     RECT          rect ;
     short         i ;

     switch (message)
          {
          case WM_COMMAND:
               hMenu = GetMenu (hwnd) ;
               CheckMenuItem (hMenu, nDrawingMode, MF_UNCHECKED) ;
               nDrawingMode = wParam ;
               CheckMenuItem (hMenu, nDrawingMode, MF_CHECKED) ;
               InvalidateRect (hwnd, NULL, FALSE) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               hPenBlack = CreatePenIndirect (&lpBlack) ;
               hPenWhite = CreatePenIndirect (&lpWhite) ;

               SetMapMode (hdc, MM_ANISOTROPIC) ;
               GetClientRect (hwnd, &rect) ;
               SetViewportExt (hdc, rect.right, rect.bottom) ;
               SetWindowExt (hdc, 10, 4) ;

               for (i = 0 ; i < 10 ; i += 2)
                    {
                    SetRect (&rect, i, 0, i + 2, 4) ;
                    FillRect (hdc, &rect, GetStockObject (i / 2)) ;
                    }
               SetROP2 (hdc, nDrawingMode) ;

               SelectObject (hdc, hPenWhite) ;
               MoveTo (hdc, 1, 1) ;
               LineTo (hdc, 9, 1) ;

               SelectObject (hdc, hPenBlack) ;
               MoveTo (hdc, 1, 3) ;
               LineTo (hdc, 9, 3) ;

               EndPaint (hwnd, &ps) ;

               DeleteObject (hPenBlack) ;
               DeleteObject (hPenWhite) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


SCRAMBLE.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP13\SCRAMBLE.C

/*------------------------------------------------
   SCRAMBLE.C -- Scramble (and Unscramble) Screen
                 (c) Charles Petzold, 1990
  ------------------------------------------------*/

#include <windows.h>
#include <stdlib.h>
#define   NUM  200

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static short nKeep [NUM][4] ;
     HDC          hdc     = CreateDC ("DISPLAY", NULL, NULL, NULL) ;
     HDC          hdcMem  = CreateCompatibleDC (hdc) ;
     short        cxSize  = GetSystemMetrics (SM_CXSCREEN) / 10 ;
     short        cySize  = GetSystemMetrics (SM_CYSCREEN) / 10 ;
     HBITMAP      hBitmap = CreateCompatibleBitmap (hdc, cxSize, cySize) ;
     short        i, j, x1, y1, x2, y2 ;

     SelectObject (hdcMem, hBitmap) ;

     srand (LOWORD (GetCurrentTime ())) ;

     for (i = 0 ; i < 2 ; i++)
          for (j = 0 ; j < NUM ; j++)
               {
               if (i == 0)
                    {
                    nKeep [j] [0] = x1 = cxSize * (rand () % 10) ;
                    nKeep [j] [1] = y1 = cySize * (rand () % 10) ;
                    nKeep [j] [2] = x2 = cxSize * (rand () % 10) ;
                    nKeep [j] [3] = y2 = cySize * (rand () % 10) ;
                    }
               else
                    {
                    x1 = nKeep [NUM - 1 - j] [0] ;
                    y1 = nKeep [NUM - 1 - j] [1] ;
                    x2 = nKeep [NUM - 1 - j] [2] ;
                    y2 = nKeep [NUM - 1 - j] [3] ;
                    }
               BitBlt (hdcMem, 0, 0, cxSize, cySize, hdc,  x1, y1, SRCCOPY) ;
               BitBlt (hdc,  x1, y1, cxSize, cySize, hdc,  x2, y2, SRCCOPY) ;
               BitBlt (hdc,  x2, y2, cxSize, cySize, hdcMem, 0, 0, SRCCOPY) ;
               }
     return FALSE ;
     }


SHOWBIT.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP19\SHOWBIT.C

/*-----------------------------------------------------------
   SHOWBIT.C -- Shows bitmaps in BITLIB dynamic link library
                (c) Charles Petzold, 1990
  -----------------------------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static   char szAppName [] = "ShowBit" ;
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Show Bitmaps from BITLIB (Press Key)",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

void DrawBitmap (HDC hdc, short xStart, short yStart, HBITMAP hBitmap)
     {
     BITMAP bm ;
     DWORD  dwSize ;
     HDC    hMemDC ;
     POINT  pt ;

     hMemDC = CreateCompatibleDC (hdc) ;
     SelectObject (hMemDC, hBitmap) ;
     GetObject (hBitmap, sizeof (BITMAP), (LPSTR) &bm) ;
     pt.x = bm.bmWidth ;
     pt.y = bm.bmHeight ;

     BitBlt (hdc, xStart, yStart, pt.x, pt.y, hMemDC, 0, 0, SRCCOPY) ;

     DeleteDC (hMemDC) ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static HANDLE hLibrary ;
     static short  nCurrent = 1 ;
     HANDLE        hBitmap ;
     HDC           hdc ;
     PAINTSTRUCT   ps ;

     switch (message)
          {
          case WM_CREATE:
               if ((hLibrary = LoadLibrary ("BITLIB.DLL")) < 32)
                    MessageBeep (0) ;

               return 0 ;

          case WM_CHAR:
               if (hLibrary >= 32)
                    {
                    nCurrent ++ ;
                    InvalidateRect (hwnd, NULL, TRUE) ;
                    }
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               if (hLibrary >= 32)
                    {
                    if (NULL == (hBitmap = LoadBitmap (hLibrary,
                                             MAKEINTRESOURCE (nCurrent))))
                         {
                         nCurrent = 1 ;
                         hBitmap = LoadBitmap (hLibrary,
                                             MAKEINTRESOURCE (nCurrent)) ;
                         }

                    if (hBitmap)
                         DrawBitmap (hdc, 0, 0, hBitmap) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               if (hLibrary >= 32)
                    FreeLibrary (hLibrary) ;

               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


SHOWPOP.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP17\SHOWPOP.C

/*----------------------------------------
   SHOWPOP.C -- DDE Client using DDEPOP
                (c) Charles Petzold, 1990
  ----------------------------------------*/

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

struct
     {
     char *szAbb ;
     char *szState ;
     long lPop ;
     }
     pop [] = {
              "AL", "Alabama",             0, "AK", "Alaska",              0,
              "AZ", "Arizona",             0, "AR", "Arkansas",            0,
              "CA", "California",          0, "CO", "Colorado",            0,
              "CT", "Connecticut",         0, "DE", "Delaware",            0,
              "DC", "Dist. of Columbia",   0, "FL", "Florida",             0,
              "GA", "Georgia",             0, "HI", "Hawaii",              0,
              "ID", "Idaho",               0, "IL", "Illinois",            0,
              "IN", "Indiana",             0, "IA", "Iowa",                0,
              "KS", "Kansas",              0, "KY", "Kentucky",            0,
              "LA", "Louisiana",           0, "ME", "Maine",               0,
              "MD", "Maryland",            0, "MA", "Massachusetts",       0,
              "MI", "Michigan",            0, "MN", "Minnesota",           0,
              "MS", "Mississippi",         0, "MO", "Missouri",            0,
              "MT", "Montana",             0, "NE", "Nebraska",            0,
              "NV", "Nevada",              0, "NH", "New Hampshire",       0,
              "NJ", "New Jersey",          0, "NM", "New Mexico",          0,
              "NY", "New York",            0, "NC", "North Carolina",      0,
              "ND", "North Dakota",        0, "OH", "Ohio",                0,
              "OK", "Oklahoma",            0, "OR", "Oregon",              0,
              "PA", "Pennsylvania",        0, "RI", "Rhode Island",        0,
              "SC", "South Carolina",      0, "SD", "South Dakota",        0,
              "TN", "Tennessee",           0, "TX", "Texas",               0,
              "UT", "Utah",                0, "VT", "Vermont",             0,
              "VA", "Virginia",            0, "WA", "Washington",          0,
              "WV", "West Virginia",       0, "WI", "Wisconsin",           0,
              "WY", "Wyoming",             0, "US", "United States Total", 0
              } ;

#define NUM_STATES       (sizeof (pop) / sizeof (pop [0]))
#define WM_USER_INITIATE (WM_USER + 1)
#define DDE_TIMEOUT      3000

long FAR PASCAL WndProc  (HWND, WORD, WORD, LONG) ;

char   szAppName [] = "ShowPop" ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "DDE Client - US Population",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

     SendMessage (hwnd, WM_USER_INITIATE, 0, 0L) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static BOOL   fDoingInitiate = TRUE ;
     static char   szServerApp [] = "DdePop",
                   szTopic     [] = "US_Population" ;
     static HWND   hwndServer = NULL ;
     static short  cxChar, cyChar ;
     ATOM          aApp, aTop, aItem ;
     char          szBuffer [24], szPopulation [16], szItem [16] ;
     DDEACK        DdeAck ;
     DDEDATA FAR   *lpDdeData ;
     DDEADVISE FAR *lpDdeAdvise ;
     DWORD         dwTime ;
     GLOBALHANDLE  hDdeAdvise, hDdeData ;
     HDC           hdc ;
     MSG           msg ;
     PAINTSTRUCT   ps ;
     short         i, x, y ;
     TEXTMETRIC    tm ;
     WORD          wStatus, cfFormat ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;
               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;
               ReleaseDC (hwnd, hdc) ;
               return 0 ;

          case WM_USER_INITIATE:

                     // Broadcast WM_DDE_INITIATE message

               aApp = GlobalAddAtom (szServerApp) ;
               aTop = GlobalAddAtom (szTopic) ;

               SendMessage (0xFFFF, WM_DDE_INITIATE, hwnd,
                            MAKELONG (aApp, aTop)) ;

                     // If no response, try loading DDEPOP first

               if (hwndServer == NULL)
                    {
                    WinExec (szServerApp, SW_SHOWMINNOACTIVE) ;

                    SendMessage (0xFFFF, WM_DDE_INITIATE, hwnd,
                                 MAKELONG (aApp, aTop)) ;
                    }

                    // Delete the atoms

               GlobalDeleteAtom (aApp) ;
               GlobalDeleteAtom (aTop) ;
               fDoingInitiate = FALSE ;

                    // If still no response, display message box

               if (hwndServer == NULL)
                    {
                    MessageBox (hwnd, "Cannot connect with DDEPOP.EXE!",
                                szAppName, MB_ICONEXCLAMATION | MB_OK) ;

                    return 0 ;
                    }

                    // Post WM_DDE_ADVISE messages

               for (i = 0 ; i < NUM_STATES ; i++)
                    {
                    hDdeAdvise = GlobalAlloc (GHND | GMEM_DDESHARE,
                                              sizeof (DDEADVISE)) ;

                    lpDdeAdvise = (DDEADVISE FAR *) GlobalLock (hDdeAdvise) ;

                    lpDdeAdvise->fAckReq   = TRUE ;
                    lpDdeAdvise->fDeferUpd = FALSE ;
                    lpDdeAdvise->cfFormat  = CF_TEXT ;

                    GlobalUnlock (hDdeAdvise) ;

                    aItem = GlobalAddAtom (pop[i].szAbb) ;

                    if (!PostMessage (hwndServer, WM_DDE_ADVISE, hwnd,
                                      MAKELONG (hDdeAdvise, aItem)))
                         {
                         GlobalFree (hDdeAdvise) ;
                         GlobalDeleteAtom (aItem) ;
                         break ;
                         }

                    DdeAck.fAck = FALSE ;

                    dwTime = GetCurrentTime () ;

                    while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
                         {
                         if (PeekMessage (&msg, hwnd, WM_DDE_ACK,
                                          WM_DDE_ACK, PM_REMOVE))
                              {
                              GlobalDeleteAtom (HIWORD (msg.lParam)) ;

                              DdeAck = * (DDEACK *) & LOWORD (msg.lParam);

                              if (DdeAck.fAck == FALSE)
                                   GlobalFree (hDdeAdvise) ;

                              break ;
                              }
                         }

                    if (DdeAck.fAck == FALSE)
                         break ;

                    while (PeekMessage (&msg, hwnd, WM_DDE_FIRST,
                                        WM_DDE_LAST, PM_REMOVE))
                         {
                         DispatchMessage (&msg) ;
                         }
                    }

               if (i < NUM_STATES)
                    {
                    MessageBox (hwnd, "Failure on WM_DDE_ADVISE!",
                                szAppName, MB_ICONEXCLAMATION | MB_OK) ;
                    }
               return 0 ;

          case WM_DDE_ACK:

                    // In response to WM_DDE_INITIATE, save server window

               if (fDoingInitiate)
                    {
                    hwndServer = wParam ;
                    GlobalDeleteAtom (LOWORD (lParam)) ;
                    GlobalDeleteAtom (HIWORD (lParam)) ;
                    }
               return 0 ;

          case WM_DDE_DATA:

                    // wParam          -- sending window handle
                    // LOWORD (lParam) -- DDEDATA memory handle
                    // HIWORD (lParam) -- item atom

               hDdeData  = LOWORD (lParam) ;
               lpDdeData = (DDEDATA FAR *) GlobalLock (hDdeData) ;
               aItem     = HIWORD (lParam) ;

                    // Initialize DdeAck structure

               DdeAck.bAppReturnCode = 0 ;
               DdeAck.reserved       = 0 ;
               DdeAck.fBusy          = FALSE ;
               DdeAck.fAck           = FALSE ;

                    // Check for matching format and data item

               if (lpDdeData->cfFormat == CF_TEXT)
                    {
                    GlobalGetAtomName (aItem, szItem, sizeof (szItem)) ;

                    for (i = 0 ; i < NUM_STATES ; i++)
                         if (strcmp (szItem, pop[i].szAbb) == 0)
                              break ;

                    if (i < NUM_STATES)
                         {
                         lstrcpy (szPopulation, lpDdeData->Value) ;
                         pop[i].lPop = atol (szPopulation) ;
                         InvalidateRect (hwnd, NULL, FALSE) ;

                         DdeAck.fAck = TRUE ;
                         }
                    }

                    // Acknowledge if necessary

               if (lpDdeData->fAckReq == TRUE)
                    {
                    wStatus = * (WORD *) & DdeAck ;

                    if (!PostMessage (wParam, WM_DDE_ACK, hwnd,
                                      MAKELONG (wStatus, aItem)))
                         {
                         GlobalDeleteAtom (aItem) ;
                         GlobalUnlock (hDdeData) ;
                         GlobalFree (hDdeData) ;
                         return 0 ;
                         }
                    }
               else
                    {
                    GlobalDeleteAtom (aItem) ;
                    }

                    // Clean up

               if (lpDdeData->fRelease == TRUE || DdeAck.fAck == FALSE)
                    {
                    GlobalUnlock (hDdeData) ;
                    GlobalFree (hDdeData) ;
                    }
               else
                    {
                    GlobalUnlock (hDdeData) ;
                    }

               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               for (i = 0 ; i < NUM_STATES ; i++)
                    {
                    if (i < (NUM_STATES + 1) / 2)
                         {
                         x = cxChar ;
                         y = i * cyChar ;
                         }
                    else
                         {
                         x = 44 * cxChar ;
                         y = (i - (NUM_STATES + 1) / 2) * cyChar ;
                         }

                    TextOut (hdc, x, y, szBuffer,
                             wsprintf (szBuffer, "%-20s",
                                       (LPSTR) pop[i].szState)) ;

                    x += 36 * cxChar ;

                    SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;

                    TextOut (hdc, x, y, szBuffer,
                             wsprintf (szBuffer, "%10ld", pop[i].lPop)) ;

                    SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DDE_TERMINATE:

                    // Respond with another WM_DDE_TERMINATE message

               PostMessage (hwndServer, WM_DDE_TERMINATE, hwnd, 0L) ;
               hwndServer = NULL ;
               return 0 ;

          case WM_CLOSE:
               if (hwndServer == NULL)
                    break ;

                    // Post WM_DDE_UNADVISE message

               PostMessage (hwndServer, WM_DDE_UNADVISE, hwnd,
                            MAKELONG (CF_TEXT, NULL)) ;

               dwTime = GetCurrentTime () ;

               while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
                    {
                    if (PeekMessage (&msg, hwnd, WM_DDE_ACK,
                                     WM_DDE_ACK, PM_REMOVE))
                         break ;
                    }

                    // Post WM_DDE_TERMINATE message

               PostMessage (hwndServer, WM_DDE_TERMINATE, hwnd, 0L) ;

               dwTime = GetCurrentTime () ;

               while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
                    {
                    if (PeekMessage (&msg, hwnd, WM_DDE_TERMINATE,
                                     WM_DDE_TERMINATE, PM_REMOVE))
                         break ;
                    }

               break ;             // for default processing

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


STRLIB.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP19\STRLIB.C

/*------------------------------------------------
   STRLIB.C -- Library module for STRPROG program
               (c) Charles Petzold,  1990
  ------------------------------------------------*/

#include <windows.h>

typedef BOOL FAR PASCAL GETSTR (LPSTR, LPSTR) ;
HANDLE hStrings [256] ;
short  nTotal = 0 ;

int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg, WORD wHeapSize,
                        LPSTR lpszCmdLine)
     {
     if (wHeapSize > 0)
          UnlockData (0) ;

     return 1 ;
     }

BOOL FAR PASCAL AddString (LPSTR lpStringIn)
     {
     HANDLE hString ;
     NPSTR  npString ;
     short  i, nLength, nCompare ;

     if (nTotal == 255)
          return FALSE ;

     if (0 == (nLength = lstrlen (lpStringIn)))
          return FALSE ;

     if (NULL == (hString = LocalAlloc (LHND, 1 + nLength)))
          return FALSE ;

     npString = LocalLock (hString) ;
     lstrcpy (npString, lpStringIn) ;
     AnsiUpper (npString) ;
     LocalUnlock (hString) ;

     for (i = nTotal ; i > 0 ; i--)
          {
          npString = LocalLock (hStrings [i - 1]) ;
          nCompare = lstrcmpi (lpStringIn, npString) ;
          LocalUnlock (hStrings [i - 1]) ;

          if (nCompare > 0)
               {
               hStrings [i] = hString ;
               break ;
               }
          hStrings [i] = hStrings [i - 1] ;
          }

     if (i == 0)
          hStrings [0] = hString ;

     nTotal++ ;
     return TRUE ;
     }

BOOL FAR PASCAL DeleteString (LPSTR lpStringIn)
     {
     NPSTR npString ;
     short i, j, nCompare ;

     if (0 == lstrlen (lpStringIn))
          return FALSE ;

     for (i = 0 ; i < nTotal ; i++)
          {
          npString = LocalLock (hStrings [i]) ;
          nCompare = lstrcmpi (npString, lpStringIn) ;
          LocalUnlock (hStrings [i]) ;

          if (nCompare == 0)
               break ;
          }

     if (i == nTotal)
          return FALSE ;

     for (j = i ; j < nTotal ; j++)
          hStrings [j] = hStrings [j + 1] ;

     nTotal-- ;
     return TRUE ;
     }

short FAR PASCAL GetStrings (GETSTR lpfnGetStrCallBack, LPSTR lpParam)
     {
     BOOL  bReturn ;
     NPSTR npString ;
     short i ;

     for (i = 0 ; i < nTotal ; i++)
          {
          npString = LocalLock (hStrings [i]) ;
          bReturn = (*lpfnGetStrCallBack) ((LPSTR) npString, lpParam) ;
          LocalUnlock (hStrings [i]) ;

          if (bReturn == FALSE)
               return i + 1 ;
          }
     return nTotal ;
     }


STRPROG.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP19\STRPROG.C

/*--------------------------------------------------------
   STRPROG.C -- Program using STRLIB dynamic link library
                (c) Charles Petzold, 1990
  --------------------------------------------------------*/

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

#define MAXLEN 32
#define WM_DATACHANGE WM_USER

typedef struct
     {
     HDC   hdc ;
     short xText ;
     short yText ;
     short xStart ;
     short yStart ;
     short xIncr ;
     short yIncr ;
     short xMax ;
     short yMax ;
     }
     CBPARM ;

BOOL  FAR PASCAL AddString    (LPSTR) ;      // functions in STRLIB
BOOL  FAR PASCAL DeleteString (LPSTR) ;
short FAR PASCAL GetStrings   (FARPROC, CBPARM FAR *) ;

long  FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

char  szAppName [] = "StrProg" ;
char  szString  [MAXLEN] ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "DLL Demonstration Program",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

BOOL FAR PASCAL DlgProc (HWND hDlg, WORD message, WORD wParam, LONG lParam)
     {
     switch (message)
          {
          case WM_INITDIALOG:
               SendDlgItemMessage (hDlg, IDD_STRING, EM_LIMITTEXT,
                                   MAXLEN - 1, 0L);
               return TRUE ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDOK:
                         GetDlgItemText (hDlg, IDD_STRING, szString, MAXLEN)
                         EndDialog (hDlg, TRUE) ;
                         return TRUE ;

                    case IDCANCEL:
                         EndDialog (hDlg, FALSE) ;
                         return TRUE ;
                    }
          }
     return FALSE ;
     }

BOOL FAR PASCAL EnumCallBack (HWND hwnd, LONG lParam)
     {
     char szClassName [16] ;

     GetClassName (hwnd, szClassName, sizeof szClassName) ;

     if (0 == strcmp (szClassName, szAppName))
          SendMessage (hwnd, WM_DATACHANGE, 0, 0L) ;

     return TRUE ;
     }

BOOL FAR PASCAL GetStrCallBack (LPSTR lpString, CBPARM FAR *lpcbp)
     {
     TextOut (lpcbp->hdc, lpcbp->xText, lpcbp->yText,
              lpString, lstrlen (lpString)) ;

     if ((lpcbp->yText += lpcbp->yIncr) > lpcbp->yMax)
          {
          lpcbp->yText = lpcbp->yStart ;
          if ((lpcbp->xText += lpcbp->xIncr) > lpcbp->xMax)
               return FALSE ;
          }
     return TRUE ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static FARPROC lpfnDlgProc, lpfnGetStrCallBack, lpfnEnumCallBack ;
     static HANDLE  hInst ;
     static short   cxChar, cyChar, cxClient, cyClient ;
     CBPARM         cbparam ;
     HDC            hdc ;
     PAINTSTRUCT    ps ;
     TEXTMETRIC     tm ;

     switch (message)
          {
          case WM_CREATE:
               hInst = ((LPCREATESTRUCT) lParam)->hInstance ;

               lpfnDlgProc        = MakeProcInstance (DlgProc, hInst) ;
               lpfnGetStrCallBack = MakeProcInstance (GetStrCallBack, hInst)
               lpfnEnumCallBack   = MakeProcInstance (EnumCallBack, hInst) ;

               hdc = GetDC (hwnd) ;
               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;
               ReleaseDC (hwnd, hdc) ;

               return 0 ;

          case WM_COMMAND:
               switch (wParam)
                    {
                    case IDM_ENTER:
                         if (DialogBox (hInst, "EnterDlg", hwnd, lpfnDlgProc)
                              {
                              if (AddString (szString))
                                   EnumWindows (lpfnEnumCallBack, 0L) ;
                              else
                                   MessageBeep (0) ;
                              }
                         break ;

                    case IDM_DELETE:
                         if (DialogBox (hInst, "DeleteDlg", hwnd, lpfnDlgProc
                              {
                              if (DeleteString (szString))
                                   EnumWindows (lpfnEnumCallBack, 0L) ;
                              else
                                   MessageBeep (0) ;
                              }
                         break ;
                    }
               return 0 ;

          case WM_SIZE:
               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;
               return 0 ;

          case WM_DATACHANGE:
               InvalidateRect (hwnd, NULL, TRUE) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               cbparam.hdc   = hdc ;
               cbparam.xText = cbparam.xStart = cxChar ;
               cbparam.yText = cbparam.yStart = cyChar ;
               cbparam.xIncr = cxChar * MAXLEN ;
               cbparam.yIncr = cyChar ;
               cbparam.xMax  = cbparam.xIncr * (1 + cxClient / cbparam.xIncr)
               cbparam.yMax  = cyChar * (cyClient / cyChar - 1) ;

               GetStrings (lpfnGetStrCallBack, &cbparam) ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


SYSMETS.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP03\SYSMETS.C

/*-----------------------------------------------------
   SYSMETS.C -- System Metrics Display Program (Final)
                (c) Charles Petzold, 1990
  -----------------------------------------------------*/

#include <windows.h>
#include "sysmets.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "SysMets" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "System Metrics",
                          WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static short  cxChar, cxCaps, cyChar, cxClient, cyClient, nMaxWidth,
                   nVscrollPos, nVscrollMax, nHscrollPos, nHscrollMax ;
     char          szBuffer[10] ;
     HDC           hdc ;
     short         i, x, y, nPaintBeg, nPaintEnd, nVscrollInc, nHscrollInc ;
     PAINTSTRUCT   ps ;
     TEXTMETRIC    tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;

               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;

               ReleaseDC (hwnd, hdc) ;

               nMaxWidth = 40 * cxChar + 18 * cxCaps ;
               return 0 ;

          case WM_SIZE:
               cyClient = HIWORD (lParam) ;
               cxClient = LOWORD (lParam) ;

         nVscrollMax = max (0, NUMLINES + 2 - cyClient / cyChar) ;
               nVscrollPos = min (nVscrollPos, nVscrollMax) ;

               SetScrollRange (hwnd, SB_VERT, 0, nVscrollMax, FALSE) ;
               SetScrollPos   (hwnd, SB_VERT, nVscrollPos, TRUE) ;

         nHscrollMax = max (0, 2 + (nMaxWidth - cxClient) / cxChar) ;
               nHscrollPos = min (nHscrollPos, nHscrollMax) ;

               SetScrollRange (hwnd, SB_HORZ, 0, nHscrollMax, FALSE) ;
               SetScrollPos   (hwnd, SB_HORZ, nHscrollPos, TRUE) ;
               return 0 ;

          case WM_VSCROLL:
               switch (wParam)
                    {
                    case SB_TOP:
                         nVscrollInc = -nVscrollPos ;
                         break ;

                    case SB_BOTTOM:
                         nVscrollInc = nVscrollMax - nVscrollPos ;
                         break ;

                    case SB_LINEUP:
                         nVscrollInc = -1 ;
                         break ;

                    case SB_LINEDOWN:
                         nVscrollInc = 1 ;
                         break ;

                    case SB_PAGEUP:
                         nVscrollInc = min (-1, -cyClient / cyChar) ;
                         break ;

                    case SB_PAGEDOWN:
                         nVscrollInc = max (1, cyClient / cyChar) ;
                         break ;

                    case SB_THUMBTRACK:
                         nVscrollInc = LOWORD (lParam) - nVscrollPos ;
                         break ;

                    default:
                         nVscrollInc = 0 ;
                    }
               if (nVscrollInc = max (-nVscrollPos,
                         min (nVscrollInc, nVscrollMax - nVscrollPos)))
                    {
                    nVscrollPos += nVscrollInc ;
                    ScrollWindow (hwnd, 0, -cyChar * nVscrollInc, NULL, NULL)
                    SetScrollPos (hwnd, SB_VERT, nVscrollPos, TRUE) ;
                    UpdateWindow (hwnd) ;
                    }
               return 0 ;

          case WM_HSCROLL:
               switch (wParam)
                    {
                    case SB_LINEUP:
                         nHscrollInc = -1 ;
                         break ;

                    case SB_LINEDOWN:
                         nHscrollInc = 1 ;
                         break ;

                    case SB_PAGEUP:
                         nHscrollInc = -8 ;
                         break ;

                    case SB_PAGEDOWN:
                         nHscrollInc = 8 ;
                         break ;

                    case SB_THUMBPOSITION:
                         nHscrollInc = LOWORD (lParam) - nHscrollPos ;
                         break ;

                    default:
                         nHscrollInc = 0 ;
                    }
               if (nHscrollInc = max (-nHscrollPos,
                         min (nHscrollInc, nHscrollMax - nHscrollPos)))
                    {
                    nHscrollPos += nHscrollInc ;
                    ScrollWindow (hwnd, -cxChar * nHscrollInc, 0, NULL, NULL)
                    SetScrollPos (hwnd, SB_HORZ, nHscrollPos, TRUE) ;
                    }
               return 0 ;

          case WM_KEYDOWN:
               switch (wParam)
                    {
                    case VK_HOME:
                         SendMessage (hwnd, WM_VSCROLL, SB_TOP, 0L) ;
                         break ;

                    case VK_END:
                         SendMessage (hwnd, WM_VSCROLL, SB_BOTTOM, 0L) ;
                         break ;

                    case VK_PRIOR:
                         SendMessage (hwnd, WM_VSCROLL, SB_PAGEUP, 0L) ;
                         break ;

                    case VK_NEXT:
                         SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0L) ;
                         break ;

                    case VK_UP:
                         SendMessage (hwnd, WM_VSCROLL, SB_LINEUP, 0L) ;
                         break ;

                    case VK_DOWN:
                         SendMessage (hwnd, WM_VSCROLL, SB_LINEDOWN, 0L) ;
                         break ;

                    case VK_LEFT:
                         SendMessage (hwnd, WM_HSCROLL, SB_PAGEUP, 0L) ;
                         break ;

                    case VK_RIGHT:
                         SendMessage (hwnd, WM_HSCROLL, SB_PAGEDOWN, 0L) ;
                         break ;
                    }
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               nPaintBeg = max (0, nVscrollPos + ps.rcPaint.top / cyChar - 1)
               nPaintEnd = min (NUMLINES,
                                nVscrollPos + ps.rcPaint.bottom / cyChar) ;

               for (i = nPaintBeg ; i < nPaintEnd ; i++)
                    {
                    x = cxChar * (1 - nHscrollPos) ;
                    y = cyChar * (1 - nVscrollPos + i) ;

                    TextOut (hdc, x, y,
                             sysmetrics[i].szLabel,
           lstrlen (sysmetrics[i].szLabel)) ;

                    TextOut (hdc, x + 18 * cxCaps, y,
                             sysmetrics[i].szDesc,
           lstrlen (sysmetrics[i].szDesc)) ;

                    SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;

                    TextOut (hdc, x + 18 * cxCaps + 40 * cxChar, y,
                             szBuffer,
                             wsprintf (szBuffer, "%5d",
          GetSystemMetrics (sysmetrics[i].nIndex))) ;

                    SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }

     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


SYSMETS1.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP02\SYSMETS1.C

/*----------------------------------------------------
   SYSMETS1.C -- System Metrics Display Program No. 1
                 (c) Charles Petzold, 1990
  ----------------------------------------------------*/

#include <windows.h>
#include "sysmets.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "SysMets1" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Get System Metrics No. 1",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static short cxChar, cxCaps, cyChar ;
     char         szBuffer[10] ;
     HDC          hdc ;
     short        i ;
     PAINTSTRUCT  ps ;
     TEXTMETRIC   tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;

               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;

               ReleaseDC (hwnd, hdc) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               for (i = 0 ; i < NUMLINES ; i++)
                    {
        TextOut (hdc, cxChar, cyChar * (1 + i),
                             sysmetrics[i].szLabel,
           lstrlen (sysmetrics[i].szLabel)) ;

        TextOut (hdc, cxChar + 18 * cxCaps, cyChar * (1 + i),
                             sysmetrics[i].szDesc,
           lstrlen (sysmetrics[i].szDesc)) ;

                    SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;

        TextOut (hdc, cxChar + 18 * cxCaps + 40 * cxChar,
           cyChar * (1 + i), szBuffer,
                             wsprintf (szBuffer, "%5d",
          GetSystemMetrics (sysmetrics[i].nIndex))) ;

                    SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }

     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


SYSMETS2.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP02\SYSMETS2.C

/*----------------------------------------------------
   SYSMETS2.C -- System Metrics Display Program No. 2
                 (c) Charles Petzold, 1990
  ----------------------------------------------------*/

#include <windows.h>
#include "sysmets.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "SysMets2" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Get System Metrics No. 2",
                          WS_OVERLAPPEDWINDOW | WS_VSCROLL,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static short cxChar, cxCaps, cyChar, cxClient, cyClient, nVscrollPos ;
     char         szBuffer[10] ;
     HDC          hdc ;
     short        i, y ;
     PAINTSTRUCT  ps ;
     TEXTMETRIC   tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;

               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;

               ReleaseDC (hwnd, hdc) ;

               SetScrollRange (hwnd, SB_VERT, 0, NUMLINES, FALSE) ;
               SetScrollPos   (hwnd, SB_VERT, nVscrollPos, TRUE) ;
               return 0 ;

          case WM_SIZE:
               cyClient = HIWORD (lParam) ;
               cxClient = LOWORD (lParam) ;
               return 0 ;

          case WM_VSCROLL:
               switch (wParam)
                    {
                    case SB_LINEUP:
                         nVscrollPos -= 1 ;
                         break ;

                    case SB_LINEDOWN:
                         nVscrollPos += 1 ;
                         break ;

                    case SB_PAGEUP:
                         nVscrollPos -= cyClient / cyChar ;
                         break ;

                    case SB_PAGEDOWN:
                         nVscrollPos += cyClient / cyChar ;
                         break ;

                    case SB_THUMBPOSITION:
                         nVscrollPos = LOWORD (lParam) ;
                         break ;

                    default:
                         break ;
                    }
               nVscrollPos = max (0, min (nVscrollPos, NUMLINES)) ;

               if (nVscrollPos != GetScrollPos (hwnd, SB_VERT))
                    {
                    SetScrollPos (hwnd, SB_VERT, nVscrollPos, TRUE) ;
                    InvalidateRect (hwnd, NULL, TRUE) ;
                    }
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               for (i = 0 ; i < NUMLINES ; i++)
                    {
                    y = cyChar * (1 - nVscrollPos + i) ;

                    TextOut (hdc, cxChar, y,
                             sysmetrics[i].szLabel,
           lstrlen (sysmetrics[i].szLabel)) ;

                    TextOut (hdc, cxChar + 18 * cxCaps, y,
                             sysmetrics[i].szDesc,
           lstrlen (sysmetrics[i].szDesc)) ;

                    SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;

                    TextOut (hdc, cxChar + 18 * cxCaps + 40 * cxChar, y,
                             szBuffer,
                             wsprintf (szBuffer, "%5d",
          GetSystemMetrics (sysmetrics[i].nIndex))) ;

                    SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }

     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


SYSMETS3.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP02\SYSMETS3.C

/*----------------------------------------------------
   SYSMETS3.C -- System Metrics Display Program No. 3
                 (c) Charles Petzold, 1990
  ----------------------------------------------------*/

#include <windows.h>
#include "sysmets.h"

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "SysMets3" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Get System Metrics No. 3",
                          WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static short cxChar, cxCaps, cyChar, cxClient, cyClient, nMaxWidth,
                  nVscrollPos, nVscrollMax, nHscrollPos, nHscrollMax ;
     char         szBuffer[10] ;
     HDC          hdc ;
     short        i, x, y, nPaintBeg, nPaintEnd, nVscrollInc, nHscrollInc ;
     PAINTSTRUCT  ps ;
     TEXTMETRIC   tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;

               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;

               ReleaseDC (hwnd, hdc) ;

               nMaxWidth = 40 * cxChar + 18 * cxCaps ;
               return 0 ;

          case WM_SIZE:
               cyClient = HIWORD (lParam) ;
               cxClient = LOWORD (lParam) ;

         nVscrollMax = max (0, NUMLINES + 2 - cyClient / cyChar) ;
               nVscrollPos = min (nVscrollPos, nVscrollMax) ;

               SetScrollRange (hwnd, SB_VERT, 0, nVscrollMax, FALSE) ;
               SetScrollPos   (hwnd, SB_VERT, nVscrollPos, TRUE) ;

         nHscrollMax = max (0, 2 + (nMaxWidth - cxClient) / cxChar) ;
               nHscrollPos = min (nHscrollPos, nHscrollMax) ;

               SetScrollRange (hwnd, SB_HORZ, 0, nHscrollMax, FALSE) ;
               SetScrollPos   (hwnd, SB_HORZ, nHscrollPos, TRUE) ;
               return 0 ;

          case WM_VSCROLL:
               switch (wParam)
                    {
                    case SB_TOP:
                         nVscrollInc = -nVscrollPos ;
                         break ;

                    case SB_BOTTOM:
                         nVscrollInc = nVscrollMax - nVscrollPos ;
                         break ;

                    case SB_LINEUP:
                         nVscrollInc = -1 ;
                         break ;

                    case SB_LINEDOWN:
                         nVscrollInc = 1 ;
                         break ;

                    case SB_PAGEUP:
                         nVscrollInc = min (-1, -cyClient / cyChar) ;
                         break ;

                    case SB_PAGEDOWN:
                         nVscrollInc = max (1, cyClient / cyChar) ;
                         break ;

                    case SB_THUMBTRACK:
                         nVscrollInc = LOWORD (lParam) - nVscrollPos ;
                         break ;

                    default:
                         nVscrollInc = 0 ;
                    }
               if (nVscrollInc = max (-nVscrollPos,
                         min (nVscrollInc, nVscrollMax - nVscrollPos)))
                    {
                    nVscrollPos += nVscrollInc ;
                    ScrollWindow (hwnd, 0, -cyChar * nVscrollInc, NULL, NULL)
                    SetScrollPos (hwnd, SB_VERT, nVscrollPos, TRUE) ;
                    UpdateWindow (hwnd) ;
                    }
               return 0 ;

          case WM_HSCROLL:
               switch (wParam)
                    {
                    case SB_LINEUP:
                         nHscrollInc = -1 ;
                         break ;

                    case SB_LINEDOWN:
                         nHscrollInc = 1 ;
                         break ;

                    case SB_PAGEUP:
                         nHscrollInc = -8 ;
                         break ;

                    case SB_PAGEDOWN:
                         nHscrollInc = 8 ;
                         break ;

                    case SB_THUMBPOSITION:
                         nHscrollInc = LOWORD (lParam) - nHscrollPos ;
                         break ;

                    default:
                         nHscrollInc = 0 ;
                    }
               if (nHscrollInc = max (-nHscrollPos,
                         min (nHscrollInc, nHscrollMax - nHscrollPos)))
                    {
                    nHscrollPos += nHscrollInc ;
                    ScrollWindow (hwnd, -cxChar * nHscrollInc, 0, NULL, NULL)
                    SetScrollPos (hwnd, SB_HORZ, nHscrollPos, TRUE) ;
                    }
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;

               nPaintBeg = max (0, nVscrollPos + ps.rcPaint.top / cyChar - 1)
               nPaintEnd = min (NUMLINES,
                                nVscrollPos + ps.rcPaint.bottom / cyChar) ;

               for (i = nPaintBeg ; i < nPaintEnd ; i++)
                    {
                    x = cxChar * (1 - nHscrollPos) ;
                    y = cyChar * (1 - nVscrollPos + i) ;

                    TextOut (hdc, x, y,
                             sysmetrics[i].szLabel,
           lstrlen (sysmetrics[i].szLabel)) ;

                    TextOut (hdc, x + 18 * cxCaps, y,
                             sysmetrics[i].szDesc,
           lstrlen (sysmetrics[i].szDesc)) ;

                    SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;

                    TextOut (hdc, x + 18 * cxCaps + 40 * cxChar, y,
                             szBuffer,
                             wsprintf (szBuffer, "%5d",
          GetSystemMetrics (sysmetrics[i].nIndex))) ;

                    SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
                    }

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }

     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


TYPE.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP03\TYPE.C

/*-------------------------------------
   TYPE.C -- Typing Program
             (c) Charles Petzold, 1990
  -------------------------------------*/

#include <windows.h>
#include <stdlib.h>

#define BUFFER(x,y) *(pBuffer + y * cxBuffer + x)

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "Type" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "Typing Program",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static char *pBuffer = NULL ;
     static int  cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer,
                 xCaret, yCaret ;
     HDC         hdc ;
     int         x, y, i ;
     PAINTSTRUCT ps ;
     TEXTMETRIC  tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;

               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;
               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight ;

               ReleaseDC (hwnd, hdc) ;
               return 0 ;

          case WM_SIZE:
                                   // obtain window size in pixels

               cxClient = LOWORD (lParam) ;
               cyClient = HIWORD (lParam) ;

                                   // calculate window size in characters

               cxBuffer = max (1, cxClient / cxChar) ;
               cyBuffer = max (1, cyClient / cyChar) ;

                                   // allocate memory for buffer and clear it

               if (pBuffer != NULL)
                    free (pBuffer) ;

               if ((LONG) cxBuffer * cyBuffer > 65535L ||
                         (pBuffer = malloc (cxBuffer * cyBuffer)) == NULL)

                    MessageBox (hwnd, "Window too large.  Cannot "
                                      "allocate enough memory.", "Type",
                                MB_ICONEXCLAMATION | MB_OK) ;

               else
                    for (y = 0 ; y < cyBuffer ; y++)
                         for (x = 0 ; x < cxBuffer ; x++)
                              BUFFER(x,y) = ' ' ;

                                   // set caret to upper left corner
               xCaret = 0 ;
               yCaret = 0 ;

               if (hwnd == GetFocus ())
                    SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;

               return 0 ;

          case WM_SETFOCUS:
                                   // create and show the caret

               CreateCaret (hwnd, NULL, cxChar, cyChar) ;
               SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
               ShowCaret (hwnd) ;
               return 0 ;

          case WM_KILLFOCUS:
                                   // hide and destroy the caret
               HideCaret (hwnd) ;
               DestroyCaret () ;
               return 0 ;

          case WM_KEYDOWN:
               switch (wParam)
                    {
                    case VK_HOME:
                         xCaret = 0 ;
                         break ;

                    case VK_END:
                         xCaret = cxBuffer - 1 ;
                         break ;

                    case VK_PRIOR:
                         yCaret = 0 ;
                         break ;

                    case VK_NEXT:
                         yCaret = cyBuffer - 1 ;
                         break ;

                    case VK_LEFT:
                         xCaret = max (xCaret - 1, 0) ;
                         break ;

                    case VK_RIGHT:
                         xCaret = min (xCaret + 1, cxBuffer - 1) ;
                         break ;

                    case VK_UP:
                         yCaret = max (yCaret - 1, 0) ;
                         break ;

                    case VK_DOWN:
                         yCaret = min (yCaret + 1, cyBuffer - 1) ;
                         break ;

                    case VK_DELETE:
                         for (x = xCaret ; x < cxBuffer - 1 ; x++)
                              BUFFER (x, yCaret) = BUFFER (x + 1, yCaret) ;

                         BUFFER (cxBuffer - 1, yCaret) = ' ' ;

                         HideCaret (hwnd) ;
                         hdc = GetDC (hwnd) ;

                         SelectObject (hdc,
                              GetStockObject (SYSTEM_FIXED_FONT)) ;

                         TextOut (hdc, xCaret * cxChar, yCaret * cyChar,
                                  & BUFFER (xCaret, yCaret),
                                  cxBuffer - xCaret) ;

                         ShowCaret (hwnd) ;
                         ReleaseDC (hwnd, hdc) ;
                         break ;
                    }

               SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
               return 0 ;

          case WM_CHAR:
               for (i = 0 ; i < LOWORD (lParam) ; i++)
                    {
                    switch (wParam)
                         {
                         case '\b' :                    // backspace
                              if (xCaret > 0)
                                   {
                                   xCaret-- ;
                                   SendMessage (hwnd, WM_KEYDOWN,
                                                VK_DELETE, 1L) ;
                                   }
                              break ;

                         case '\t' :                    // tab
                              do
                                   {
                                   SendMessage (hwnd, WM_CHAR, ' ', 1L) ;
                                   }
                              while (xCaret % 8 != 0) ;
                              break ;

                         case '\n' :                    // line feed
                              if (++yCaret == cyBuffer)
                                   yCaret = 0 ;
                              break ;

                         case '\r' :                    // carriage return
                              xCaret = 0 ;

                              if (++yCaret == cyBuffer)
                                   yCaret = 0 ;
                              break ;

                         case '\x1B' :                  // escape
                              for (y = 0 ; y < cyBuffer ; y++)
                                   for (x = 0 ; x < cxBuffer ; x++)
                                        BUFFER (x, y) = ' ' ;

                              xCaret = 0 ;
                              yCaret = 0 ;

                              InvalidateRect (hwnd, NULL, FALSE) ;
                              break ;

                         default:                       // character codes
                              BUFFER (xCaret, yCaret) = (char) wParam ;

                              HideCaret (hwnd) ;
                              hdc = GetDC (hwnd) ;

                              SelectObject (hdc,
                                   GetStockObject (SYSTEM_FIXED_FONT)) ;

                              TextOut (hdc, xCaret * cxChar, yCaret * cyChar,
                                       & BUFFER (xCaret, yCaret), 1) ;

                              ShowCaret (hwnd) ;
                              ReleaseDC (hwnd, hdc) ;

                              if (++xCaret == cxBuffer)
                                   {
                                   xCaret = 0 ;

                                   if (++yCaret == cyBuffer)
                                        yCaret = 0 ;
                                   }
                              break ;
                         }
                    }

               SetCaretPos (xCaret * cxChar, yCaret * cyChar) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

               for (y = 0 ; y < cyBuffer ; y++)
                    TextOut (hdc, 0, y * cyChar, & BUFFER(0,y), cxBuffer) ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }


WHATSIZE.C
CD-ROM Disc Path:   \SAMPCODE\PROGWIN\CHAP11\WHATSIZE.C

/*-----------------------------------------
   WHATSIZE.C -- What Size is the Window?
                 (c) Charles Petzold, 1990
  -----------------------------------------*/

#include <windows.h>
#include <stdio.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
     {
     static char szAppName[] = "WhatSize" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASS    wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          RegisterClass (&wndclass) ;
          }

     hwnd = CreateWindow (szAppName, "What Size is the Window?",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, nCmdShow) ;
     UpdateWindow (hwnd) ;

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

void Show (HWND hwnd, HDC hdc, short xText, short yText, short nMapMode,
           char *szMapMode)
     {
     char szBuffer [60] ;
     RECT rect ;

     SaveDC (hdc) ;

     SetMapMode (hdc, nMapMode) ;
     GetClientRect (hwnd, &rect) ;
     DPtoLP (hdc, (LPPOINT) &rect, 2) ;

     RestoreDC (hdc, -1) ;

     TextOut (hdc, xText, yText, szBuffer,
               sprintf (szBuffer, "%-20s %7d %7d %7d %7d", szMapMode,
                    rect.left, rect.right, rect.top, rect.bottom)) ;
     }

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
     {
     static char  szHeading [] =
                    "Mapping Mode            Left   Right     Top  Bottom" ;
     static char  szUndLine [] =
                    "------------            ----   -----     ---  ------" ;
     static short cxChar, cyChar ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     TEXTMETRIC   tm ;

     switch (message)
          {
          case WM_CREATE:
               hdc = GetDC (hwnd) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

               GetTextMetrics (hdc, &tm) ;
               cxChar = tm.tmAveCharWidth ;
               cyChar = tm.tmHeight + tm.tmExternalLeading ;

               ReleaseDC (hwnd, hdc) ;
               return 0 ;

          case WM_PAINT:
               hdc = BeginPaint (hwnd, &ps) ;
               SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;

               SetMapMode (hdc, MM_ANISOTROPIC) ;
               SetWindowExt (hdc, 1, 1) ;
               SetViewportExt (hdc, cxChar, cyChar) ;

               TextOut (hdc, 1, 1, szHeading, sizeof szHeading - 1) ;
               TextOut (hdc, 1, 2, szUndLine, sizeof szUndLine - 1) ;

               Show (hwnd, hdc, 1, 3, MM_TEXT,      "TEXT (pixels)") ;
               Show (hwnd, hdc, 1, 4, MM_LOMETRIC,  "LOMETRIC (.1 mm)") ;
               Show (hwnd, hdc, 1, 5, MM_HIMETRIC,  "HIMETRIC (.01 mm)") ;
               Show (hwnd, hdc, 1, 6, MM_LOENGLISH, "LOENGLISH (.01 in)") ;
               Show (hwnd, hdc, 1, 7, MM_HIENGLISH, "HIENGLISH (.001 in)") ;
               Show (hwnd, hdc, 1, 8, MM_TWIPS,     "TWIPS (1/1440 in)") ;

               EndPaint (hwnd, &ps) ;
               return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
     }




Object Linking & Embedding: Sample `C' Source Code


CLDEMO.C
CD-ROM Disc Path:   \SAMPCODE\OLE\CLIENT\CLDEMO.C

//---------------------------------------------------------------------------
// cldemo.c
//
// Copyright (c) Microsoft Corporation, 1990-
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// include files
//---------------------------------------------------------------------------

#include "windows.h"
#include "ecd.h"
#include "cldemo.h"
#include "client.h"

// ----- constants ---------------------------------------------------------
#define szLessonClass  "Lesson1Class"
#define szItemClass    "ItemClass"
#define szMenuName     "Menu"
#define szTitle        "Client - %s"
#define szDefOpen      "test.cl1"
#define szUntitled     "Untitled"
#define szSave         "Save Changes to %s ?"
#define szInvalidFn    "Invalid file name"
#define szNoFile       "No filename specified."
#define szFnError      "File Error"
#define dxCascade      20
#define dyCascade      20
#define dxInflate      5
#define dyInflate      5
#define cbFnMax        255
#define szMsgMax       100
#define szMaxClassName 20
#define MaxChildWnd     20


// ----- globals -----------------------------------------------------------



HANDLE  hAccTable;
HWND    hwndMain;
POINT   ptAnchor;                // top-left corner of a new window
char    rgchFilename[cbFnMax]; // file's name
char    rgchOpenName[cbFnMax];
BOOL    fDirty = FALSE;   // true if any modification has been made to the fi
WORD    cfLink, cfOwnerLink, cfNative;
HWND  hInst;
HWND  hwndEdit = NULL;
HANDLE hEditBuffer = NULL;
FARPROC lpEditWndProc;
BOOL fInsUpdate = FALSE;
char szInsFileName[cbFnMax];
HWND hUndoitem = NULL;

HWND rgchChildWnd[MaxChildWnd];
int irgchChild = 0;
int nObjDestroy = 0;

// BOOL fObjectClose = FALSE;

extern HANDLE      hObjectUndo;
extern LPECDOBJECT     lpObjectUndo;
extern BOOL            fEcdrelease;
extern BOOL            fEcdReleaseError;
extern BOOL            fEcdReleaseStat;

// ----- Local functions ---------------------------------------------------
BOOL InitApplication (HANDLE hInstance);
BOOL InitInstance (HANDLE hInstance, int nCmdShow);
void TermInstance (void);
void GetFromClipboard (HWND, WORD);
void PutOnClipboard(HWND, WORD);
void ResetAnchor (PPOINT);
void MoveAnchor (PPOINT, PRECT, PPOINT);
void SetNullFilename (HWND);
void SetFilename (HWND, char*);
BOOL SaveAsNeeded (HWND);
BOOL New (HWND);
BOOL Open (HWND);
BOOL Save (HWND);
BOOL SaveAs (HWND);
BOOL WriteToFile (HWND);
BOOL ReadFromFile (HWND, int);
void CleanHwnd (HWND hwnd);
ECDSTATUS CreateObject(WORD wParam, PITEM pitem);
void CallPrint();
void RemoveObjUndo();
void PrintError(ECDSTATUS stat);
void PrintWindowTitle(PITEM pitem, HWND hwnd);

VOID TestEqual();

void PrepareUndoClear(PITEM pitem);
void GetUndo(PITEM pitem);
ECDSTATUS CopyLink(PITEM pCopy);
VOID WaitForRelease(PITEM pitem);
HWND GetTopChild();
HWND GetNextWnd(LPINT i);

long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
long FAR PASCAL ItemWndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL AboutDlgProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL SaveAsDlgProc(HWND, unsigned, WORD, LONG);
int  FAR PASCAL OpenDlgProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL InsFileProc (HWND, unsigned, WORD, LONG);

//---------------------------------------------------------------------------
// WinMain
// Purpose: Wins the Main
//---------------------------------------------------------------------------
int PASCAL
WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow
{
    MSG msg;
  BOOL fMsg;
   hInst = hInstance;

    // initialize the application
  fMsg = SetMessageQueue(32);

    if (!hPrevInstance)
        if (!InitApplication(hInstance))
            return (FALSE);

    // initialize the instance
    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    // initialize the client module
    if (!InitClient (hInstance))
        return FALSE;

    // Main message pump
    while (GetMessage(&msg, NULL, NULL, NULL))
        {
        if (!TranslateAccelerator(hwndMain, hAccTable, &msg))
            {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            }
        }

    // clean up
    TermInstance ();
    TermClient ();

    return (msg.wParam);
}

//---------------------------------------------------------------------------
// CreateItemWindow
// Purpose: Create a window in which we'll put an object
// Returns: handle to the newly created window
//---------------------------------------------------------------------------
HWND CreateItemWindow (HWND hwndParent, BOOL fIconic, LPRECT lprect)
{
    RECT  rc;
    POINT ptSize;

    // Find a window position and size
    // We do all the previous work even if lprect != NULL
    // create the window
    return (CreateWindow(
        szItemClass,
        "",                  // Window Title
        WS_DLGFRAME | WS_CHILD | WS_CLIPSIBLINGS |
          WS_THICKFRAME |  WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX |
      (fIconic ? WS_MINIMIZE : 0),
//          WS_THICKFRAME | (fVisible ? WS_VISIBLE : 0),
        NULL,
        NULL,
        200,
        200,
        hwndParent,
        NULL,
        hInst,
        NULL));
}


//---------------------------------------------------------------------------
// InitApplication
// Purpose: Register windows' classes
// Return: TRUE if successful, FALSE otherwise.
//---------------------------------------------------------------------------
BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  szMenuName;
    wc.lpszClassName = szLessonClass;

    if (!RegisterClass(&wc))
        return FALSE;

    wc.style   = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
    wc.hIcon   =  NULL;
    wc.cbWndExtra = sizeof(HANDLE); // used to store a handle to the window's
                                    //  content
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szItemClass;
    wc.lpfnWndProc   = ItemWndProc;

    if (!RegisterClass(&wc))
        return FALSE;
}



//---------------------------------------------------------------------------
// InitInstance
// Purpose: Create the main window
// Return: TRUE if successful, FALSE otherwise.
//---------------------------------------------------------------------------
BOOL InitInstance(HANDLE hInstance, int nCmdShow)
{

    hAccTable = LoadAccelerators(hInstance, "Accelerators");

    ResetAnchor(&ptAnchor);

    // register clipboard formats.
    cfLink      = RegisterClipboardFormat("ObjectLink");
    cfOwnerLink = RegisterClipboardFormat("OwnerLink");
    cfNative    = RegisterClipboardFormat("Native");

    // Create the main window
    hwndMain = CreateWindow(
        szLessonClass,               // class name
        "",                  // title
        WS_OVERLAPPEDWINDOW,         // style
        CW_USEDEFAULT,               // position: default
        CW_USEDEFAULT,
        CW_USEDEFAULT,               // size: default
        CW_USEDEFAULT,
        NULL,                        // parent: none
        NULL,                        // menu: use the class menu
        hInstance,
        NULL
    );

    if (!hwndMain)
        return (FALSE);

    // This document is Untitled
    SetNullFilename (hwndMain);

    ShowWindow(hwndMain, nCmdShow);
    return (TRUE);
}

//---------------------------------------------------------------------------
// TermInstance
// Purpose:
// Return: void
//---------------------------------------------------------------------------
void TermInstance (void)
{
}

//---------------------------------------------------------------------------
// MainWndProc
// Purpose: Handle the main window's events
//---------------------------------------------------------------------------
long FAR PASCAL
MainWndProc(HWND hwnd, unsigned message, WORD wParam, LONG lParam)
{
    PITEM           pitem;
    HANDLE          hitem;
    PAINTSTRUCT     ps;
    ECDCLIPFORMAT   cfFormat;
   FARPROC lpInsProc;
   RECT rc;
  HDC hDC;
  short mm;
  static BOOL object = 0;
   FARPROC lpProc;
  ECDSTATUS EcdStat;
  HWND hwndItem;


    switch (message)
        {
        case WM_PAINT:
        BeginPaint(hwnd, &ps);
//        CallWindowProc( lpEditWndProc, hwndEdit, message, ps.hdc, 0L);

            EndPaint (hwnd, &ps);
        break;

      case WM_CREATE:  GetClientRect(hwnd, (LPRECT)&rc);
                        break;


      case WM_COMMAND:
            switch (wParam)
                {
                case IDM_COPY:
                case IDM_CUT:
                    PutOnClipboard(hwnd, wParam);
                    if (wParam == IDM_COPY)
                        break;
              else{
                HWND hwndChild;
                PITEM pitem;
                HANDLE hitem;

                hwndChild = GetTopChild();

                hitem = GetWindowWord(hwndChild, 0);
                pitem = (PITEM)LocalLock(hitem);
                EcdDelete(pitem->lpecdobject);
                LocalUnlock(hwndChild);
                DestroyWindow(hwndChild);
                break;
                }

                case IDM_CLEAR:
                    {
                  HWND hwndChild;
            PITEM pitem, pObjectUndo;
            HANDLE hitem;
            hwndChild = GetTopChild();


                  hitem = GetWindowWord(hwndChild, 0);
                  pitem = (PITEM) LocalLock(hitem);
            PrepareUndoClear(pitem);
            LocalUnlock(hitem);
                  DestroyWindow(hwndChild);
                  fDirty = TRUE;
                  break;
                    }

                case IDM_PASTE:
                case IDM_LINK:
                    GetFromClipboard(hwnd, wParam);
              RemoveObjUndo();
                    fDirty = TRUE;
                    break;

                case IDM_PROPERTIES:
                    {
                    HWND    hwndTop;
                    HANDLE  hitem;
                    PITEM   pitem;

                hwndTop = GetTopChild();


                    hitem = GetWindowWord(hwndTop, 0);
                    pitem = (PITEM) LocalLock(hitem);

                    lpProc = MakeProcInstance(PropertiesDlgProc, hInst);
                    DialogBox(hInst,
                        (pitem->wType == IDM_LINK) ? "LinkProp" : "EmbProp",
                        hwnd, lpProc);
                    FreeProcInstance(lpProc);
                    LocalUnlock(hitem);
                    break;
                    }

                case IDM_ABOUT:
                    {
                    FARPROC lpProc;
                    HANDLE  hInst;

                    hInst = GetWindowWord(hwnd, GWW_HINSTANCE);
                    lpProc = MakeProcInstance(AboutDlgProc, hInst);
                    DialogBox(hInst, "AboutBox", hwnd, lpProc);
                    FreeProcInstance(lpProc);
                    break;
                    }

                case IDM_NEW:
                    New(hwnd);
            RemoveObjUndo();
                    break;
           case IDM_INSERTFILE:
            {
            int fh;

                  fh = Insert(hwndMain);
                  if (fh < 0){
                MessageBox(hwndMain,
                          "Error In Insert File",
                          szAppName, MB_ICONASTERISK | MB_OK);
                return FALSE;
                }
                   //Fall through
              }

           case IDM_UNDO:
           case IDM_COPYLINK:
           case IDM_INSERT:
           case IDM_SHAPES:
           case IDM_PBRUSH:
           case IDM_EXCEL:
           case IDM_GRAPH:
           case IDM_TORUS:

            {
            PITEM pitem;
               // Allocate memory for a new item
               hitem = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITE

               if (hitem == NULL || ((pitem = (PITEM)LocalLock (hitem)) == NU
                   goto errRtn;
                }

               if (hwndItem = CreateItemWindow(hwndMain, FALSE, NULL))
                   {
                   SetWindowWord (hwndItem, 0, hitem);
                   BringWindowToTop (hwndItem);
                   }
              else
                   goto errRtn;

            rgchChildWnd[irgchChild++] = hwndItem;
                  SetWindowWord (hwndMain, 0, (GetWindowWord(hwndMain, 0)+1)
              if ((wParam == IDM_UNDO) && hObjectUndo){
                GetUndo(pitem);
                goto Horrible; //dirtiest code
              }
              else
                RemoveObjUndo(); // so nothing left of old object

              if (wParam == IDM_INSERTFILE)
               EcdStat = EcdCreateFromTemplate(PROTOCOL, lpclient, (LPSTR)rgc
                 ecdrender_draw, 0);
              else if (wParam == IDM_COPYLINK){
                EcdStat = CopyLink(pitem);
                }
              else
                EcdStat = CreateObject(wParam, pitem);
              if (EcdStat == ECD_WAIT_FOR_RELEASE){
                WaitForRelease(pitem);
                    }
              if (fTestEcdStat(EcdStat)){
                MessageBox(hwndMain,
                          "Error In EcdCreate",
                          szAppName, MB_ICONASTERISK | MB_OK);
                goto errRtn;
                }
              else {
                    cfFormat = EcdEnumObjectFormats (pitem->lpecdobject, NULL
                   if (cfFormat == cfNative)
                         pitem->wType = IDM_PASTE;
                     else if (cfFormat == cfLink)
                         pitem->wType = IDM_LINK;

                   pitem->wUpdate = IDD_AUTO;
Horrible:
                  pitem->fOpen = FALSE;
                  pitem->fClose = FALSE;

                   hDC = GetDC(hwndItem);
                  //     EcdSetHostNames(pitem->lpecdobject, szHostname, szHo
                  mm = SetMapMode(hDC, MM_HIMETRIC);
                  EcdQueryBounds(pitem->lpecdobject, &rc);
                  LPtoDP(hDC, (LPPOINT)&rc, 2);
                  SetMapMode(hDC, mm);
                  fInsUpdate = TRUE;
                  if ((rc.right - rc.left == 0) || (rc.bottom - rc.top == 0))
                    rc.right = 200;
                    rc.bottom = 200;
                    rc.left = 0;
                    rc.top = 0;
                    }
                  MoveWindow(hwndItem, rc.left, rc.top, rc.right - rc.left,
                    rc.bottom - rc.top, TRUE);
                   SendMessage (hwndItem, WM_USER, 0, 0L);
                   ShowWindow(hwndItem, SW_SHOW);
                    InvalidateRect(hwndItem, NULL, TRUE);
                   ReleaseDC(hwndItem, hDC);

                  }
                    LocalUnlock(hitem);
              break;
              }

                case IDM_OPEN:
                    Open(hwnd);
              RemoveObjUndo(); // so nothing left of old
                    break;

                case IDM_SAVE:
                    Save(hwnd);
                    break;

                case IDM_SAVEAS:
                    SaveAs(hwnd);
                    break;

          case IDM_EQUAL:
              TestEqual();
              break;

                case IDM_EXIT:
                    SendMessage (hwnd, WM_CLOSE, 0, 0L);
                    return(0L);
                    break;
                case IDM_CLOSE:
            {
            HWND hwndTop;
            /*
            hwndTop = GetTopWindow(hwndMain);
            if (hwndTop == hwndEdit)
              hwndTop = GetWindow(hwndTop, GW_HWNDNEXT);
            */
            hwndTop = GetTopChild();

            SendMessage (hwndTop, WM_USER+1, 0, 0L);
                  return(0L);
            }
          case IDM_RECONNECT:
            {
            HWND hwndTop;
            hwndTop = GetTopChild();

            SendMessage (hwndTop, WM_USER+2, 0, 0L);
                  break;
            }

          case IDM_PRINT:
            CallPrint();
            break;
            }
            break;

        case WM_CLOSE:
            if (!SaveAsNeeded(hwnd))
                return(0L);
            break;

        case WM_DESTROY:
      {
      int nObjects;
      HWND hwndT;
      int i = 0;
      MSG msg;

        nObjDestroy = GetWindowWord(hwndMain, 0);
        nObjects = nObjDestroy;
        while (nObjects--){
          hwndT = GetNextWnd(&i);
          DestroyWindow(hwndT);
          }
        while (nObjDestroy){
          GetMessage(&msg, NULL, NULL, NULL);
              TranslateMessage(&msg);
              DispatchMessage(&msg);
              }
            PostQuitMessage (0);
            return(0L);
        }

        case WM_INITMENU:
            ClientUpdateMenu(hwnd, (HMENU) wParam);
            break;

    }
   return (DefWindowProc(hwnd, message, wParam, lParam));

  errRtn:
    if (pitem)
        LocalUnlock (hitem);

    if (hitem)
        LocalFree (hitem);

    if (hwndItem)
        {
        SetWindowWord(hwndItem, 0, NULL);
        DestroyWindow(hwndItem);
        }

}


//---------------------------------------------------------------------------
// ItemWndProc
// Purpose: Handle Item window's messages
//---------------------------------------------------------------------------
long FAR PASCAL
ItemWndProc (HWND hwnd, unsigned message, WORD wParam, LONG lParam)
{
    PITEM           pitem;
    HANDLE          hitem;
   HANDLE        hOldwnd = hwnd;
   static POINT ptOld, ptNew;
   static BOOL bCapture = FALSE;
   static RECT rc;
   int xChange, yChange;
   HWND hNext;
   static int xWnd, yWnd;


    switch (message)
        {
      case WM_USER:
      {
            HANDLE hitem;
            PITEM pitem;
        ECDSTATUS EcdStat;
        HANDLE hWinTitle;
        LPSTR pTitle, pTitle1;

            hitem = GetWindowWord (hwnd, 0);
            pitem = (PITEM) LocalLock (hitem);
        PrintWIndowTitle(pitem ,hwnd);

            LocalUnlock(hitem);
            break;
            }
      case WM_SIZE:
        {
        RECT rc;
        HWND hdc;
        short mm;
        ECDSTATUS EcdStat;

            hitem = GetWindowWord (hwnd, 0);
        if (hitem && (pitem = (PITEM) LocalLock (hitem))){
          if (pitem->fOpen){
            GetClientRect(hwnd, &rc);
                hdc = GetDC(hwnd);
            mm = SetMapMode(hdc, MM_HIMETRIC);
            DPtoLP(hdc,(LPPOINT)&rc,2);
            EcdSetBounds(pitem->lpecdobject, (LPRECT)&rc);
             SetMapMode(hdc, mm);
             ReleaseDC(hwnd, hdc);
            }
            LocalUnlock(hitem);
          }
          return (DefWindowProc(hwnd, message, wParam, lParam));
        }


        case WM_DESTROY:
      {
        int i = 0;
            hitem = GetWindowWord (hwnd, 0);
            if (hitem)
                {
                pitem = (PITEM) LocalLock (hitem);
                ClientDelete(pitem);
                LocalUnlock(hitem);
                LocalFree(hitem);
                }
          while (hwnd != rgchChildWnd[i])
            i += 1;
          if (i > MaxChildWnd){
            MessageBox(hwndMain, "Wrong Child Id",
                         szAppName, MB_ICONASTERISK | MB_OK);
            return;
            }
          rgchChildWnd[i] = 0;
          nObjDestroy -= 1;
              SetWindowWord (hwndMain, 0, (GetWindowWord(hwndMain, 0) - 1) );
            break;
        }

        case WM_PAINT:
            {
            HDC             hdc;
            PAINTSTRUCT     ps;

            BeginPaint (hwnd, (LPPAINTSTRUCT)&ps);
            hitem = GetWindowWord (hwnd, 0);
            pitem = (PITEM) LocalLock (hitem);

            if (pitem)
                ClientPaint(hwnd, ps.hdc, pitem);
            LocalUnlock(hitem);
        hNext = GetWindow(hwnd, GW_HWNDNEXT);
        if (hNext && (hNext != hwndEdit))
          InvalidateRect(hNext, NULL, FALSE);

            EndPaint (hwnd, (LPPAINTSTRUCT)&ps);
            break;
            }


        case WM_LBUTTONDBLCLK:
            {
            HANDLE hitem;
            PITEM pitem;

            // edit the object
            hitem = GetWindowWord (hwnd, 0);
            pitem = (PITEM) LocalLock (hitem);
            ClientEdit(hwnd, pitem);
            LocalUnlock(hitem);
            break;
            }
        case WM_LBUTTONDOWN:
            BringWindowToTop (hwnd);
        SetCapture(hwnd);
        GetCursorPos((LPPOINT)&ptOld);
        bCapture = TRUE;
        break;

      case WM_LBUTTONUP:
        if (bCapture){
          bCapture = FALSE;
          ReleaseCapture();
          GetCursorPos((LPPOINT)&ptNew);
          xChange = ptNew.x - ptOld.x;
          yChange = ptNew.y - ptOld.y;
          GetWindowRect(hwnd, (LPRECT)&rc);
              ScreenToClient(hwndMain, (LPPOINT) &rc);
              ScreenToClient(hwndMain, ((LPPOINT) &rc)+1);
          MoveWindow( hwnd, rc.left + xChange, rc.top + yChange,
            rc.right - rc.left, rc.bottom - rc.top, TRUE);
          }
        break;
      case WM_USER+1: // Asked by user to close the document
            {
            HANDLE hitem;
        ECDSTATUS EcdStat;
            PITEM pitem;

            // edit the object
            hitem = GetWindowWord (hwnd, 0);
            pitem = (PITEM) LocalLock (hitem);
        pitem->fOpen = FALSE;
        pitem->fClose = TRUE;
        if ((EcdStat = EcdClose(pitem->lpecdobject)) == ECD_WAIT_FOR_RELEASE)
          WaitForRelease(pitem);
          }
          if (fTestEcdStat(EcdStat)){
            MessageBox(hwnd, "Error In Closing Object",
               szAppName, MB_ICONASTERISK | MB_OK);
            }
            LocalUnlock(hitem);
          return (DefWindowProc(hwnd, message, wParam, lParam));
            }
      case WM_USER+2: // Asked by user to Reconnect
            {
            HANDLE hitem;
        ECDSTATUS EcdStat;
            PITEM pitem;

            // edit the object
            hitem = GetWindowWord (hwnd, 0);
            pitem = (PITEM) LocalLock (hitem);
        pitem->fOpen = TRUE;
        pitem->fClose = FALSE;
        if ((EcdStat = EcdReconnect(pitem->lpecdobject)) == ECD_WAIT_FOR_RELE
          WaitForRelease(pitem);
          }
          if (fTestEcdStat(EcdStat)){
            MessageBox(hwnd, "Error In Reconnecting Object",
               szAppName, MB_ICONASTERISK | MB_OK);
            }
            LocalUnlock(hitem);
          return (DefWindowProc(hwnd, message, wParam, lParam));
            }


    }
    return (DefWindowProc(hwnd, message, wParam, lParam));
}


//---------------------------------------------------------------------------
// AboutDlgProc
// Purpose: Handle the About... dialog box events
//---------------------------------------------------------------------------
BOOL FAR PASCAL
AboutDlgProc(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
{
    switch (message)
        {
        case WM_COMMAND:
            if (wParam == IDOK
              || wParam == IDCANCEL)
                {
                EndDialog(hDlg, TRUE);
                return (TRUE);
                }
            break;
        }
    return (FALSE);
}


//---------------------------------------------------------------------------
// SaveAsDlgProc
// Purpose: Handle the File Save As... dialog box events
//---------------------------------------------------------------------------
BOOL FAR PASCAL
SaveAsDlgProc (HWND hDlg, unsigned message, WORD wParam, LONG lParam)
{
    switch (message)
        {
        case WM_COMMAND:
            switch (wParam)
                {
                case IDOK:
                    GetDlgItemText(hDlg, IDC_EDIT, (LPSTR) rgchFilename, cbFn
                    EndDialog(hDlg, TRUE);
                    return (TRUE);

                case IDCANCEL:
                    EndDialog(hDlg, NULL);
                    return (FALSE);
                }
            break;

        case WM_INITDIALOG:
            SetDlgItemText(hDlg, IDC_EDIT, (LPSTR)rgchFilename);
            SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL, 0,
                MAKELONG(0, 32767));
            DlgDirList(hDlg, "", 0, IDC_PATH, 0);
            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE);
    }
    return FALSE;
}

//---------------------------------------------------------------------------
// OpenDlgProc
// Purpose: Handle the File Open... dialog box events
//---------------------------------------------------------------------------
int FAR PASCAL OpenDlgProc(HWND hDlg, unsigned message, WORD wParam, LONG lPa
{
    int fh;

    switch (message)
        {
        case WM_COMMAND:
            switch (wParam)
                {
                case IDC_LISTBOX:
                    switch (HIWORD(lParam))
                        {
                        case LBN_SELCHANGE:
                            DlgDirSelect(hDlg, rgchOpenName, IDC_LISTBOX);
                            SetDlgItemText(hDlg, IDC_EDIT, rgchOpenName);
                            SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL,
                                NULL, MAKELONG(0, 32767));
                            break;

                        case LBN_DBLCLK:
                            goto openfile;
                        }
                    return (TRUE);

                case IDOK:
openfile:
                    GetDlgItemText(hDlg, IDC_EDIT, rgchOpenName, cbFnMax);

                    if (!rgchOpenName[0])
                        {
                        MessageBox(hDlg, szNoFile,
                            NULL, MB_OK | MB_ICONHAND);
                        return (TRUE);
                        }

                    if ((fh = _lopen(rgchOpenName, OF_READ)) == -1)
                        {
                        MessageBox(hDlg, szInvalidFn,
                            NULL, MB_OK | MB_ICONHAND);
                        return (TRUE);
                        }
                    EndDialog(hDlg, fh);
                    return (TRUE);

                case IDCANCEL:
                    EndDialog(hDlg, -1);
                    return (FALSE);
            }
            break;

        case WM_INITDIALOG:
            DlgDirList(hDlg, "", IDC_LISTBOX, IDC_PATH, 0);
            SetDlgItemText(hDlg, IDC_EDIT, szDefOpen);
            SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL, NULL,
                MAKELONG(0, 32767));
            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE); // The focus is already set to a control
    }
    return FALSE;
}



//---------------------------------------------------------------------------
// GetFromClipboard
// Purpose: Paste or Link from the Clipboard
// Returns: void
//---------------------------------------------------------------------------
void GetFromClipboard (HWND hwndMain, WORD w)
{
    ClientPasteLink(hwndMain, w);
}

//---------------------------------------------------------------------------
// PutOnClipboard
// Purpose:  Cut or Copy onto the Clipboard
// Returns: void
//---------------------------------------------------------------------------
void PutOnClipboard(HWND hwndMain, WORD w)
{
    ClientCutCopy(hwndMain, w);
}

//---------------------------------------------------------------------------
// ResetAnchor
// Purpose: Resets the anchor so that new child windows are created at the
//          top left of the main window
// Returns: void
//---------------------------------------------------------------------------
void ResetAnchor(PPOINT pptAnchor)
{
    pptAnchor->x = dxInflate - dxCascade ;
    pptAnchor->y = dyInflate - dyCascade ;
}

//---------------------------------------------------------------------------
// MoveAnchor
// Purpose: Moves the anchor so that the new child window
//          1) appear in cascade;
//          2) doesn't get created past the edge
// Returns: void
//---------------------------------------------------------------------------
void MoveAnchor(PPOINT pptAnchor, PRECT pclientRect, PPOINT pptSize)
{
    ptAnchor.y += dyCascade;
    if (pptAnchor->y + pptSize->y >= pclientRect->bottom)
        pptAnchor->y = pclientRect->top ;

    ptAnchor.x += dxCascade;
    if (pptAnchor->x + pptSize->x >= pclientRect->right)
        pptAnchor->x  = pclientRect->left ;
}

//---------------------------------------------------------------------------
// SetNullFilename
// Purpose: This document is untitled...
// Returns: void
//---------------------------------------------------------------------------
void SetNullFilename (HWND hwndMain)
{
    SetFilename (hwndMain, szUntitled);
}


//---------------------------------------------------------------------------
// SetFilename
// Purpose: Update window title
//          Keep a copy of the filename
// Returns: FALSE if need to cancel the operation, TRUE otherwise
//---------------------------------------------------------------------------
void SetFilename (HWND hwnd, char* rgch)
{
    char rgchTitle[szMsgMax];

    // Keep a copy of the filename handy
    lstrcpy (rgchFilename, rgch);

    // Set up the window title
    wsprintf ((LPSTR) rgchTitle, (LPSTR) szTitle, (LPSTR) rgch);
    SetWindowText(hwnd, rgchTitle);
}

//---------------------------------------------------------------------------
// SaveAsNeeded
// Purpose: If necessary, ask the user if s/he wants to save the file
// Returns: FALSE if need to cancel the operation, TRUE otherwise
//---------------------------------------------------------------------------
BOOL SaveAsNeeded(HWND hwnd)
{
    int retval;
    char rgch[szMsgMax];

    if (!fDirty)
        return TRUE;
    wsprintf ((LPSTR) rgch, (LPSTR) szSave, (LPSTR) rgchFilename);
    retval = MessageBox (hwnd, rgch, szAppName,
        MB_YESNOCANCEL | MB_ICONINFORMATION);
    switch (retval)
        {
        case IDNO:
            return TRUE;
        case IDYES:
            return (Save(hwnd));
        default:
            return FALSE;
        }
}

//---------------------------------------------------------------------------
// New
// Purpose: Delete old Data
// Returns: FALSE if the operation was canceled, TRUE otherwise
//---------------------------------------------------------------------------
BOOL New (HWND hwnd)
{
    // Save the current file if necessary
    if (!SaveAsNeeded(hwnd))
        return (FALSE);

    // delete current objects
    CleanHwnd (hwnd);

    fDirty = FALSE;

    // reset filename
    SetNullFilename(hwnd);
}

//---------------------------------------------------------------------------
// Open
// Purpose: Ask for a file name
//          Open the file
// Returns: FALSE if the operation was canceled, TRUE otherwise
//---------------------------------------------------------------------------
BOOL Open (HWND hwnd)
{
    FARPROC lpProc;
    int     fh;

    // Save the current file if necessary
    if (!SaveAsNeeded(hwnd))
        return (FALSE);

    // Ask for a file name
    lpProc = MakeProcInstance(OpenDlgProc, hInst);
    fh = DialogBox(hInst, "Open", hwnd, lpProc);
    FreeProcInstance(lpProc);
    if (fh < 0)
        return (FALSE);
    SetFile(fh);
    lstrcpy(rgchFilename, rgchOpenName);
    SetFilename(hwnd, rgchFilename);

    // delete current objects
    CleanHwnd (hwnd);

    // read new objects
    return(ReadFromFile(hwnd, fh));
}


//---------------------------------------------------------------------------
// Save
// Purpose: Save the current data to a file
//          Ask for a new name if necessary
// Returns: FALSE if the operation was canceled, TRUE otherwise
//---------------------------------------------------------------------------
BOOL Save(HWND hwnd)
{
    if (!fDirty)
        {
        // The file is already saved.  We are done.
        return (TRUE);
        }
    if (!lstrcmp((LPSTR) rgchFilename, (LPSTR) szUntitled))
        return (SaveAs(hwnd));
    return (WriteToFile(hwnd));
}


//---------------------------------------------------------------------------
// SaveAs
// Purpose: Save the current data to a file
//          Ask for a new name
// Returns: FALSE if the operation was canceled, TRUE otherwise
//---------------------------------------------------------------------------
BOOL SaveAs(HWND hwnd)
{
    FARPROC lpProc;
    int     dlg;

    lpProc = MakeProcInstance(SaveAsDlgProc, hInst);
    dlg = DialogBox(hInst, "SaveAs", hwnd, lpProc);
    FreeProcInstance(lpProc);
    if (!dlg)
        return (FALSE);
    SetFilename(hwnd, rgchFilename);
    return(WriteToFile(hwnd));
}


//---------------------------------------------------------------------------
// WriteToFile
// Purpose: Write the current data into a file
// Returns: FALSE if the operation was aborted, TRUE otherwise
//---------------------------------------------------------------------------
BOOL    WriteToFile (HWND hwndMain)
{
    int     fh, nObjects;
    HANDLE  hitem;
    PITEM   pitem;
    HWND    hwnd;
  int i =0;
    RECT    rc;

  WORD  wFile, wSize = 0;
  LPSTR lpEditBuffer;
        ECDSTATUS EcdStat;



        if ((fh =_lcreat (rgchFilename, 0)) <= 0)
            {
            MessageBox (
                    GetFocus(),
                    szInvalidFn,
                    szAppName,
                    MB_ICONEXCLAMATION | MB_OK);
            return FALSE;
            }
        SetFile(fh);

      nObjects = GetWindowWord(hwndMain, 0);
      if (_lwrite (fh, (LPSTR)&nObjects, 2) <= 0){
        MessageBox (
                    GetFocus(),
                    szFnError,
                    szAppName,
                    MB_ICONEXCLAMATION | MB_OK);
            _lclose(fh);
            return(FALSE);
            }


        hwnd = GetNextWnd(&i);

    while (hwnd && nObjects--){
      if (hwnd != hwndEdit){
        if (IsIconic(hwnd)){
          rc.left = 0;
          rc.right = 0;
          rc.top = 0;
          rc.bottom = 0;
          }
        else { // if normal size window
          GetWindowRect(hwnd, &rc);
          // Screen coordinates => Parent coordinates
              ScreenToClient(hwndMain, (LPPOINT) &rc);
              ScreenToClient(hwndMain, ((LPPOINT) &rc)+1);
              }
            hitem = GetWindowWord (hwnd, 0);
            pitem = (PITEM) LocalLock(hitem);
            if ( (_lwrite (fh, (LPSTR) &rc, sizeof(RECT)) <= 0)
                || (_lwrite (fh, (LPSTR) &(pitem->wType), sizeof(WORD)) <= 0)
                || (_lwrite (fh, (LPSTR) &(pitem->wUpdate), sizeof(WORD)) <=
                || ((EcdStat = EcdSaveToStream(((PITEM) pitem)->lpecdobject,
                        (LPECDSTREAM) lpstream)) != ECD_OK))
               {

          if (EcdStat == ECD_WAIT_FOR_RELEASE)
            WaitForRelease(pitem);
          if (fTestEcdStat(EcdStat)){
                  MessageBox (
                        GetFocus(),
                        szFnError,
                        szAppName,
                        MB_ICONEXCLAMATION | MB_OK);
                  LocalUnlock(hitem);
                  _lclose(fh);
                  return(FALSE);
            }
               }
            LocalUnlock(hitem);
            }

        hwnd = GetNextWnd(&i);
    }
    _lclose (fh);
    fDirty = FALSE;
    return TRUE;
}

//---------------------------------------------------------------------------
// ReadFromFile
// Purpose: Read new data from a file
// Returns: FALSE if the operation was aborted, TRUE otherwise
//---------------------------------------------------------------------------
BOOL ReadFromFile (HWND hwnd, int fh)
{
    char ch;
    RECT rc;
    BOOL fRet = TRUE;
    LPECDOBJECT lpobject;
    WORD wType, wUpdate;
   WORD wSize;
   LPSTR lpEditBuffer;
   int nObjects;
        ECDSTATUS EcdStat;

        if (_lread (fh, (LPSTR)&nObjects, 2) <= 0)
           return FALSE; // end of file
      SetWindowWord(hwndMain, 0, nObjects);


      while(nObjects--){
        if ((_lread (fh, (LPSTR)&rc, sizeof(RECT)) <= 0)
            || (_lread (fh, (LPSTR) &wType, sizeof(WORD)) <= 0)
                || (_lread (fh, (LPSTR) &wUpdate, sizeof(WORD)) <= 0)
                || ((EcdStat = EcdLoadFromStream((LPECDSTREAM) lpstream, PROT
                    lpclient, 0, NULL, &lpobject)) != ECD_OK))
                {
                // file problem while reading an object description
            while(EcdQueryReleaseStatus(lpobject) == ECD_BUSY)
              {
              MSG msg;
              GetMessage(&msg, NULL, NULL, NULL);
                TranslateMessage(&msg);
                DispatchMessage(&msg);
               }
            if (fEcdReleaseError){
                      MessageBox (
                        GetFocus(),
                        szFnError,
                        szAppName,
                        MB_ICONEXCLAMATION | MB_OK);
                PrintError(fEcdReleaseStat);
                      fRet = FALSE;
                      break;
                }
                }

            ClientCreateNewItem (hwnd, TRUE, &rc, lpobject, wType, wUpdate);
        }

    _lclose (fh);
    return (fRet);
}


//---------------------------------------------------------------------------
// CleanHwnd
// Purpose: Delete all the children of the main window
// Returns: void
//---------------------------------------------------------------------------
void CleanHwnd (HWND hwndMain)
{
    HWND hwnd, hwndT;
    HANDLE hitem;
  int nObjects = GetWindowWord(hwndMain, 0);
  int i = 0;

    hwnd = GetWindow (hwndMain, GW_CHILD);

    while (nObjects--){
        hwndT = GetNextWnd(&i);
    if (hwndT != hwndEdit)
        {
        DestroyWindow(hwndT);
        }
    }
    ResetAnchor(&ptAnchor);
}


long far PASCAL EditWndProc(HWND hwnd, unsigned message, WORD wParam, LONG lP
{
  PAINTSTRUCT ps;
  PITEM           pitem;
   HANDLE          hitem;
  POINT pt;
  HWND hNext;


  switch (message) {

  case WM_PAINT:

        BeginPaint(hwnd, &ps);
        CallWindowProc( lpEditWndProc, hwndEdit, message, ps.hdc, 0L);
        hNext = GetWindow(hwnd, GW_HWNDNEXT);
        if (hNext)
          InvalidateRect(hNext, NULL, FALSE);

            EndPaint (hwnd, &ps);
        break;

  default:
      return CallWindowProc(lpEditWndProc, hwndEdit, message, wParam, lParam)
          break;
  }
    return(0L);
}


//*------------------------------------------------------------------------
//| InsFileProc
//|     Parameters:
//|         hWnd    - Handle to Window which message is delivered to.
//|         msgID   - ID number of message
//|         wParam  - 16-bit parameter
//|         lParam  - 32-bit parameter
//|
//*------------------------------------------------------------------------
BOOL FAR PASCAL InsFileProc (HWND     hWnd,
                            unsigned wMsgID,
                            WORD     wParam,
                            LONG     lParam)
{
  int nRet;

    switch(wMsgID)
    {
    case WM_INITDIALOG:
        return TRUE;
    case WM_COMMAND:
        switch (wParam)
        {
        case IDOK:
            nRet = GetDlgItemText(hWnd, 101, (LPSTR)szInsFileName, cbFnMax);
            EndDialog(hWnd,TRUE);
            return TRUE;

        case IDCANCEL:
            EndDialog(hWnd,FALSE);
            return TRUE;
        }
        break;
    }
    return FALSE;
}

ECDSTATUS CreateObject(WORD wParam, PITEM pitem)
    {
    char szClassName[szMaxClassName];
    switch(wParam){
      case IDM_SHAPES:
        lstrcpy ((LPSTR)szClassName, "Shapes");
        break;
      case IDM_PBRUSH:
         lstrcpy ((LPSTR)szClassName, "PBrush");
        break;
      case IDM_EXCEL :
        lstrcpy ((LPSTR)szClassName, "ExcelWorksheet");
        break;
      case IDM_GRAPH :
        lstrcpy ((LPSTR)szClassName, "Graph");
        break;
      case IDM_TORUS :
        lstrcpy ((LPSTR)szClassName, "Torus");
        break;
        }
     return(EcdCreate(PROTOCOL, lpclient, (LPSTR)szClassName, 0, NULL, &(pite
          ecdrender_draw,  0));

    }



  void CallPrint(){
    static char szPrinter[80];
    char *szDevice, *szDriver, *szOutput;
    HWND hPrnDC, hDC;
    int nObjects;
     HANDLE  hitem;
     PITEM   pitem;
     HWND    hwnd;
     RECT    rc;
    short mm;
    int nRecSize, nRet;
      HSTR hstr;
      LPSTR lpstrInfo;
    int i =0;




    nObjects = GetWindowWord(hwndMain, 0);
    GetProfileString("windows", "device", ",,", szPrinter, 80);
    if ((szDevice = strtok(szPrinter, ",")) &&
      (szDriver = strtok(NULL, ",")) &&
      (szOutput = strtok(NULL, ",")))
      hPrnDC = CreateIC(szDriver, szDevice, szOutput, NULL);
    else {
         MessageBox (GetFocus(), "Not Printed",
                        szAppName, MB_ICONEXCLAMATION | MB_OK);
                return;
                }

    nObjects = GetWindowWord(hwndMain, 0);
    hwnd = GetWindow (hwndMain, GW_CHILD);
    while (hwnd && nObjects--){
      if (hwnd != hwndEdit){
        GetWindowRect(hwnd, &rc);
            // Screen coordinates => Parent coordinates
            ScreenToClient(hwnd, (LPPOINT) &rc);
            ScreenToClient(hwnd, ((LPPOINT) &rc)+1);
        mm = SetMapMode(hPrnDC, MM_ISOTROPIC);
        LPtoDP(hPrnDC, (LPPOINT)&rc, 2);

            hitem = GetWindowWord (hwnd, 0);
            pitem = (PITEM) LocalLock(hitem);
        if (EcdDraw( pitem->lpecdobject, hPrnDC, (LPRECT)&rc, NULL) != ECD_OK
                {
                MessageBox (
                        GetFocus(),
                        szFnError,
                        szAppName,
                        MB_ICONEXCLAMATION | MB_OK);
                LocalUnlock(hitem);
                return;
                }
        else {
              LocalUnlock(hitem);
          nRecSize = (rc.right-rc.left)*(rc.top - rc.bottom);
          if (nRecSize < 0)
            nRecSize = - nRecSize;
            nRet = Escape(hPrnDC, STARTDOC, 5, "HELLO",   NULL);
            nRet = Escape(hPrnDC, NEWFRAME, 0, NULL,  NULL);
            nRet = Escape(hPrnDC, ENDDOC, 0, NULL,  NULL);
        SetMapMode(hPrnDC, mm);

            }
      }
        hwnd = GetNextWnd(&i);
      }
    DeleteDC(hPrnDC);
    }


void RemoveObjUndo(){

      PITEM pitem;
      if (hObjectUndo){
        pitem = (PITEM)LocalLock(hObjectUndo);
        EcdDelete(pitem->lpecdobject);
        LocalUnlock(hObjectUndo);
          LocalFree(hObjectUndo);
          hObjectUndo = NULL;
      }
    }

void PrintError(ECDSTATUS stat){
  char szError[szMsgMax];

  switch(stat){
    case ECD_ERROR_MEMORY:
      lstrcpy(szError, "Error ECD_ERROR_MEMORY");
      break;
    case ECD_ERROR_FATAL:
      lstrcpy(szError, "Error ECD_ERROR_FATAL");
      break;
    case ECD_ERROR_STREAM:
      lstrcpy(szError, "Error ECD_ERROR_STREAM");
      break;
    case ECD_ERROR_STATIC:
      lstrcpy(szError, "Error ECD_ERROR_STATIC");
      break;
    case ECD_ERROR_BLANK:
      lstrcpy(szError, "Error ECD_ERROR_BLANK");
      break;
    case ECD_ERROR_LAUNCH:
      lstrcpy(szError, "Error ECD_ERROR_LAUNCH");
      break;
    case ECD_ERROR_COMM:
      lstrcpy(szError, "Error ECD_ERROR_COMM");
      break;
    case ECD_ERROR_DRAW:
      lstrcpy(szError, "Error ECD_ERROR_DRAW");
      break;
    case ECD_ERROR_CLIP:
      lstrcpy(szError, "Error ECD_ERROR_CLIP");
      break;
    case ECD_ERROR_FORMAT:
      lstrcpy(szError, "Error ECD_ERROR_FORMAT");
      break;
    case ECD_ERROR_ILLEGALOBJECT:
      lstrcpy(szError, "Error ECD_ERROR_ILLEGALOBJECT");
      break;
    case ECD_ERROR_OPTION:
      lstrcpy(szError, "Error ECD_ERROR_OPTION");
      break;
    case ECD_ERROR_PROTOCOL:
      lstrcpy(szError, "Error ECD_ERROR_PROTOC");
      break;
    case ECD_ERROR_ADDRESS:
      lstrcpy(szError, "Error ECD_ERROR_ADDRESS");
      break;

    case ECD_ERROR_NOT_EQUAL:
      lstrcpy(szError, "Error ECD_ERROR_NOT_EQUAL");
      break;

    case ECD_ERROR_HANDLE:
      lstrcpy(szError, "Error ECD_ERROR_HANDLE");
      break;
    case ECD_ERROR_GENERIC:
      lstrcpy(szError, "Error ECD_ERROR_GENERIC");
      break;
    case ECD_WAIT_FOR_RELEASE:
      lstrcpy(szError, "Error ECD_WAIT_FOR_RELEASE");
      break;
    case ECD_ERROR_MAPPING_MODE:
      lstrcpy(szError, "Error ECD_ERROR_MAPPING_MODE");
      break;

    case ECD_ERROR_INVALIDCLASS:
      lstrcpy(szError, "Error ECD_ERROR_INVALIDCLASS");
      break;
    case ECD_ERROR_SYNTAX:
      lstrcpy(szError, "Error ECD_ERROR_SYNTAX");
      break;
    case ECD_ERROR_NOT_OPEN:
      lstrcpy(szError, "Error ECD_ERROR_NOTOPEN");
      break;
    case ECD_ERROR_PROTECT_ONLY:
      lstrcpy(szError, "Error ECD_ERROR_PROTECT_ONLY");
      break;
    case ECD_ERROR_POKENATIVE:
      lstrcpy(szError, "Error ECD_ERROR_POKENATIVE");
      break;
    case ECD_ERROR_ADVISE_PICT:
      lstrcpy(szError, "Error ECD_ERROR_ADVISE_PICT");
      break;
    case ECD_ERROR_DATATYPE:
      lstrcpy(szError, "Error ECD_ERROR_DATATYPE");
      break;
    case ECD_ERROR_ALREADY_BLOCKED:
      lstrcpy(szError, "Error ECD_ERROR_ALREADYBLOCKED");
      break;
    default:
      lstrcpy(szError, "Error Other");
      break;
      }

      MessageBox(hwndMain,szError, szAppName, MB_ICONASTERISK | MB_OK);
      }




void PrintWindowTitle(PITEM pitem, HWND hwnd){

  ECDSTATUS EcdStat;
  HANDLE hWinTitle;
    LPSTR pTitle, pTitle1;
   LPSTR lpstrInfo, lpstr1, lpstr2;
  HSTR hstr;

            if (((EcdStat = EcdGetData(pitem->lpecdobject,
                    (pitem->wType == IDM_PASTE) ? cfOwnerLink : cfLink,
                    &hstr))
                    == ECD_OK)
                && hstr)
                {
                // Both link formats are:  "szClass szDocument szItem 0"
                lpstrInfo = GlobalLock(hstr);
           lpstr1 = lpstrInfo;
           hWinTitle = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, 512);
           pTitle = pTitle1 = (LPSTR)LocalLock(hWinTitle);
          if (pitem->wType == IDM_PASTE){
            lstrcpy(pTitle, "Embed!");
            pTitle += 6;
            }
          else{
            lstrcat(pTitle, "Link!");
            pTitle += 5;
            }
           while (*lpstr1){
            *(pTitle++) = *(lpstr1++);
            }
           *(pTitle++) = '!';
           lpstr1 += 1;
           while (*lpstr1)
            *(pTitle++) = *(lpstr1++);
           *(pTitle++) = '!';
           lpstr1 += 1;
           while (*lpstr1)
            *(pTitle++) = *(lpstr1++);
           *pTitle = '!';
           lpstr1 += 1;


                SetWindowText(hwnd, (LPSTR)pTitle1);
           LocalUnlock(hWinTitle);
          LocalFree(hWinTitle);
               GlobalUnlock(hstr);
                }
          }

void GetUndo(PITEM pitem){
  PITEM pObjectUndo;

  pObjectUndo = (PITEM)LocalLock(hObjectUndo);
  pitem->wType = pObjectUndo->wType ;
  pitem->wUpdate = pObjectUndo->wUpdate ;
  pitem->lpecdobject = pObjectUndo->lpecdobject;
  LocalUnlock(hObjectUndo);
  LocalFree(hObjectUndo);
  hObjectUndo = 0;
  }

ECDSTATUS CopyLink(PITEM pCopy){
   HWND hwnd;
    HANDLE hitem;
    PITEM pitem;
  ECDSTATUS EcdStat;
  int i = 0;

  hwnd = GetNextWnd(&i);
   hitem = GetWindowWord(hwnd, 0);
   pitem = (PITEM) LocalLock(hitem);
  EcdStat = EcdCopyFromLink(pitem->lpecdobject, PROTOCOL, lpclient,NULL, NULL
  LocalUnlock(hitem);
  return EcdStat;
}

VOID WaitForRelease(PITEM pitem){
   MSG msg;

  fEcdrelease = FALSE;
  do  {
  GetMessage(&msg, NULL, NULL, NULL);
   TranslateMessage(&msg);
   DispatchMessage(&msg);
   }
while (!fEcdrelease);
}


HWND GetTopChild(){
  HWND  hwnd;
  int i = 0;

  hwnd = GetTopWindow(hwndMain);

  while ((hwnd != rgchChildWnd[i]) && i++ < irgchChild)
    ;
  if (i <= irgchChild) // if it was found
    return hwnd;
  // else find the first non null guy
  i = 0;
  while (!(hwnd = rgchChildWnd[i]) && i++ < irgchChild)
    ;
    return hwnd;
}

HWND GetNextWnd(LPINT i){
  HWND hwnd;
  while (!(hwnd = rgchChildWnd[*i]) && *i < irgchChild)
    *i += 1;
  *i += 1;
  return hwnd;
}


BOOL fTestEcdStat(ECDSTATUS EcdStat){
  // use it for Async conditions

  switch(EcdStat){
    case ECD_WAIT_FOR_RELEASE:
      if (fEcdReleaseError){
        PrintError(fEcdReleaseStat);
        return TRUE;
        }
      else
        return FALSE;
      break;
    case ECD_OK:
      return FALSE;
    default:
      PrintError(EcdStat);
      return TRUE;
      }
    }


BOOL Insert(HWND hwnd)
{
    FARPROC lpProc;
    int     fh;


    // Ask for a file name
    lpProc = MakeProcInstance(OpenDlgProc, hInst);
    fh = DialogBox(hInst, "Open", hwnd, lpProc);
    FreeProcInstance(lpProc);
  if (fh > 0)
    _lclose(fh); // because the file is opened in Open
    return (fh);

}


VOID TestEqual(){ // test the top and next object are equal
  HWND hTop, hNext;
  HANDLE hitem1, hitem2;
  PITEM pitem1, pitem2;
  ECDSTATUS EcdStat;
  int i = 0;

  hTop = GetTopChild();
  hitem1 = GetWindowWord(hTop, 0);
  pitem1 = (PITEM)LocalLock(hitem1);

  hNext = GetNextWnd(&i);
  hitem2 = GetWindowWord(hNext, 0);
  pitem2 = (PITEM)LocalLock(hitem2);

  EcdStat = EcdEqual(pitem1->lpecdobject, pitem2->lpecdobject);
  if (EcdStat == ECD_WAIT_FOR_RELEASE)
    WaitForRelease(pitem1);
  if (fTestEcdStat(EcdStat))
    PrintError(EcdStat);
}






CLIENT.C
CD-ROM Disc Path:   \SAMPCODE\OLE\CLIENT\CLIENT.C

//---------------------------------------------------------------------------
// client.c
//
// Copyright (c) Microsoft Corporation, 1990-
//---------------------------------------------------------------------------

#include "windows.h"
#include "ecd.h"
#include "cldemo.h"
#include "client.h"

//--- Globals --------------------------------------------------------------
extern HWND  hwndEdit;
extern BOOL fInsUpdate;
extern HWND rgchChildWnd[];
extern int irgchChild;
// extern BOOL fObjectClose;

LPECDCLIENT     lpclient;
ECDCLIENTVTBL   clientTbl;
ECDSTREAMVTBL   streamTbl;
LPAPPSTREAM     lpstream;
HANDLE      hObjectUndo = NULL;
LPECDOBJECT     lpObjectUndo;
WORD            wUpdateUndo, wTypeUndo;
BOOL            fEcdrelease;
BOOL            fEcdReleaseError;
BOOL            fEcdReleaseStat;
HANDLE          hobjStream = NULL;
HANDLE          hobjClient = NULL;
// HANDLE       hobjPrn = NULL;
HANDLE hWinTitle = 0;
int  nOffDocNm, nOffItemNm;


//--- Local Functions Declaration -------------------------------------------
void GetUpdateStatus(HWND hDlg);
void PrepareUndo(PITEM pitem);
void PrepareUndoClear(PITEM pitem);
void PrintWindowTitle(PITEM pitem, HWND hwnd);
VOID SetRectSize(HWND hwnd, PITEM pitem);
void PrintLinkName(PITEM pitem, HWND hwnd);
void SetData(PITEM pitem, HWND hDlg);


extern HWND GetTopChild();
extern HWND GetNextWnd(LPINT i);

//---------------------------------------------------------------------------
// InitClient
// Purpose: Set up this application as a client
// Returns: TRUE if successful
//---------------------------------------------------------------------------
BOOL InitClient (HANDLE hInstance)
    {

    // Set up the client structure

    if (!(hobjClient = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
                                   sizeof(ECDCLIENT))))
            return FALSE;

    if (!(lpclient = (LPECDCLIENT)(GlobalLock(hobjClient))))
        {
        GlobalFree(hobjClient);
        hobjClient = NULL;
        return FALSE;
        }

    lpclient->lpvtbl = (LPECDCLIENTVTBL)&clientTbl;

    lpclient->lpvtbl->CallBack = MakeProcInstance(CallBack, hInstance);

    // Set up the stream structure

    if (!(hobjStream = GlobalAlloc (GMEM_MOVEABLE, sizeof(APPSTREAM))))
        {
        GlobalUnlock(hobjClient);
        GlobalFree(hobjClient);
        hobjClient = NULL;
        return FALSE;
        }

    if(lpstream = (LPAPPSTREAM)(GlobalLock(hobjStream)))
        {
        lpstream->lpstbl = (LPECDSTREAMVTBL)&streamTbl;
        streamTbl.Get =
            (LONG  (pascal far *) (LPECDSTREAM, LPSTR, LONG))
            MakeProcInstance((FARPROC) ReadStream, hInstance);
        streamTbl.Put =
            (LONG  (pascal far *) (LPECDSTREAM, LPSTR, LONG))
            MakeProcInstance((FARPROC) WriteStream, hInstance);
        streamTbl.Seek =
            (LONG  (pascal far *) (LPECDSTREAM, LONG))
            MakeProcInstance((FARPROC) PosStream, hInstance);
        streamTbl.Status =  MakeProcInstance((FARPROC) StatusStream, hInstanc
        lpstream->hobjStream = hobjStream;
        }
    else
        {
        GlobalUnlock(hobjClient);
        GlobalFree(hobjClient);
        hobjClient = NULL;
        GlobalFree(hobjStream);
        hobjStream = NULL;
        return FALSE;
        }
    return TRUE;
}

//---------------------------------------------------------------------------
// TermClient
// Purpose: To clean up after termination
// Returns: void
//---------------------------------------------------------------------------
void TermClient (void)
{
    // Get rid of the client structure
    if (hobjClient)
        {
        GlobalUnlock(hobjClient);
        GlobalFree(hobjClient);
        }

    // Get rid of the stream structure
    if (hobjStream)
        {
        GlobalUnlock(hobjStream);
        GlobalFree(hobjStream);
        }
}

//---------------------------------------------------------------------------
// CallBack
// Purpose: Client Callback Function
//---------------------------------------------------------------------------
int FAR PASCAL
CallBack(LPECDCLIENT lpclient, int flags, LPECDOBJECT lpObject)
{
  RECT rc;
  HWND hDC;
  ECDSTATUS EcdStat;
    switch(flags)
        {
        case ECD_SAVED:
        case ECD_CHANGED:
        case ECD_CLOSED:
            {
            HANDLE hitem;
            PITEM  pitem;
            HWND   hwnd, hNext;
        short mm;

            // The file needs to be saved
            fDirty = TRUE;

            // Find out if we need to update our visuals immediately
        if (fInsUpdate){ // it is for case when object created by EcdCreate
          fInsUpdate = FALSE;
          }

            hwnd = GetTopWindow(hwndMain);
        while(hwnd){
          if (hwnd != hwndEdit){
            hitem = GetWindowWord(hwnd, 0);
            pitem = (PITEM) LocalLock(hitem);
                if (pitem->lpecdobject == lpObject && (flags == ECD_CLOSED)){
              pitem->fOpen = FALSE;
              }
                if (pitem->lpecdobject == lpObject){
              SetRectSize(hwnd, pitem);
                    InvalidateRect(hwnd, NULL, TRUE);
              }
                LocalUnlock(hitem);
            }
          hwnd = GetWindow(hwnd, GW_HWNDNEXT);
          }

            }
              break;

        case ECD_RELEASE:
            fEcdrelease = TRUE;
        if ((fEcdReleaseStat = EcdQueryReleaseError(lpObject)) != ECD_OK){
          fEcdReleaseError = TRUE;
          }
        else
          fEcdReleaseError = FALSE;

            break;

        case ECD_QUERY_PAINT:
            // Yes, paint!
            return TRUE;
            break;

        case ECD_RENAMED:
            // The file needs to be saved
            fDirty = TRUE;
            break;

        default:
            break;
    }
    return 0;
}

//---------------------------------------------------------------------------
// ClientUpdateMenu
// Purpose: Update the Edit menu
// Returns: void
//---------------------------------------------------------------------------
void ClientUpdateMenu(HWND hwnd, HMENU hMenu)
{
    HWND    hwndChild;
    HANDLE  hitem;
    PITEM   pitem;
    int     mfPaste = MF_GRAYED;
    int     mfPasteLink = MF_GRAYED;
    int     mfProperties = MF_GRAYED;
    int     mfClear = MF_GRAYED;
    int     mfCut   = MF_GRAYED;
    int     mfCopy  = MF_GRAYED;
    int     mfUndo  = MF_GRAYED;
    int     mfClose  = MF_GRAYED;
    int     mfCopyLink  = MF_GRAYED;
    int     mfReconnect  = MF_GRAYED;

    // Enable "Paste" if there is a paste-able object in the clipboard */
   if (hObjectUndo)
    mfUndo = MF_ENABLED;
    if (EcdQueryCreateFromClip(PROTOCOL, ecdrender_draw, 0) == ECD_OK)
        mfPaste = MF_ENABLED;

    // Enable "Paste Link" if there is a link-able object in the clipboard
    if (EcdQueryLinkFromClip(PROTOCOL, ecdrender_draw, 0) == ECD_OK)
        mfPasteLink = MF_ENABLED;

    // Enable "Clear", "Cut", "Copy" and maybe "Properties..."
    // if we have a child window
    if (GetWindowWord(hwndMain, 0)) // if there is any window
        {
        mfClear = MF_ENABLED;
        mfCut   = MF_ENABLED;
        mfCopy  = MF_ENABLED;
        mfCopyLink  = MF_ENABLED;
         hwndChild = GetTopWindow(hwnd);
      if (hwndChild == hwndEdit)
      hwndChild = GetTopWindow(hwnd);
        hitem = GetWindowWord(hwndChild, 0);
        pitem = (PITEM) LocalLock(hitem);
        if (pitem->wType != IDM_STATIC)
            mfProperties = MF_ENABLED;
      if (pitem->fOpen)
          mfClose  = MF_ENABLED;
      if (pitem->fClose)
      mfReconnect = MF_ENABLED;
        LocalUnlock(hitem);
        }

    EnableMenuItem(hMenu, IDM_UNDO,       mfUndo);
    EnableMenuItem(hMenu, IDM_CUT,        mfCut);
    EnableMenuItem(hMenu, IDM_COPY,       mfCopy);
    EnableMenuItem(hMenu, IDM_CLOSE,      mfClose);
    EnableMenuItem(hMenu, IDM_COPYLINK,   mfCopyLink);
    EnableMenuItem(hMenu, IDM_LINK,       mfPasteLink);
    EnableMenuItem(hMenu, IDM_PASTE,      mfPaste);
    EnableMenuItem(hMenu, IDM_CLEAR,      mfClear);
    EnableMenuItem(hMenu, IDM_PROPERTIES, mfProperties);
    EnableMenuItem(hMenu, IDM_RECONNECT,  mfReconnect);
}

//---------------------------------------------------------------------------
// ClientCutCopy
// Purpose: Does "Cut" and "Copy"
// Returns: void
//---------------------------------------------------------------------------
void ClientCutCopy(HWND hwndMain, WORD w)
{
    HWND hwnd;
    HANDLE hitem;
    PITEM pitem;

    hwnd = GetTopWindow(hwndMain);
    hitem = GetWindowWord(hwnd, 0);
    pitem = (PITEM) LocalLock(hitem);
    if (pitem->lpecdobject && OpenClipboard(hwndMain))
        {
        EmptyClipboard();
        if (w = IDM_COPY)
            {
            EcdCopyToClipboard(pitem->lpecdobject);
            }
        else
            {
            EcdCutToClipboard(pitem->lpecdobject);
            pitem->lpecdobject = NULL;
            }
        CloseClipboard();
        }
    LocalUnlock(hitem);
}


//---------------------------------------------------------------------------
// ClientPasteLink
// Purpose: Does "Paste" and "Paste Link"
// Returns: void
//---------------------------------------------------------------------------
void ClientPasteLink(HWND hwndMain, WORD w)
{
    HWND hwnd = NULL;
    HANDLE hitem;
    PITEM pitem = NULL;
    ECDCLIPFORMAT   cfFormat;

  RECT rc;
  HDC hdc;
  short mm;
  POINT pt;
  ECDSTATUS EcdStat;

    // Allocate memory for a new item
    hitem = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITEM));
    if (hitem == NULL || ((pitem = (PITEM)LocalLock (hitem)) == NULL))
        goto  errRtn;

    if (hwnd = CreateItemWindow(hwndMain, FALSE, NULL))
        {
        SetWindowWord (hwnd, 0, hitem);
        BringWindowToTop (hwnd);
        }
    else goto errRtn;

    rgchChildWnd[irgchChild++] = hwnd;
        SetWindowWord (hwndMain, 0, (GetWindowWord(hwndMain, 0)+1) );

    // Grab the item from the clipboard
    switch (w)
        {
        case IDM_PASTE:
            if (!OpenClipboard(hwndMain))
                goto errRtn;
            else if( (EcdStat = EcdCreateFromClip(PROTOCOL, lpclient, 0, NULL
                ecdrender_draw,  0)) != ECD_OK)
                {
          if (EcdStat == ECD_WAIT_FOR_RELEASE)
            WaitForRelease(pitem);
          if (fTestEcdStat(EcdStat)){
             CloseClipboard();
             goto errRtn;
                 }
                }
            CloseClipboard();
            break;
        case IDM_LINK:
            if (!OpenClipboard(hwndMain))
                goto errRtn;
            else if ( (EcdStat = EcdCreateLinkFromClip(PROTOCOL, lpclient, 0,
                    ecdrender_draw, 0)) != ECD_OK)
                {
            if (EcdStat == ECD_WAIT_FOR_RELEASE)
            WaitForRelease(pitem);
          if (fTestEcdStat(EcdStat)){
               CloseClipboard();
               goto errRtn;
                   }
                }
            CloseClipboard();
            break;
        }

    pitem->fOpen = FALSE;
    pitem->fClose = FALSE;
    cfFormat = EcdEnumObjectFormats (pitem->lpecdobject, NULL);
    if (cfFormat == cfNative)
    {
        pitem->wType = IDM_PASTE;
    }
    else if (cfFormat == cfLink)
        pitem->wType = IDM_LINK;

    pitem->wUpdate = IDD_AUTO;

    EcdSetHostNames(pitem->lpecdobject, szHostname, szHostobjectname);

  GetCaretPos((LPPOINT)&pt);
  pt.y += 15;
  hdc = GetDC(hwnd);
  mm = SetMapMode(hdc, MM_HIMETRIC);
  DPtoLP(hdc, (LPPOINT)&pt, 1);

  EcdQueryBounds(pitem->lpecdobject, &rc);
  rc.top = pt.y ;
  rc.bottom += pt.y ;
  LPtoDP(hdc, (LPPOINT)&rc, 2);


  SetMapMode(hdc, mm);
  MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top +
    GetSystemMetrics(SM_CYCAPTION), TRUE);
  ReleaseDC(hwnd, hdc);
   SendMessage (hwnd, WM_USER, 0, 0L);

    ShowWindow(hwnd, SW_SHOW);
   InvalidateRect(hwnd, NULL, TRUE);

    LocalUnlock(hitem);

    return;

 errRtn:
    if (pitem)
        LocalUnlock (hitem);

    if (hitem)
        LocalFree (hitem);

    if (hwnd)
        {
        SetWindowWord(hwnd, 0, NULL);
        DestroyWindow(hwnd);
        }

}

//---------------------------------------------------------------------------
// ClientCreateNewItem
// Purpose: Creates a new window and associates a new item
// Returns: void
//---------------------------------------------------------------------------
void ClientCreateNewItem (HWND hwndMain, BOOL fVisible,
    LPRECT lprect, LPECDOBJECT lpobject, WORD wType, WORD wUpdate)
{
    HWND   hwndItem;
    HANDLE hitem;
    PITEM  pitem = NULL;
  BOOL fIconic = FALSE;

    // Allocate memory for a new item
    hitem = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITEM));

    if (hitem == NULL || ((pitem = (PITEM)LocalLock (hitem)) == NULL))
        goto  errRtn;

    pitem->wType = wType;
    pitem->wUpdate = wUpdate;
    pitem->lpecdobject = lpobject;

  pitem->fOpen = FALSE;
  pitem->fClose = FALSE;

    // Create a window in which to put the new item
  if ((lprect->left == 0) && (lprect->top == 0) && (lprect->right == 0) && (
    lprect->bottom == 0)) // i.e. iconic window
    fIconic = TRUE;
    if (hwndItem = CreateItemWindow(hwndMain, fIconic, lprect))
        {
      if (!fIconic)
        MoveWindow(hwndItem, lprect->left, lprect->top,
          lprect->right - lprect->left, lprect->bottom - lprect->top, TRUE);
        EcdSetHostNames(pitem->lpecdobject, szHostname, szHostobjectname);
        SetWindowWord (hwndItem, 0, hitem);
      rgchChildWnd[irgchChild++] = hwndItem;
       SendMessage (hwndItem, WM_USER, 0, 0L);
        if (fVisible)
            ShowWindow(hwndItem, SW_SHOW);
        InvalidateRect(hwndItem, NULL, TRUE);
        }
    else goto errRtn;
    LocalUnlock(hitem);
    return;

 errRtn:
    if (pitem)
        LocalUnlock (hitem);

    if (hitem)
        LocalFree (hitem);
}

//---------------------------------------------------------------------------
// ClientPaint
// Purpose: Ask the server to paint for us
// Returns: void
//---------------------------------------------------------------------------
void ClientPaint(HWND hwnd, HDC hdc, PITEM pitem)
{
    RECT rc;
  HDC saveDC;
  short mm;
  POINT pt;
  int bot;

    // Find the coordinates of the "display" area


    GetClientRect (hwnd, (LPRECT)&rc);

    // Convert the rectangle's coordinates to MM_HIMETRIC
    SetMapMode(hdc, MM_HIMETRIC);
    DPtoLP(hdc,(LPPOINT)&rc,2);

    // Ask the server to draw the object
    EcdDraw (pitem->lpecdobject, hdc, (LPRECT)&rc, hdc);
}

//---------------------------------------------------------------------------
// ClientEdit
// Purpose: Ask the server to edit the object
// Returns: void
//---------------------------------------------------------------------------
void ClientEdit(HWND hwnd, PITEM pitem)
{
    RECT rc;
  HWND hdc;
  short mm;
  ECDSTATUS EcdStat;

    GetClientRect(hwnd,&rc);
   if (EcdQueryOpen(pitem->lpecdobject) != ECD_OK) //
      EcdStat = EcdOpen (pitem->lpecdobject, TRUE, hwnd, &rc);
   else{
      EcdStat = EcdOpen (pitem->lpecdobject, TRUE, hwnd, &rc);
    /* should be following code
    if (EcdReconnect(pitem->lpecdobject) != ECD_OK){
      MessageBox(hwndMain, "Error Reconnecting ",
                          szAppName, MB_ICONASTERISK | MB_OK);
        EcdOpen (pitem->lpecdobject, TRUE, hwnd, &rc);
      }
    */
    }
    pitem->fOpen = TRUE;
    if (EcdStat != ECD_OK){
      if (EcdStat == ECD_WAIT_FOR_RELEASE)
        WaitForRelease(pitem);
        if (fTestEcdStat(EcdStat)){
        }
      }

  hdc = GetDC(hwnd);
    mm = SetMapMode(hdc, MM_HIMETRIC);
    DPtoLP(hdc,(LPPOINT)&rc,2);
  EcdSetBounds(pitem->lpecdobject, (LPRECT)&rc);
  SetMapMode(hdc, mm);
  ReleaseDC(hwnd, hdc);

}

//---------------------------------------------------------------------------
// ClientDelete
// Purpose: Ask the server to delete the object
// Returns: void
//---------------------------------------------------------------------------
void ClientDelete(PITEM pitem)
{
    MSG msg;

    if (EcdDelete (pitem->lpecdobject) == ECD_WAIT_FOR_RELEASE)
        {
        fEcdrelease = FALSE;
          do
            {
            GetMessage(&msg, NULL, NULL, NULL);
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            }
        while (!fEcdrelease);
        }
}

//---------------------------------------------------------------------------
// SetFile
// Purpose: Set up the stream structure
// Returns: void
//---------------------------------------------------------------------------
void SetFile (int fh)
{
    lpstream->fh = fh;
}

//---------------------------------------------------------------------------
// PropertiesDlgProc
// Purpose: Handles the Properties... dialog box events
//---------------------------------------------------------------------------
BOOL FAR PASCAL
PropertiesDlgProc(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
{
    HWND hwnd;
    HANDLE hitem;
    PITEM pitem;
    LPECDOBJECT lpobject;
    HSTR hstr;
    LPSTR lpstrInfo, lpstr1, lpstr2;

    switch (message)
        {
        case WM_INITDIALOG:
            lpObjectUndo = NULL;
            wUpdateUndo = 0;
        hwnd = GetTopChild();
            hitem = GetWindowWord(hwnd, 0);
            pitem = (PITEM) LocalLock(hitem);
            PrepareUndo(pitem);
            CheckDlgButton(hDlg, pitem->wUpdate, TRUE);
            if (pitem->wType == IDM_PASTE)
                EnableWindow(GetDlgItem(hDlg, IDCANCEL), FALSE);
          if (pitem->wType != IDM_PASTE)
            PrintLinkName(pitem, hDlg);
         //    PrintWindowTitle(pitem, GetDlgItem(hDlg, IDD_LINKINFO));
          else
             PrintWindowTitle(pitem, GetDlgItem(hDlg, IDD_WHICH));

            LocalUnlock(hitem);
            return (TRUE);

        case WM_COMMAND:
            switch (wParam)
                {
                case IDD_FREEZE:
                case IDD_UPDATE:
            /*
                    hwnd = GetTopWindow(hwndMain);
              if (hwnd == hwndEdit)
                hwnd = GetWindow(hwnd, GW_HWNDNEXT);
              */
              hwnd = GetTopChild();
                    hitem = GetWindowWord(hwnd,0);
                    pitem = (PITEM) LocalLock(hitem);
                    if (wParam == IDD_FREEZE)
                        {
                        if (pitem->wType == IDM_PASTE)
                            EnableWindow(GetDlgItem(hDlg, IDCANCEL), TRUE);
                        else
                            EnableWindow(GetDlgItem(hDlg, IDD_UPDATE), FALSE)
                        EnableWindow(GetDlgItem(hDlg, IDD_EDIT), FALSE);
                        EnableWindow(GetDlgItem(hDlg, IDD_FREEZE), FALSE);
                        if (EcdObjectConvert(pitem->lpecdobject, SPROTOCOL,
                            lpclient, NULL, NULL, &lpobject) == ECD_OK)
                            {
                            ClientDelete (pitem);
                            pitem->lpecdobject = lpobject;
                            pitem->wType = IDM_STATIC;
                            }
                        }
                    else // (wParam == IDD_UPDATE)
                        {
                        EcdUpdate(pitem->lpecdobject);
                        }
                    fDirty = TRUE;
                    InvalidateRect(hwnd, NULL, TRUE);
                    LocalUnlock(hitem);
                    break;

                case IDD_EDIT:
                    {
                    RECT rc;

                    GetUpdateStatus(hDlg);
              hwnd = GetTopChild();

                    hitem = GetWindowWord(hwnd, 0);
                    pitem = (PITEM) LocalLock(hitem);
                    EcdDelete(lpObjectUndo);
                  lpObjectUndo = NULL;
                    GetClientRect(hwnd,&rc);
                    EcdOpen (pitem->lpecdobject, TRUE, hwnd, &rc);
                    LocalUnlock(hitem);
                    fDirty = TRUE;
                    InvalidateRect(hwnd, NULL, TRUE);
                    }
                    /* Fall through */

                case IDOK:
                    GetUpdateStatus(hDlg);
                    EcdDelete(lpObjectUndo);
                  lpObjectUndo = NULL;
              hwnd = GetTopChild();
                  hitem = GetWindowWord(hwnd, 0);
                  pitem = (PITEM) LocalLock(hitem);
              if (pitem->wType != IDM_PASTE)
                SetData(pitem, hDlg);
              LocalUnlock(hitem);
              GlobalFree(hWinTitle);
                    EndDialog(hDlg, TRUE);
                    return TRUE;

                case IDCANCEL:
              hwnd = GetTopChild();

                    hitem = GetWindowWord(hwnd, 0);
                    pitem = (PITEM) LocalLock(hitem);
                    if (lpObjectUndo)
                        {
                        EcdDelete(pitem->lpecdobject);
                        pitem->lpecdobject = lpObjectUndo;
                        pitem->wType = wTypeUndo;
                        pitem->wUpdate  = wUpdateUndo;
                        }
                    LocalUnlock(hitem);
            InvalidateRect(hwnd, NULL, TRUE);
              GlobalFree(hWinTitle);
                    EndDialog(hDlg, TRUE);
                    return TRUE;
                }
            break;
        }
    return (FALSE);
}


//---------------------------------------------------------------------------
// GetUpdateStatus
// Purpose: Read the status of the update buttons in the Properties Dialog
//          associate to a linked object.
//          Updates the internal data structures and inform the dll.
// Return: void
//---------------------------------------------------------------------------
void GetUpdateStatus(HWND hDlg)
{
    WORD wUpdate;
    HWND hwnd;
    HANDLE hitem;
    PITEM pitem;
   ECDSTATUS EcdRet;
   ECDOPT_UPDATE EcdOpt;


  hwnd = GetTopChild();
    hitem = GetWindowWord(hwnd, 0);
    pitem = (PITEM) LocalLock(hitem);
    if (pitem->wType == IDM_LINK)
        {
        wUpdate = (IsDlgButtonChecked(hDlg, IDD_AUTO) ?
            IDD_AUTO : IDD_MANUAL);
        if (wUpdate != pitem->wUpdate)
            {
            pitem->wUpdate = wUpdate;
        EcdRet = EcdGetLinkUpdateOptions(pitem->lpecdobject,
          (ECDOPT_UPDATE FAR *)&EcdOpt);
        if ((wUpdate == IDD_AUTO )&& (EcdOpt != ecdupdate_always))
          EcdSetLinkUpdateOptions(pitem->lpecdobject, ecdupdate_always);
        else if ((wUpdate == IDD_MANUAL) && (EcdOpt != ecdupdate_oncall))
          EcdSetLinkUpdateOptions(pitem->lpecdobject, ecdupdate_oncall);
            }
        }
    LocalUnlock(hitem);
}

//---------------------------------------------------------------------------
// PrepareUndo
// Purpose: Keep track of the current object to be able to Undo later
// Return: void
//---------------------------------------------------------------------------
void PrepareUndo(PITEM pitem)
{
    // Delete the old copy of the object if necessary
    if (lpObjectUndo)
        EcdDelete(lpObjectUndo);

    // Create a copy of the current object
    if (EcdClone(pitem->lpecdobject, lpclient,
        NULL, NULL, (LPECDOBJECT FAR *)&lpObjectUndo) != ECD_OK)
        lpObjectUndo = NULL;
    else
        {
        wUpdateUndo = pitem->wUpdate;
        wTypeUndo = pitem->wType;
        }
}


//---------------------------------------------------------------------------
// PrepareUndoClear
// Purpose: Keep track of the current object to be able to Undo later
// Return: void
//---------------------------------------------------------------------------
void PrepareUndoClear(PITEM pitem)
{
  PITEM pObjectUndo;
    // Delete the old copy of the object if necessary
    if (hObjectUndo){
    pObjectUndo = (PITEM)LocalLock(hObjectUndo);
    EcdDelete(pObjectUndo->lpecdobject);
    }
  else {
    hObjectUndo = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITEM));
    pObjectUndo = (PITEM) LocalLock(hObjectUndo);
      }
    // Create a copy of the current object
    if (EcdClone(pitem->lpecdobject, lpclient,
        NULL, NULL, (LPECDOBJECT FAR *)&pObjectUndo->lpecdobject) != ECD_OK)
    LocalUnlock(hObjectUndo);
    LocalFree(hObjectUndo);
      hObjectUndo = NULL;
    }
  else{
    pObjectUndo->wType = pitem->wType;
    pObjectUndo->wUpdate = pitem->wUpdate;
    LocalUnlock(hObjectUndo);
    }
}

//---------------------------------------------------------------------------
// ReadStream
// Purpose: Read from an open file
//---------------------------------------------------------------------------
LONG FAR PASCAL ReadStream(LPAPPSTREAM lpStream, LPSTR lpstr, LONG cb)
{
    return _lread(lpStream->fh, lpstr, (WORD)cb);
}

//---------------------------------------------------------------------------
// WriteStream
// Purpose: Write to an open file
//---------------------------------------------------------------------------
LONG FAR PASCAL WriteStream(LPAPPSTREAM lpStream, LPSTR lpstr, LONG cb)
{
    return _lwrite(lpStream->fh, lpstr, (WORD)cb);
}

//---------------------------------------------------------------------------
// PosStream
// Purpose: Reposition file pointer
//---------------------------------------------------------------------------
LONG FAR PASCAL PosStream(LPAPPSTREAM lpStream, LONG pos)
{
    return  _llseek(lpStream->fh, (LONG)pos, 0);
}

//---------------------------------------------------------------------------
// StatusStream
// Purpose: Returns the status of a file operation
// Returns: NULL (Not implemented)
//---------------------------------------------------------------------------
WORD FAR PASCAL StatusStream(LPAPPSTREAM lpStream)
{
    return NULL;
}


VOID SetRectSize(HWND hwnd, PITEM pitem){
  RECT rc, rc1;
  HDC hDC;
  short mm;

  if (!IsIconic(hwnd)){
    GetWindowRect(hwnd, &rc1);
      ScreenToClient(hwndMain, (LPPOINT) &rc1);
    hDC = GetDC(hwnd);
    mm = SetMapMode(hDC, MM_HIMETRIC);
    EcdQueryBounds(pitem->lpecdobject, &rc);
    LPtoDP(hDC, (LPPOINT)&rc, 2);
    SetMapMode(hDC, mm);
    if ((rc.right - rc.left == 0) || (rc.bottom - rc.top == 0)){
      rc.right = 200 ;
      rc.bottom = 200;
      rc.left = 0;
      rc.top = 0;
      }
    MoveWindow(hwnd, rc1.left, rc1.top, rc.right - rc.left,
      rc.bottom - rc.top + GetSystemMetrics(SM_CYCAPTION), TRUE);
    ReleaseDC(hwnd, hDC);
    }

}



/* Combine This function with PrintWindowTitle, lots of problems */

void PrintLinkName(PITEM pitem, HWND hwnd){

  ECDSTATUS EcdStat;
    LPSTR pTitle, pTitle1;
   LPSTR lpstrInfo, lpstr1, lpstr2;
  HSTR hstr;

            if (((EcdStat = EcdGetData(pitem->lpecdobject,
                    (pitem->wType == IDM_PASTE) ? cfOwnerLink : cfLink,
                    &hstr))
                    == ECD_OK)
                && hstr)
                {
                // Both link formats are:  "szClass szDocument szItem 0"
                lpstrInfo = GlobalLock(hstr);
           lpstr1 = lpstrInfo;
           hWinTitle = GlobalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, 512);
           pTitle = pTitle1 = (LPSTR)GlobalLock(hWinTitle);
           while (*lpstr1){
            *(pTitle++) = *(lpstr1++);
            }
           *(pTitle++) = '\0';
           lpstr1 += 1;
                SetWindowText(GetDlgItem(hwnd, IDD_LINKINFO), (LPSTR)pTitle1)
           nOffDocNm = pTitle - pTitle1;
          pTitle1 = pTitle;
           while (*lpstr1){
            *(pTitle++) = *(lpstr1++);
            }
           *(pTitle++) = '\0';
           lpstr1 += 1;
                SetWindowText(GetDlgItem(hwnd, IDD_DOCNM), (LPSTR)pTitle1);

          nOffItemNm = pTitle - pTitle1 + nOffDocNm;
          pTitle1 = pTitle;
           while (*lpstr1){
            *(pTitle++) = *(lpstr1++);
            }
           *(pTitle++) = '\0';
           lpstr1 += 1;
                SetWindowText(GetDlgItem(hwnd, IDD_ITEMNM), (LPSTR)pTitle1);

           GlobalUnlock(hWinTitle);
//          LocalFree(hWinTitle);
               GlobalUnlock(hstr);
                }
          }

void SetData(PITEM pitem, HWND hDlg){
    char szObj[128];
    BOOL fSet = FALSE;
    LPSTR lpWinTitle;
    ECDSTATUS EcdStat;

    lpWinTitle = GlobalLock(hWinTitle);
    GetDlgItemText(hDlg, IDD_DOCNM, (LPSTR)szObj, 128);
    if (lstrcmpi((LPSTR)szObj, (LPSTR)(lpWinTitle + nOffDocNm))){
      lstrcpy((LPSTR)(lpWinTitle + nOffDocNm), (LPSTR)szObj);
      fSet = TRUE;
      }
    GetDlgItemText(hDlg, IDD_ITEMNM, (LPSTR)szObj, 128);
    if (lstrcmp((LPSTR)szObj, (LPSTR)(lpWinTitle + nOffItemNm))){
      lstrcpy((LPSTR)(lpWinTitle + nOffItemNm), (LPSTR)szObj);
      fSet = TRUE;
      }
    GlobalUnlock(hWinTitle);
    if (fSet){
      EcdStat = EcdSetData(pitem->lpecdobject,
                    (pitem->wType == IDM_PASTE) ? cfOwnerLink : cfLink,
              hWinTitle);
      PrintError(EcdStat);
      }
    }





SERVER.C
CD-ROM Disc Path:   \SAMPCODE\OLE\MISHAPES\SERVER.C

#define SERVERONLY
#include "windows.h"
#include "ecd.h"
#include "shapes.h"

//////////////////////////////////////////////////////////////////////////
//
// (c) Copyright Microsoft Corp. 1990 - All Rights Reserved
//
/////////////////////////////////////////////////////////////////////////


// We alis the null item with the very first item in the file.
// Since we never copy more than one item to clip board, there
// is no problem for the objects being edited. If they are created
// from template, we give the first child window back.


extern      HANDLE  hInst;

extern      char    *pcolors[];
extern      char    *pshapes[];
extern      HBRUSH  hbrColor [5];

extern      WORD    cfLink;
extern      WORD    cfOwnerLink;
extern      WORD    cfNative;

extern      WORD    cShapes;

ECDDOCUMENTVTBL     docVTbl;
ECDOBJECTVTBL       itemVTbl;
ECDSERVERVTBL       srvrVTbl;


void FreeVTbls ()
{

    FreeProcInstance(srvrVTbl.Open);
    FreeProcInstance(srvrVTbl.Create);
    FreeProcInstance(srvrVTbl.CreateFromTemplate);
    FreeProcInstance(srvrVTbl.Edit);
    FreeProcInstance(srvrVTbl.Exit);
    FreeProcInstance(srvrVTbl.Release);

    FreeProcInstance (docVTbl.Save);
    FreeProcInstance (docVTbl.Close);
    FreeProcInstance (docVTbl.GetObject);
    FreeProcInstance (docVTbl.Release);

    FreeProcInstance (docVTbl.SetHostNames);
    FreeProcInstance (docVTbl.SetDocDimensions);


    FreeProcInstance (itemVTbl.Show);
    FreeProcInstance (itemVTbl.GetData);
    FreeProcInstance (itemVTbl.SetData);
    FreeProcInstance (itemVTbl.Delete);
    FreeProcInstance (itemVTbl.SetTargetDevice);
    FreeProcInstance (itemVTbl.EnumFormats);

}

void InitVTbls ()
{

    // srvr vtable.

    srvrVTbl.Open    = MakeProcInstance(SrvrOpen, hInst);
    srvrVTbl.Create  = MakeProcInstance(SrvrCreate, hInst);
    srvrVTbl.CreateFromTemplate = MakeProcInstance(SrvrCreateFromTemplate, hI
    srvrVTbl.Edit    = MakeProcInstance(SrvrEdit, hInst);
    srvrVTbl.Exit    = MakeProcInstance(SrvrExit, hInst);
    srvrVTbl.Release = MakeProcInstance(SrvrRelease, hInst);

    // doc table
    docVTbl.Save       = MakeProcInstance(DocSave, hInst);
    docVTbl.Close      = MakeProcInstance(DocClose, hInst);
    docVTbl.GetObject  = MakeProcInstance(DocGetObject, hInst);
    docVTbl.Release    = MakeProcInstance(DocRelease, hInst);

    docVTbl.SetHostNames        = MakeProcInstance(DocSetHostNames, hInst);
    docVTbl.SetDocDimensions    = MakeProcInstance(DocSetDocDimensions, hInst

    // item table.

    itemVTbl.Show      = MakeProcInstance (ItemOpen, hInst);
    itemVTbl.GetData   = MakeProcInstance (ItemGetData, hInst);
    itemVTbl.SetData   = MakeProcInstance (ItemSetData, hInst);
    itemVTbl.Delete    = MakeProcInstance (ItemDelete, hInst);

    itemVTbl.SetTargetDevice =  MakeProcInstance (ItemSetTargetDevice, hInst)
    itemVTbl.EnumFormats =  MakeProcInstance (ItemEnumFormats, hInst);

}

BOOL ProcessCmdLine (hwnd, lpcmdline)
LPSTR   lpcmdline;
HWND    hwnd;
{

    // Look for any file name on the command line.
    char    buf[100];
    int      i;

    while (*lpcmdline){
        // skip blanks
        while ( *lpcmdline && *lpcmdline == ' ')
            lpcmdline++;

        if (*lpcmdline == '-' || *lpcmdline == '/'){
            // skip the options.
            while ( *lpcmdline && *lpcmdline != ' ')
                lpcmdline++;


        } else {
            // looks like we found the file name. terminate with NULL and
            // open the document.

            // !!! check for the buffer limits.

            i = 0;
            while ( *lpcmdline && *lpcmdline != ' ')
                buf[i++] =*lpcmdline++;

            buf[i] = 0;

           // now open the document.
           if(CreateDocFromFile ((PSRVR)GetWindowLong (hwnd, 0),
                (LPSTR)buf, NULL))
                return TRUE;
            else
                return FALSE;
        }
    }
    return TRUE;


}

BOOL InitServer (hwnd, hInst)
HWND    hwnd;
HANDLE  hInst;
{


    HANDLE      hsrvr = NULL;
    PSRVR       psrvr = NULL;
    int         retval;

    hsrvr = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (SRVR));

    if (hsrvr == NULL || (psrvr = (PSRVR) LocalLock (hsrvr)) == NULL)
        goto errRtn;

    psrvr->hsrvr = hsrvr;

    psrvr->ecdsrvr.lpvtbl = &srvrVTbl;

    retval = EcdRegisterServer ((LPSTR)"miShapes", (LPECDSERVER)psrvr,
                (LONG FAR *) &psrvr->lhsrvr, hInst, ECD_SRVR_MULTI);


    if (retval != ECD_OK)
        goto errRtn;

    psrvr->hwnd = hwnd;        // corresponding main window
    SetWindowLong (hwnd, 0, (LONG)(LPSRVR)psrvr);
    return TRUE;

errRtn:
    if (psrvr)
        LocalUnlock (hsrvr);

    if (hsrvr)
        LocalFree (hsrvr);

    return FALSE;

}

int     FAR     PASCAL SrvrRelease (lpecdsrvr)
LPECDSERVER   lpecdsrvr;
{

    PSRVR   psrvr;
    HANDLE  hsrvr;
    HWND    hwnd;


    psrvr = (PSRVR)((LPSRVR)lpecdsrvr);

    if (psrvr->lhsrvr)
        DeleteServer (psrvr);

    else {
        // This delete server should release the server immediately
        hwnd = psrvr->hwnd;
        LocalUnlock (hsrvr = psrvr->hsrvr);
        LocalFree (hsrvr);
        DestroyWindow(hwnd);
    }
    return TRUE;    // return something
}

void DeleteServer (psrvr)
PSRVR   psrvr;
{
     LHSERVER lhsrvr;


#ifdef TEST
     EcdRevokeServer ((LHSERVER)psrvr);
#else

     lhsrvr = psrvr->lhsrvr;
     psrvr->lhsrvr = NULL;
     if (lhsrvr){
        ShowWindow (psrvr->hwnd, FALSE);
        EcdRevokeServer (lhsrvr);
     }
#endif
}

int     FAR     PASCAL SrvrOpen (lpecdsrvr, lhdoc, lpdocname, lplpecddoc)
LHDOCUMENT     lhdoc;
LPECDSERVER    lpecdsrvr;
LPSTR          lpdocname;
LPECDDOCUMENT FAR *lplpecddoc;
{
    PDOC    pdoc;


    PROBE_BUSY(bBusy);

    // errors are not taken care properly
    if(!(pdoc = CreateDocFromFile ((PSRVR)((LPSRVR)lpecdsrvr), lpdocname, lhd
        return ECD_ERROR_MEMORY;

    *lplpecddoc = (LPECDDOCUMENT)pdoc;
    return ECD_OK;

}


int     FAR     PASCAL SrvrCreate (lpecdsrvr, lhdoc, lpclassname, lpdocname,
LHDOCUMENT         lhdoc;
LPECDSERVER   lpecdsrvr;
LPSTR         lpclassname;
LPSTR         lpdocname;
LPECDDOCUMENT  FAR *lplpecddoc;
{

   PDOC pdoc;
   // errors are not taken care properly

   PROBE_BUSY(bBusy);

   if (!(pdoc = CreateNewDoc ((PSRVR)lpecdsrvr, lhdoc, lpdocname)))
        return ECD_ERROR_MEMORY;

   CreateNewItem (pdoc, IDM_RECT, IDM_RED, TRUE);
   *lplpecddoc = (LPECDDOCUMENT)pdoc;

   return ECD_OK;

}

int     FAR     PASCAL SrvrCreateFromTemplate (lpecdsrvr, lhdoc, lpclassname,
LHDOCUMENT    lhdoc;
LPECDSERVER   lpecdsrvr;
LPSTR         lpclassname;
LPSTR         lpdocname;
LPSTR         lptemplatename;
LPECDDOCUMENT  FAR *lplpecddoc;
{

    PDOC    pdoc;

    PROBE_BUSY(bBusy);

    if(!(pdoc = CreateDocFromFile ((PSRVR)lpecdsrvr, lptemplatename, lhdoc)))
        return ECD_ERROR_MEMORY;

    ChangeDocName (pdoc, (LPSTR)lptemplatename);
    *lplpecddoc = (LPECDDOCUMENT)pdoc;
    return ECD_OK;

}

int     FAR     PASCAL SrvrEdit (lpecdsrvr, lhdoc, lpclassname, lpdocname, lp
LHDOCUMENT    lhdoc;
LPECDSERVER   lpecdsrvr;
LPSTR         lpclassname;
LPSTR         lpdocname;
LPECDDOCUMENT  FAR *lplpecddoc;
{

   PDOC pdoc;

   PROBE_BUSY(bBusy);

   // errors are not taken care properly

   if (!(pdoc = CreateNewDoc ((PSRVR)lpecdsrvr, lhdoc, lpdocname)))
        return ECD_ERROR_MEMORY;

   *lplpecddoc = (LPECDDOCUMENT)pdoc;

   return ECD_OK;


}

int     FAR     PASCAL SrvrExit (lpecdsrvr)
LPECDSERVER   lpecdsrvr;
{

    // Server lib is calling us to exit.
    // Let us hide the main window.
    // But let us not delete the window.
    PSRVR   psrvr;

    PROBE_BUSY(bBusy);

    psrvr = (PSRVR)lpecdsrvr;

    ShowWindow (psrvr->hwnd, FALSE);
    EcdRevokeServer (psrvr->lhsrvr);
    return ECD_OK;



}

// doucment functions.

PDOC    InitDoc (hwnd, lhdoc)
HWND        hwnd;
LHDOCUMENT  lhdoc;
{
    HANDLE      hdoc = NULL;
    PDOC        pdoc = NULL;
    char        buf[128];
    PSRVR       psrvr;



    hdoc = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (DOC));

    if (hdoc == NULL || (pdoc = (PDOC) LocalLock (hdoc)) == NULL)
        goto errRtn;

    pdoc->hdoc = hdoc;
    pdoc->hwnd = hwnd;        // corresponding main window

    psrvr = (PSRVR)GetWindowLong (GetParent (hwnd), 0);
    GetWindowText (hwnd, (LPSTR)buf, 128);
    if (lhdoc == NULL){
        if (EcdRegisterDocument (psrvr->lhsrvr, (LPSTR)buf, (LPECDDOCUMENT)pd
            (LHDOCUMENT FAR *)&pdoc->lhdoc) != ECD_OK)
            goto errRtn;
    } else
        pdoc->lhdoc = lhdoc;

    pdoc->aName = GlobalAddAtom ((LPSTR)buf);
    SetWindowLong (hwnd, 0, (LONG)pdoc);

    pdoc->ecddoc.lpvtbl = &docVTbl;

    // set the anchor point for children
    pdoc->ptAnchor.x = 0;
    pdoc->ptAnchor.y = 0;

    return pdoc;

errRtn:

    if (pdoc)
        LocalUnlock (hdoc);

    if (hdoc)
        LocalFree;

    return (PDOC)NULL;

}


int FAR PASCAL  DocSave (lpecddoc)
LPECDDOCUMENT    lpecddoc;
{

    PROBE_BUSY(bBusy);
    // not yet implemented
    return ECD_OK;


}

void DeleteDoc (pdoc)
PDOC    pdoc;
{
    LHDOCUMENT   lhdoc;

#ifdef TEST
    EcdRevokeDocument ((LHDOCUMENT)pdoc);

#else
    lhdoc = pdoc->lhdoc;
    pdoc->lhdoc = NULL;
    if (lhdoc) {
        ShowWindow (pdoc->hwnd, FALSE);
        EcdRevokeDocument (lhdoc);
    }
#endif

}


int FAR PASCAL  DocClose (lpecddoc)
LPECDDOCUMENT    lpecddoc;
{
    PDOC    pdoc;

    PROBE_BUSY(bBusy);
    pdoc = (PDOC)lpecddoc;

    SendDocChangeMsg (pdoc, ECD_CLOSED);
    DeleteDoc (pdoc);
    return ECD_OK;

}

int FAR PASCAL DocSetHostNames(lpecddoc, lpclientName, lpdocName)
LPECDDOCUMENT    lpecddoc;
LPSTR            lpclientName;
LPSTR            lpdocName;
{


    PDOC    pdoc;
    char    buf[200];
    int     len;
    HWND    hwnd;

    PROBE_BUSY(bBusy);

    // Do something to show that the titiel are chaning
    pdoc = (PDOC)lpecddoc;
    hwnd = pdoc->hwnd;

    SetWindowText (hwnd, lpdocName);;

    hwnd = GetParent (hwnd);
    lstrcpy ((LPSTR)buf, lpclientName);
    lstrcat ((LPSTR)buf, (LPSTR)":");
    lstrcat ((LPSTR)buf, (LPSTR)"Sample mishapes server application");
    len = lstrlen ((LPSTR)buf);
    SetWindowText (hwnd, (LPSTR)buf);

    return ECD_OK;

}
int FAR PASCAL DocSetDocDimensions(lpecddoc, lprc)
LPECDDOCUMENT   lpecddoc;
LPRECT  lprc;
{
    PROBE_BUSY(bBusy);
    return ECD_OK;


}

int FAR PASCAL  DocRelease (lpecddoc)
LPECDDOCUMENT    lpecddoc;
{

    // !!! what is this supposed to do?
    // Revoke document calls DocRelease.

    PDOC    pdoc;
    HANDLE  hdoc;
    HWND    hwnd;


    PROBE_BUSY(bBusy);

    pdoc = (PDOC)lpecddoc;
    GlobalDeleteAtom (pdoc->aName);
    hwnd = pdoc->hwnd;
    LocalUnlock (hdoc = pdoc->hdoc);
    LocalFree (hdoc);
    DestroyWindow(hwnd);
    return TRUE;        // return something

}

int ChangeDocName (pdoc, lpname)
PDOC    pdoc;
LPSTR   lpname;
{

    GlobalDeleteAtom (pdoc->aName);
    pdoc->aName = GlobalAddAtom (lpname);
    SetWindowText (pdoc->hwnd, lpname);
    return TRUE;        // return something

}


int FAR PASCAL  DocGetObject (lpecddoc, lpitemname, lplpecdobject, lpecdclien
LPECDDOCUMENT       lpecddoc;
LPSTR               lpitemname;
LPECDOBJECT FAR *   lplpecdobject;
LPECDCLIENT         lpecdclient;
{
    PDOC    pdoc;
    HWND    hwnd;
    ATOM    aName;
    PITEM   pitem;


    PROBE_BUSY(bBusy);

    pdoc  = (PDOC)lpecddoc;
    aName = GlobalFindAtom (lpitemname);
    hwnd = GetWindow ((hwnd = pdoc->hwnd), GW_CHILD);

    // go thru all the child window list and find the window which is
    // matching the given item name.

    while (hwnd){

       // !!! We are trying to match the doc item with any item
       // OK only if there is only one item in a doc. Otherwise
       // we will be in troubles. Should work without any problems.
       // for embedded objects.

        pitem = (PITEM)GetWindowLong (hwnd, 0);

        // Alias the null with the very first item
        if (pitem->aName == aName || pitem->aName == NULL || aName == NULL)
            goto rtn;

        hwnd = GetWindow (hwnd, GW_HWNDNEXT);
    }
    // we did not find the item we wanted. So, create one

    // create a window with empty native data.

    if (CreateNewItem (pdoc, IDM_RECT, IDM_RED, FALSE)) {
        // newly created window is always the first child
        pitem = (PITEM)GetWindowLong (GetWindow (pdoc->hwnd, GW_CHILD), 0);
        BringWindowToTop (pitem->hwnd);
    } else
        return ECD_ERROR_MEMORY;
rtn:
    pitem->aName = GlobalAddAtom (lpitemname);
    // If the item is not null, then do not show the window.
    *lplpecdobject = (LPECDOBJECT)pitem;
    pitem->lpecdclient = lpecdclient;
    return ECD_OK;

}


// item related routines

void SetNewItemName (pitem)
PITEM   pitem;
{
    char    buf[3];

    lstrcpy ((LPSTR)pitem->name, (LPSTR)"Shape #");


    if (cShapes++ > 100)
        cShapes = 1;

    buf[0] = (char)((cShapes / 10)  + (int)'0');
    buf[1] = (char)((cShapes % 10)  + (int)'0');
    buf[2] = 0;

    lstrcat ((LPSTR)pitem->name, (LPSTR)buf);
    pitem->aName = GlobalAddAtom ((LPSTR)pitem->name);
}

void SetItemName (pitem, lpname)
PITEM   pitem;
LPSTR   lpname;
{
    pitem->aName = GlobalAddAtom (lpname);
    lstrcpy ((LPSTR)pitem->name, lpname);
}

void CutCopyItem (hwnd)
HWND    hwnd;
{
    PITEM       pitem;

    if (OpenClipboard (hwnd)){

        EmptyClipboard ();

        // firt set the clipboard

        pitem = (PITEM) GetWindowLong (GetWindow(
                GetWindow (hwnd, GW_CHILD), GW_CHILD), 0);

        // Check for null handles from the render routines.
        SetClipboardData (CF_METAFILEPICT, GetPicture (pitem));
        SetClipboardData (CF_BITMAP, GetBitmap (pitem));
        SetClipboardData (cfNative, GetNative (pitem));
        SetClipboardData (cfLink, GetLink (pitem));
        SetClipboardData (cfOwnerLink, GetLink (pitem));
        CloseClipboard ();
    }


}

HANDLE  GetNative (pitem)
PITEM   pitem;
{


    LPSTR       lpsrc;
    LPSTR       lplink = NULL;
    HANDLE      hlink = NULL;
    int         i;



    hlink = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, sizeof (ITEM));
    if (hlink== NULL || (lplink = (LPSTR)GlobalLock (hlink)) == NULL)
        goto errRtn;

    lpsrc = (LPSTR)pitem;
    for (i = 0; i <  sizeof(ITEM); i++)
        *lplink++ = *lpsrc++;

    GlobalUnlock (hlink);
    return hlink;

errRtn:
    if (lplink)
        GlobalUnlock (hlink);

    if (hlink)
        GlobalFree (hlink);

}

HANDLE  GetLink (pitem)
PITEM   pitem;
{

    char        buf[128];
    LPSTR       lpsrc;
    LPSTR       lplink = NULL;
    HANDLE      hlink = NULL;
    int         len;
    int         i;

    // make the link
    lstrcpy ((LPSTR)buf, (LPSTR)"miShapes");
    len = lstrlen ((LPSTR)buf) + 1;
    len += GetWindowText (GetParent (pitem->hwnd), (LPSTR)buf + len , 128 - l
    len += GlobalGetAtomName (pitem->aName, (LPSTR)buf + len, 128 - len) + 1;
    buf[len++] = 0;       // throw in another null at the end.


    hlink = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, len);
    if (hlink== NULL || (lplink = (LPSTR)GlobalLock (hlink)) == NULL)
        goto errRtn;

    lpsrc = (LPSTR)buf;
    for (i = 0; i <  len; i++)
        *lplink++ = *lpsrc++;

    GlobalUnlock (hlink);

    return hlink;
errRtn:
    if (lplink)
        GlobalUnlock (hlink);

    GlobalFree (hlink);
    return NULL;
}

HANDLE     GetPicture (pitem)
PITEM       pitem;
{

    LPMETAFILEPICT  lppict = NULL;
    HANDLE          hpict = NULL;
    HANDLE          hMF = NULL;
    HANDLE          hdc;
    RECT            rc;
    HPEN            hpen;
    HPEN            holdpen;
    int             mm;


    // Now set the bitmap data.

    hdc = CreateMetaFile(NULL);

    GetClientRect (pitem->hwnd, (LPRECT)&rc);

    // paint directly into the bitmap
    SelectObject (hdc, hbrColor [ pitem->cmdColor - IDM_RED]);
    PatBlt (hdc, 0,0, rc.right, rc.bottom, WHITENESS);
    SetWindowOrg (hdc, 0, 0);
    SetWindowExt (hdc, rc.right, rc.bottom);


    hpen = CreatePen (PS_SOLID, 9, 0x00808080);
    holdpen = SelectObject (hdc, hpen);

    switch (pitem->cmdShape){
        case IDM_ROUNDRECT:
            RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

        case IDM_RECT:
            Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWRECT:
            SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
            Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWROUNDRECT:
            SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
            RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

    }

    hMF = CloseMetaFile (hdc);

    if(!(hpict = GlobalAlloc (GMEM_DDESHARE, sizeof (METAFILEPICT))))
        goto errRtn;

    if ((lppict = (LPMETAFILEPICT)GlobalLock (hpict)) == NULL)
        goto errRtn;

    lppict->mm = MM_ANISOTROPIC;
    lppict->hMF = hMF;


    hdc = GetDC (pitem->hwnd);
    mm = SetMapMode(hdc, MM_HIMETRIC);
    DPtoLP(hdc, (LPPOINT)&rc, 2);
    SetMapMode(hdc, mm);
    ReleaseDC (pitem->hwnd, hdc);

    lppict->xExt =  rc.right - rc.left;
    lppict->yExt =  rc.top - rc.bottom;
    GlobalUnlock (hpict);
    return hpict;

errRtn:
    if (lppict)
        GlobalUnlock (hpict);

    if (hpict)
        GlobalFree (hpict);

    if (hMF)
        DeleteMetaFile (hMF);
    return NULL;

}


HBITMAP     GetBitmap (pitem)
PITEM       pitem;
{

    HDC         hdc;
    HDC         hdcmem;
    RECT        rc;
    HBITMAP     hbitmap;
    HBITMAP     holdbitmap;
    HPEN        hpen;
    HPEN        holdpen;


    // Now set the bitmap data.

    hdc = GetDC (pitem->hwnd);
    hdcmem = CreateCompatibleDC (hdc);
    GetClientRect (pitem->hwnd, (LPRECT)&rc);
    hbitmap = CreateCompatibleBitmap (hdc, rc.right - rc.left, rc.bottom - rc
    holdbitmap = SelectObject (hdcmem, hbitmap);

    // paimt directly into the bitmap
    SelectObject (hdcmem, hbrColor [ pitem->cmdColor - IDM_RED]);
    PatBlt (hdcmem, 0,0, rc.right, rc.bottom, WHITENESS);

    hpen = CreatePen (PS_SOLID, 9, 0x00808080);
    holdpen = SelectObject (hdcmem, hpen);

    switch (pitem->cmdShape){
        case IDM_ROUNDRECT:
            RoundRect (hdcmem, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

        case IDM_RECT:
            Rectangle (hdcmem, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWRECT:
            SelectObject (hdcmem, GetStockObject (HOLLOW_BRUSH));
            Rectangle (hdcmem, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWROUNDRECT:
            SelectObject (hdcmem, GetStockObject (HOLLOW_BRUSH));
            RoundRect (hdcmem, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

    }



    hbitmap = SelectObject (hdcmem, holdbitmap);
    hpen = SelectObject (hdcmem, holdpen);
    DeleteObject (hpen);
    DeleteDC (hdcmem);
    ReleaseDC (pitem->hwnd, hdc);
    return hbitmap;

}

PITEM   CreateNewItem (pdoc, cmdShape, cmdColor, bVisible)
PDOC    pdoc;
int     cmdShape;
int     cmdColor;
BOOL    bVisible;
{

    RECT        rc;
    HANDLE      hitem = NULL;
    PITEM       pitem = NULL;
    HWND        hwnd;



    GetClientRect (pdoc->hwnd, (LPRECT)&rc);

    hwnd = CreateWindow(
        "ItemClass",
        "Item",

        WS_DLGFRAME| WS_CHILD | WS_CLIPSIBLINGS |
                    (bVisible ? WS_VISIBLE : 0),
        pdoc->ptAnchor.x,
        pdoc->ptAnchor.y,
        (rc.right - rc.left) >> 1,
        (rc.bottom - rc.top)>> 1,
        pdoc->hwnd,
        NULL,
        hInst,
        NULL
    );


    if (!hwnd)
        return (FALSE);

    pdoc->ptAnchor.x += 20;
    pdoc->ptAnchor.y += 20;


    // Now create the item info;
    hitem = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITEM));

    if (hitem == NULL || ((pitem = (PITEM)LocalLock (hitem)) == NULL))
        goto  errRtn;

    pitem->cmdShape = cmdShape;;
    pitem->cmdColor = cmdColor;
    pitem->hitem    = hitem;
    pitem->aName    = NULL;
    pitem->hwnd     = hwnd;
    pitem->ecdobject.lpvtbl = &itemVTbl;

    pitem->width    = (rc.right - rc.left) >> 1;
    pitem->height   = (rc.bottom - rc.top) >> 1;

    SetWindowLong (hwnd, 0, (LONG)pitem);
    return pitem;

 errRtn:
    if (pitem)
        LocalUnlock (hitem);

    if (hitem)
        LocalFree (hitem);

    return (PITEM)NULL;

}

int FAR PASCAL  ItemOpen (lpecdobject)
LPECDOBJECT     lpecdobject;
{

    // !!! This routine should activate the app
    // and prepare it ready for the editing. Activation
    // should bring on to the top and restore


    PITEM   pitem;
    HWND    hwnd;

    PROBE_BUSY(bBusy);
    pitem = (PITEM)lpecdobject;
    BringWindowToTop (pitem->hwnd);
    BringWindowToTop (GetParent (pitem->hwnd));
    SetActiveWindow ((hwnd = GetParent (GetParent (pitem->hwnd))));
    SendMessage (hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L);
    return ECD_OK;


}


int FAR PASCAL  ItemDelete (lpecdobject)
LPECDOBJECT     lpecdobject;
{

    PITEM   pitem;

    PROBE_BUSY(bBusy);
    pitem = (PITEM)lpecdobject;
    if (--pitem->ref)
        return ECD_OK;

    if (IsWindow(pitem->hwnd))
        DestroyWindow (pitem->hwnd);
    return ECD_OK;
}


int FAR PASCAL  ItemGetData (lpecdobject, cfFormat, lphandle)
LPECDOBJECT     lpecdobject;
WORD            cfFormat;
LPHANDLE        lphandle;
{

    PITEM   pitem;

    // PROBE_BUSY(bBusy);

    // asking data for emtyp object.
    pitem = (PITEM)lpecdobject;

    if (pitem->cmdShape  == NULL||
        pitem->cmdColor == NULL)
        return ECD_ERROR_MEMORY;

    if (cfFormat == cfNative){

        if (!(*lphandle = GetNative (pitem)))
            return ECD_ERROR_MEMORY;

        return ECD_OK;
    }


    if (cfFormat == CF_BITMAP){

        if (!(*lphandle = (HANDLE)GetBitmap (pitem)))
            return ECD_ERROR_MEMORY;

        return ECD_OK;
    }

    if (cfFormat == CF_METAFILEPICT){

        if (!(*lphandle = GetPicture (pitem)))
            return ECD_ERROR_MEMORY;

        return ECD_OK;
    }

    if (cfFormat == cfLink || cfFormat == cfOwnerLink){

        if (!(*lphandle = GetLink (pitem)))
            return ECD_ERROR_MEMORY;

        return ECD_OK;
    }
    return ECD_ERROR_MEMORY;          // this is actually unknow format.

}


int FAR PASCAL   ItemSetTargetDevice (lpecdobject, hdata)
LPECDOBJECT     lpecdobject;
HANDLE          hdata;
{
    LPSTR   lpdata;

    lpdata = (LPSTR)GlobalLock (hdata);
    // Print the lpdata here.
    GlobalUnlock (hdata);
    GlobalFree (hdata);
    return ECD_OK;

}

int FAR PASCAL  ItemSetData (lpecdobject, cfFormat, hdata)
LPECDOBJECT     lpecdobject;
WORD            cfFormat;
HANDLE          hdata;
{

    LPITEM   lpitem;
    PITEM    pitem;

    PROBE_BUSY(bBusy);
    pitem = (PITEM)lpecdobject;

    if (cfFormat != cfNative)
        return ECD_ERROR_MEMORY;


    lpitem = (LPITEM)GlobalLock (hdata);
    if (lpitem){
        pitem->cmdShape = lpitem->cmdShape;
        pitem->cmdColor = lpitem->cmdColor;
        SetItemName (pitem, (LPSTR)pitem->name);
        // This is not necessary.
        ShowWindow (pitem->hwnd, TRUE);
        InvalidateRect (pitem->hwnd, (LPRECT)NULL, TRUE);
        GlobalUnlock (hdata);
    }

    GlobalFree (hdata);
    return ECD_OK;
}

ECDCLIPFORMAT   FAR PASCAL ItemEnumFormats (lpecdobject, cfFormat)
LPECDOBJECT     lpecdobject;
ECDCLIPFORMAT   cfFormat;
{
    if (cfFormat == 0)
        return cfLink;

    if (cfFormat == cfLink)
        return cfOwnerLink;

    if (cfFormat == cfOwnerLink)
        return CF_BITMAP;

    if (cfFormat == CF_BITMAP)
        return CF_METAFILEPICT;

    if (cfFormat == CF_METAFILEPICT)
        return cfNative;

    //if (cfFormat == cfNative)
    //    return NULL;

    return NULL;
}

BOOL DestroyItem (hwnd)
HWND    hwnd;
{
    PITEM   pitem;
    HANDLE  hitem;


    pitem = (PITEM)GetWindowLong (hwnd, 0);
    if (pitem->aName)
        GlobalDeleteAtom (pitem->aName);

    LocalUnlock (hitem = pitem->hitem);
    LocalFree (hitem);
    return TRUE;        // return something

}

void    PaintItem (hwnd)
HWND    hwnd;
{

    HDC             hdc;
    PITEM           pitem;
    RECT            rc;
    PAINTSTRUCT     ptSt;
    HPEN            hpen;
    HPEN            holdpen;


    BeginPaint (hwnd, (LPPAINTSTRUCT)&ptSt);
    hdc = GetDC (hwnd);

    // Do not paint anything for the whole document item
    // For document item the name is null.

    pitem = (PITEM)GetWindowLong (hwnd, 0);

    GetClientRect (hwnd, (LPRECT)&rc);
    PatBlt (hdc, 0,0, rc.right, rc.bottom, WHITENESS);
    SelectObject (hdc, hbrColor [ pitem->cmdColor - IDM_RED]);
    hpen = CreatePen (PS_SOLID, 9, 0x00808080);
    holdpen = SelectObject (hdc, hpen);

    switch (pitem->cmdShape){
        case IDM_ROUNDRECT:
            RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

        case IDM_RECT:
            Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWRECT:
            SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
            Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWROUNDRECT:
            SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
            RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

    }

    hpen = SelectObject (hdc, holdpen);
    DeleteObject (hpen);

    ReleaseDC (hwnd, hdc);
    EndPaint (hwnd, (LPPAINTSTRUCT)&ptSt);
}



void    SendSrvrChangeMsg (psrvr, options)
PSRVR   psrvr;
WORD    options;
{

    HWND    hwnd;

    // if we are releasing the document, do not do anything
    if (psrvr->lhsrvr == NULL)
        return;

    hwnd = GetWindow (psrvr->hwnd, GW_CHILD);
    while (hwnd){
        SendDocChangeMsg ((PDOC)GetWindowLong (hwnd, 0), options);
        hwnd = GetWindow (hwnd, GW_HWNDNEXT);

    }

}

void    SendDocRenameMsg (psrvr, options)
PSRVR   psrvr;
WORD    options;
{

    HWND    hwnd;
    PITEM   pitem;
    PDOC    pdoc;
    char    buf[128];

    // if we are releasing the document, do not do anything
    if (psrvr->lhsrvr == NULL)
        return;

    hwnd = GetWindow (psrvr->hwnd, GW_CHILD);
    pdoc = (PDOC)GetWindowLong (hwnd, 0);

    // if we are releasing the document, do not do anything
    if (pdoc->lhdoc == NULL)
        return;

    hwnd = GetWindow (pdoc->hwnd, GW_CHILD);

    while (hwnd){
        pitem = (PITEM)GetWindowLong (hwnd, 0);
        // Sending rename to obe item is sufficient
        if (pitem->lpecdclient){
            (*pitem->lpecdclient->lpvtbl->CallBack) (pitem->lpecdclient, opti
                    (LPECDOBJECT)pitem);

            return;
        }
        hwnd = GetWindow (hwnd, GW_HWNDNEXT);
    }

    // reregister the document if there are no callbacks.
    GetWindowText (pdoc->hwnd, (LPSTR)buf, 128);
    DeleteDoc (pdoc);
    CreateDocFromFile (psrvr, (LPSTR)buf, NULL);
    return;
}

void    SendDocChangeMsg (pdoc, options)
PDOC    pdoc;
WORD    options;
{

    HWND    hwnd;

    // if we are releasing the document, do not do anything
    if (pdoc->lhdoc == NULL)
        return;

    hwnd = GetWindow (pdoc->hwnd, GW_CHILD);
    while (hwnd){
        SendItemChangeMsg ((PITEM)GetWindowLong (hwnd, 0), options);
        hwnd = GetWindow (hwnd, GW_HWNDNEXT);

    }

}


void    SendItemChangeMsg (pitem, options)
PITEM   pitem;
WORD    options;
{

    if (pitem->lpecdclient)
        (*pitem->lpecdclient->lpvtbl->CallBack) (pitem->lpecdclient, options,
                (LPECDOBJECT)pitem);
}


SERVER.C
CD-ROM Disc Path:   \SAMPCODE\OLE\SHAPES\SERVER.C

#define SERVERONLY
#include "windows.h"
#include "ecd.h"
#include "shapes.h"

//////////////////////////////////////////////////////////////////////////
//
// (c) Copyright Microsoft Corp. 1990 - All Rights Reserved
//
/////////////////////////////////////////////////////////////////////////


// We alis the null item with the very first item in the file.
// Since we never copy more than one item to clip board, there
// is no problem for the objects being edited. If they are created
// from template, we give the first child window back.


extern      HANDLE  hInst;

extern      char    *pcolors[];
extern      char    *pshapes[];
extern      HBRUSH  hbrColor [5];

extern      WORD    cfLink;
extern      WORD    cfOwnerLink;
extern      WORD    cfNative;

extern      WORD    cShapes;

ECDDOCUMENTVTBL     docVTbl;
ECDOBJECTVTBL       itemVTbl;
ECDSERVERVTBL       srvrVTbl;


void FreeVTbls ()
{

    FreeProcInstance(srvrVTbl.Open);
    FreeProcInstance(srvrVTbl.Create);
    FreeProcInstance(srvrVTbl.CreateFromTemplate);
    FreeProcInstance(srvrVTbl.Edit);
    FreeProcInstance(srvrVTbl.Exit);
    FreeProcInstance(srvrVTbl.Release);

    FreeProcInstance (docVTbl.Save);
    FreeProcInstance (docVTbl.Close);
    FreeProcInstance (docVTbl.GetObject);
    FreeProcInstance (docVTbl.Release);

    FreeProcInstance (docVTbl.SetHostNames);
    FreeProcInstance (docVTbl.SetDocDimensions);


    FreeProcInstance (itemVTbl.Show);
    FreeProcInstance (itemVTbl.GetData);
    FreeProcInstance (itemVTbl.SetData);
    FreeProcInstance (itemVTbl.Delete);
    FreeProcInstance (itemVTbl.SetTargetDevice);
    FreeProcInstance (itemVTbl.EnumFormats);

}

void InitVTbls ()
{

    // srvr vtable.

    srvrVTbl.Open    = MakeProcInstance(SrvrOpen, hInst);
    srvrVTbl.Create  = MakeProcInstance(SrvrCreate, hInst);
    srvrVTbl.CreateFromTemplate = MakeProcInstance(SrvrCreateFromTemplate, hI
    srvrVTbl.Edit    = MakeProcInstance(SrvrEdit, hInst);
    srvrVTbl.Exit    = MakeProcInstance(SrvrExit, hInst);
    srvrVTbl.Release = MakeProcInstance(SrvrRelease, hInst);

    // doc table
    docVTbl.Save       = MakeProcInstance(DocSave, hInst);
    docVTbl.Close      = MakeProcInstance(DocClose, hInst);
    docVTbl.GetObject  = MakeProcInstance(DocGetObject, hInst);
    docVTbl.Release    = MakeProcInstance(DocRelease, hInst);

    docVTbl.SetHostNames        = MakeProcInstance(DocSetHostNames, hInst);
    docVTbl.SetDocDimensions    = MakeProcInstance(DocSetDocDimensions, hInst

    // item table.

    itemVTbl.Show      = MakeProcInstance (ItemOpen, hInst);
    itemVTbl.GetData   = MakeProcInstance (ItemGetData, hInst);
    itemVTbl.SetData   = MakeProcInstance (ItemSetData, hInst);
    itemVTbl.Delete    = MakeProcInstance (ItemDelete, hInst);

    itemVTbl.SetTargetDevice =  MakeProcInstance (ItemSetTargetDevice, hInst)
    itemVTbl.EnumFormats =  MakeProcInstance (ItemEnumFormats, hInst);

}

BOOL ProcessCmdLine (hwnd, lpcmdline)
LPSTR   lpcmdline;
HWND    hwnd;
{

    // Look for any file name on the command line.
    char    buf[100];
    int      i;

    while (*lpcmdline){
        // skip blanks
        while ( *lpcmdline && *lpcmdline == ' ')
            lpcmdline++;

        if (*lpcmdline == '-' || *lpcmdline == '/'){
            // skip the options.
            while ( *lpcmdline && *lpcmdline != ' ')
                lpcmdline++;


        } else {
            // looks like we found the file name. terminate with NULL and
            // open the document.

            // !!! check for the buffer limits.

            i = 0;
            while ( *lpcmdline && *lpcmdline != ' ')
                buf[i++] =*lpcmdline++;

            buf[i] = 0;

           // now open the document.
           if(CreateDocFromFile ((PSRVR)GetWindowLong (hwnd, 0),
                (LPSTR)buf, NULL))
                return TRUE;
            else
                return FALSE;
        }
    }
    return TRUE;


}

BOOL InitServer (hwnd, hInst)
HWND    hwnd;
HANDLE  hInst;
{


    HANDLE      hsrvr = NULL;
    PSRVR       psrvr = NULL;
    int         retval;

    hsrvr = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (SRVR));

    if (hsrvr == NULL || (psrvr = (PSRVR) LocalLock (hsrvr)) == NULL)
        goto errRtn;

    psrvr->hsrvr = hsrvr;

    psrvr->ecdsrvr.lpvtbl = &srvrVTbl;

    retval = EcdRegisterServer ((LPSTR)"Shapes", (LPECDSERVER)psrvr,
                (LONG FAR *) &psrvr->lhsrvr, hInst, ECD_SRVR_SINGLE);


    if (retval != ECD_OK)
        goto errRtn;

    psrvr->hwnd = hwnd;        // corresponding main window
    SetWindowLong (hwnd, 0, (LONG)(LPSRVR)psrvr);
    return TRUE;

errRtn:
    if (psrvr)
        LocalUnlock (hsrvr);

    if (hsrvr)
        LocalFree (hsrvr);

    return FALSE;

}

int     FAR     PASCAL SrvrRelease (lpecdsrvr)
LPECDSERVER   lpecdsrvr;
{

    PSRVR   psrvr;
    HANDLE  hsrvr;
    HWND    hwnd;


    psrvr = (PSRVR)((LPSRVR)lpecdsrvr);
    if (psrvr->lhsrvr)
        DeleteServer (psrvr);

    else {
        // This delete server should release the server immediately
        hwnd = psrvr->hwnd;
        LocalUnlock (hsrvr = psrvr->hsrvr);
        LocalFree (hsrvr);
        DestroyWindow(hwnd);
    }
    return TRUE;    // return something
}

void DeleteServer (psrvr)
PSRVR   psrvr;
{
     LHSERVER lhsrvr;


#ifdef TEST
     EcdRevokeServer ((LHSERVER)psrvr);
#else

     lhsrvr = psrvr->lhsrvr;
     psrvr->lhsrvr = NULL;
     if (lhsrvr){
        ShowWindow (psrvr->hwnd, FALSE);
        EcdRevokeServer (lhsrvr);
     }
#endif
}

int     FAR     PASCAL SrvrOpen (lpecdsrvr, lhdoc, lpdocname, lplpecddoc)
LHDOCUMENT     lhdoc;
LPECDSERVER    lpecdsrvr;
LPSTR          lpdocname;
LPECDDOCUMENT FAR *lplpecddoc;
{
    PDOC    pdoc;


    PROBE_BUSY(bBusy);

    // errors are not taken care properly
    if(!(pdoc = CreateDocFromFile ((PSRVR)((LPSRVR)lpecdsrvr), lpdocname, lhd
        return ECD_ERROR_MEMORY;

    *lplpecddoc = (LPECDDOCUMENT)pdoc;
    return ECD_OK;

}


int     FAR     PASCAL SrvrCreate (lpecdsrvr, lhdoc, lpclassname, lpdocname,
LHDOCUMENT         lhdoc;
LPECDSERVER   lpecdsrvr;
LPSTR         lpclassname;
LPSTR         lpdocname;
LPECDDOCUMENT  FAR *lplpecddoc;
{

   PDOC pdoc;
   // errors are not taken care properly

   PROBE_BUSY(bBusy);

   if (!(pdoc = CreateNewDoc ((PSRVR)lpecdsrvr, lhdoc, lpdocname)))
        return ECD_ERROR_MEMORY;

   CreateNewItem (pdoc, IDM_RECT, IDM_RED, TRUE);
   *lplpecddoc = (LPECDDOCUMENT)pdoc;

   return ECD_OK;

}

int     FAR     PASCAL SrvrCreateFromTemplate (lpecdsrvr, lhdoc, lpclassname,
LHDOCUMENT    lhdoc;
LPECDSERVER   lpecdsrvr;
LPSTR         lpclassname;
LPSTR         lpdocname;
LPSTR         lptemplatename;
LPECDDOCUMENT  FAR *lplpecddoc;
{

    PDOC    pdoc;

    PROBE_BUSY(bBusy);

    if(!(pdoc = CreateDocFromFile ((PSRVR)lpecdsrvr, lptemplatename, lhdoc)))
        return ECD_ERROR_MEMORY;

    ChangeDocName (pdoc, (LPSTR)lptemplatename);
    *lplpecddoc = (LPECDDOCUMENT)pdoc;
    return ECD_OK;

}

int     FAR     PASCAL SrvrEdit (lpecdsrvr, lhdoc, lpclassname, lpdocname, lp
LHDOCUMENT    lhdoc;
LPECDSERVER   lpecdsrvr;
LPSTR         lpclassname;
LPSTR         lpdocname;
LPECDDOCUMENT  FAR *lplpecddoc;
{

   PDOC pdoc;

   PROBE_BUSY(bBusy);

   // errors are not taken care properly

   if (!(pdoc = CreateNewDoc ((PSRVR)lpecdsrvr, lhdoc, lpdocname)))
        return ECD_ERROR_MEMORY;

   *lplpecddoc = (LPECDDOCUMENT)pdoc;

   return ECD_OK;


}

int     FAR     PASCAL SrvrExit (lpecdsrvr)
LPECDSERVER   lpecdsrvr;
{

    // Server lib is calling us to exit.
    // Let us hide the main window.
    // But let us not delete the window.
    PSRVR   psrvr;

    PROBE_BUSY(bBusy);

    psrvr = (PSRVR)lpecdsrvr;

    ShowWindow (psrvr->hwnd, FALSE);
    EcdRevokeServer (psrvr->lhsrvr);
    return ECD_OK;



}

// doucment functions.

PDOC    InitDoc (hwnd, lhdoc)
HWND        hwnd;
LHDOCUMENT  lhdoc;
{
    HANDLE      hdoc = NULL;
    PDOC        pdoc = NULL;
    char        buf[128];
    PSRVR       psrvr;



    hdoc = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (DOC));

    if (hdoc == NULL || (pdoc = (PDOC) LocalLock (hdoc)) == NULL)
        goto errRtn;

    pdoc->hdoc = hdoc;
    pdoc->hwnd = hwnd;        // corresponding main window

    psrvr = (PSRVR)GetWindowLong (GetParent (hwnd), 0);
    GetWindowText (hwnd, (LPSTR)buf, 128);
    if (lhdoc == NULL){
        if (EcdRegisterDocument (psrvr->lhsrvr, (LPSTR)buf, (LPECDDOCUMENT)pd
            (LHDOCUMENT FAR *)&pdoc->lhdoc) != ECD_OK)
            goto errRtn;
    } else
        pdoc->lhdoc = lhdoc;

    pdoc->aName = GlobalAddAtom ((LPSTR)buf);
    SetWindowLong (hwnd, 0, (LONG)pdoc);

    pdoc->ecddoc.lpvtbl = &docVTbl;

    // set the anchor point for children
    pdoc->ptAnchor.x = 0;
    pdoc->ptAnchor.y = 0;

    return pdoc;

errRtn:

    if (pdoc)
        LocalUnlock (hdoc);

    if (hdoc)
        LocalFree;

    return (PDOC)NULL;

}


int FAR PASCAL  DocSave (lpecddoc)
LPECDDOCUMENT    lpecddoc;
{

    PROBE_BUSY(bBusy);
    // not yet implemented
    return ECD_OK;


}

void DeleteDoc (pdoc)
PDOC    pdoc;
{
    LHDOCUMENT   lhdoc;

#ifdef TEST
    EcdRevokeDocument ((LHDOCUMENT)pdoc);

#else
    lhdoc = pdoc->lhdoc;
    pdoc->lhdoc = NULL;
    if (lhdoc) {
        ShowWindow (pdoc->hwnd, FALSE);
        EcdRevokeDocument (lhdoc);
    }
#endif

}


int FAR PASCAL  DocClose (lpecddoc)
LPECDDOCUMENT    lpecddoc;
{
    PDOC    pdoc;

    PROBE_BUSY(bBusy);
    pdoc = (PDOC)lpecddoc;

    SendDocChangeMsg (pdoc, ECD_CLOSED);
    DeleteDoc (pdoc);
    return ECD_OK;

}

int FAR PASCAL DocSetHostNames(lpecddoc, lpclientName, lpdocName)
LPECDDOCUMENT    lpecddoc;
LPSTR            lpclientName;
LPSTR            lpdocName;
{


    PDOC    pdoc;
    char    buf[200];
    int     len;
    HWND    hwnd;

    PROBE_BUSY(bBusy);

    // Do something to show that the titiel are chaning
    pdoc = (PDOC)lpecddoc;
    hwnd = pdoc->hwnd;

    SetWindowText (hwnd, lpdocName);;

    hwnd = GetParent (hwnd);
    lstrcpy ((LPSTR)buf, lpclientName);
    lstrcat ((LPSTR)buf, (LPSTR)":");
    lstrcat ((LPSTR)buf, (LPSTR)"Sample Server Application");
    len = lstrlen ((LPSTR)buf);
    SetWindowText (hwnd, (LPSTR)buf);

    return ECD_OK;

}
int FAR PASCAL DocSetDocDimensions(lpecddoc, lprc)
LPECDDOCUMENT   lpecddoc;
LPRECT  lprc;
{
    PROBE_BUSY(bBusy);
    return ECD_OK;


}

int FAR PASCAL  DocRelease (lpecddoc)
LPECDDOCUMENT    lpecddoc;
{

    // !!! what is this supposed to do?
    // Revoke document calls DocRelease.

    PDOC    pdoc;
    HANDLE  hdoc;
    HWND    hwnd;


    PROBE_BUSY(bBusy);

    pdoc = (PDOC)lpecddoc;
    GlobalDeleteAtom (pdoc->aName);
    hwnd = pdoc->hwnd;
    LocalUnlock (hdoc = pdoc->hdoc);
    LocalFree (hdoc);
    DestroyWindow(hwnd);
    return TRUE;        // return something

}

int ChangeDocName (pdoc, lpname)
PDOC    pdoc;
LPSTR   lpname;
{

    GlobalDeleteAtom (pdoc->aName);
    pdoc->aName = GlobalAddAtom (lpname);
    SetWindowText (pdoc->hwnd, lpname);
    return TRUE;        // return something

}


int FAR PASCAL  DocGetObject (lpecddoc, lpitemname, lplpecdobject, lpecdclien
LPECDDOCUMENT       lpecddoc;
LPSTR               lpitemname;
LPECDOBJECT FAR *   lplpecdobject;
LPECDCLIENT         lpecdclient;
{
    PDOC    pdoc;
    HWND    hwnd;
    ATOM    aName;
    PITEM   pitem;


    PROBE_BUSY(bBusy);

    pdoc  = (PDOC)lpecddoc;
    aName = GlobalFindAtom (lpitemname);
    hwnd = GetWindow ((hwnd = pdoc->hwnd), GW_CHILD);

    // go thru all the child window list and find the window which is
    // matching the given item name.

    while (hwnd){

       // !!! We are trying to match the doc item with any item
       // OK only if there is only one item in a doc. Otherwise
       // we will be in troubles. Should work without any problems.
       // for embedded objects.

        pitem = (PITEM)GetWindowLong (hwnd, 0);

        // Alias the null with the very first item
        if (pitem->aName == aName || pitem->aName == NULL || aName == NULL)
            goto rtn;

        hwnd = GetWindow (hwnd, GW_HWNDNEXT);
    }
    // we did not find the item we wanted. So, create one

    // create a window with empty native data.

    if (CreateNewItem (pdoc, IDM_RECT, IDM_RED, FALSE)) {
        // newly created window is always the first child
        pitem = (PITEM)GetWindowLong (GetWindow (pdoc->hwnd, GW_CHILD), 0);
        BringWindowToTop (pitem->hwnd);
    } else
        return ECD_ERROR_MEMORY;
rtn:
    pitem->aName = GlobalAddAtom (lpitemname);
    // If the item is not null, then do not show the window.
    *lplpecdobject = (LPECDOBJECT)pitem;
    pitem->lpecdclient = lpecdclient;
    return ECD_OK;

}


// item related routines

void SetNewItemName (pitem)
PITEM   pitem;
{
    char    buf[3];

    lstrcpy ((LPSTR)pitem->name, (LPSTR)"Shape #");


    if (cShapes++ > 100)
        cShapes = 1;

    buf[0] = (char)((cShapes / 10)  + (int)'0');
    buf[1] = (char)((cShapes % 10)  + (int)'0');
    buf[2] = 0;

    lstrcat ((LPSTR)pitem->name, (LPSTR)buf);
    pitem->aName = GlobalAddAtom ((LPSTR)pitem->name);
}

void SetItemName (pitem, lpname)
PITEM   pitem;
LPSTR   lpname;
{
    pitem->aName = GlobalAddAtom (lpname);
    lstrcpy ((LPSTR)pitem->name, lpname);
}

void CutCopyItem (hwnd)
HWND    hwnd;
{
    PITEM       pitem;

    if (OpenClipboard (hwnd)){

        EmptyClipboard ();

        // firt set the clipboard

        pitem = (PITEM) GetWindowLong (GetWindow(
                GetWindow (hwnd, GW_CHILD), GW_CHILD), 0);

        // Check for null handles from the render routines.
        SetClipboardData (CF_METAFILEPICT, GetPicture (pitem));
        SetClipboardData (CF_BITMAP, GetBitmap (pitem));
        SetClipboardData (cfNative, GetNative (pitem));
        SetClipboardData (cfLink, GetLink (pitem));
        SetClipboardData (cfOwnerLink, GetLink (pitem));
        CloseClipboard ();
    }


}

HANDLE  GetNative (pitem)
PITEM   pitem;
{


    LPSTR       lpsrc;
    LPSTR       lplink = NULL;
    HANDLE      hlink = NULL;
    int         i;



    hlink = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, sizeof (ITEM));
    if (hlink== NULL || (lplink = (LPSTR)GlobalLock (hlink)) == NULL)
        goto errRtn;

    lpsrc = (LPSTR)pitem;
    for (i = 0; i <  sizeof(ITEM); i++)
        *lplink++ = *lpsrc++;

    GlobalUnlock (hlink);
    return hlink;

errRtn:
    if (lplink)
        GlobalUnlock (hlink);

    if (hlink)
        GlobalFree (hlink);

}

HANDLE  GetLink (pitem)
PITEM   pitem;
{

    char        buf[128];
    LPSTR       lpsrc;
    LPSTR       lplink = NULL;
    HANDLE      hlink = NULL;
    int         len;
    int         i;

    // make the link
    lstrcpy ((LPSTR)buf, (LPSTR)"Shapes");
    len = lstrlen ((LPSTR)buf) + 1;
    len += GetWindowText (GetParent (pitem->hwnd), (LPSTR)buf + len , 128 - l
    len += GlobalGetAtomName (pitem->aName, (LPSTR)buf + len, 128 - len) + 1;
    buf[len++] = 0;       // throw in another null at the end.


    hlink = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, len);
    if (hlink== NULL || (lplink = (LPSTR)GlobalLock (hlink)) == NULL)
        goto errRtn;

    lpsrc = (LPSTR)buf;
    for (i = 0; i <  len; i++)
        *lplink++ = *lpsrc++;

    GlobalUnlock (hlink);

    return hlink;
errRtn:
    if (lplink)
        GlobalUnlock (hlink);

    GlobalFree (hlink);
    return NULL;
}

HANDLE     GetPicture (pitem)
PITEM       pitem;
{

    LPMETAFILEPICT  lppict = NULL;
    HANDLE          hpict = NULL;
    HANDLE          hMF = NULL;
    HANDLE          hdc;
    RECT            rc;
    HPEN            hpen;
    HPEN            holdpen;
    int             mm;


    // Now set the bitmap data.

    hdc = CreateMetaFile(NULL);

    GetClientRect (pitem->hwnd, (LPRECT)&rc);

    // paint directly into the bitmap
    SelectObject (hdc, hbrColor [ pitem->cmdColor - IDM_RED]);
    PatBlt (hdc, 0,0, rc.right, rc.bottom, WHITENESS);
    SetWindowOrg (hdc, 0, 0);
    SetWindowExt (hdc, rc.right, rc.bottom);


    hpen = CreatePen (PS_SOLID, 9, 0x00808080);
    holdpen = SelectObject (hdc, hpen);

    switch (pitem->cmdShape){
        case IDM_ROUNDRECT:
            RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

        case IDM_RECT:
            Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWRECT:
            SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
            Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWROUNDRECT:
            SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
            RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

    }

    hMF = CloseMetaFile (hdc);

    if(!(hpict = GlobalAlloc (GMEM_DDESHARE, sizeof (METAFILEPICT))))
        goto errRtn;

    if ((lppict = (LPMETAFILEPICT)GlobalLock (hpict)) == NULL)
        goto errRtn;

    lppict->mm = MM_ANISOTROPIC;
    lppict->hMF = hMF;


    hdc = GetDC (pitem->hwnd);
    mm = SetMapMode(hdc, MM_HIMETRIC);
    DPtoLP(hdc, (LPPOINT)&rc, 2);
    SetMapMode(hdc, mm);
    ReleaseDC (pitem->hwnd, hdc);

    lppict->xExt =  rc.right - rc.left;
    lppict->yExt =  rc.top - rc.bottom;
    GlobalUnlock (hpict);
    return hpict;

errRtn:
    if (lppict)
        GlobalUnlock (hpict);

    if (hpict)
        GlobalFree (hpict);

    if (hMF)
        DeleteMetaFile (hMF);
    return NULL;

}


HBITMAP     GetBitmap (pitem)
PITEM       pitem;
{

    HDC         hdc;
    HDC         hdcmem;
    RECT        rc;
    HBITMAP     hbitmap;
    HBITMAP     holdbitmap;
    HPEN        hpen;
    HPEN        holdpen;


    // Now set the bitmap data.

    hdc = GetDC (pitem->hwnd);
    hdcmem = CreateCompatibleDC (hdc);
    GetClientRect (pitem->hwnd, (LPRECT)&rc);
    hbitmap = CreateCompatibleBitmap (hdc, rc.right - rc.left, rc.bottom - rc
    holdbitmap = SelectObject (hdcmem, hbitmap);

    // paimt directly into the bitmap
    SelectObject (hdcmem, hbrColor [ pitem->cmdColor - IDM_RED]);
    PatBlt (hdcmem, 0,0, rc.right, rc.bottom, WHITENESS);

    hpen = CreatePen (PS_SOLID, 9, 0x00808080);
    holdpen = SelectObject (hdcmem, hpen);

    switch (pitem->cmdShape){
        case IDM_ROUNDRECT:
            RoundRect (hdcmem, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

        case IDM_RECT:
            Rectangle (hdcmem, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWRECT:
            SelectObject (hdcmem, GetStockObject (HOLLOW_BRUSH));
            Rectangle (hdcmem, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWROUNDRECT:
            SelectObject (hdcmem, GetStockObject (HOLLOW_BRUSH));
            RoundRect (hdcmem, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

    }



    hbitmap = SelectObject (hdcmem, holdbitmap);
    hpen = SelectObject (hdcmem, holdpen);
    DeleteObject (hpen);
    DeleteDC (hdcmem);
    ReleaseDC (pitem->hwnd, hdc);
    return hbitmap;

}

PITEM   CreateNewItem (pdoc, cmdShape, cmdColor, bVisible)
PDOC    pdoc;
int     cmdShape;
int     cmdColor;
BOOL    bVisible;
{

    RECT        rc;
    HANDLE      hitem = NULL;
    PITEM       pitem = NULL;
    HWND        hwnd;



    GetClientRect (pdoc->hwnd, (LPRECT)&rc);

    hwnd = CreateWindow(
        "ItemClass",
        "Item",

        WS_DLGFRAME| WS_CHILD | WS_CLIPSIBLINGS |
                    (bVisible ? WS_VISIBLE : 0),
        pdoc->ptAnchor.x,
        pdoc->ptAnchor.y,
        (rc.right - rc.left) >> 1,
        (rc.bottom - rc.top)>> 1,
        pdoc->hwnd,
        NULL,
        hInst,
        NULL
    );


    if (!hwnd)
        return (FALSE);

    pdoc->ptAnchor.x += 20;
    pdoc->ptAnchor.y += 20;


    // Now create the item info;
    hitem = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (ITEM));

    if (hitem == NULL || ((pitem = (PITEM)LocalLock (hitem)) == NULL))
        goto  errRtn;

    pitem->cmdShape = cmdShape;;
    pitem->cmdColor = cmdColor;
    pitem->hitem    = hitem;
    pitem->aName    = NULL;
    pitem->hwnd     = hwnd;
    pitem->ecdobject.lpvtbl = &itemVTbl;

    pitem->width    = (rc.right - rc.left) >> 1;
    pitem->height   = (rc.bottom - rc.top) >> 1;

    SetWindowLong (hwnd, 0, (LONG)pitem);
    return pitem;

 errRtn:
    if (pitem)
        LocalUnlock (hitem);

    if (hitem)
        LocalFree (hitem);

    return (PITEM)NULL;

}

int FAR PASCAL  ItemOpen (lpecdobject)
LPECDOBJECT     lpecdobject;
{

    // !!! This routine should activate the app
    // and prepare it ready for the editing. Activation
    // should bring on to the top and restore


    PITEM   pitem;
    HWND    hwnd;

    PROBE_BUSY(bBusy);
    pitem = (PITEM)lpecdobject;
    BringWindowToTop (pitem->hwnd);
    BringWindowToTop (GetParent (pitem->hwnd));
    SetActiveWindow ((hwnd = GetParent (GetParent (pitem->hwnd))));
    SendMessage (hwnd, WM_SYSCOMMAND, SC_RESTORE, 0L);
    return ECD_OK;


}


int FAR PASCAL  ItemDelete (lpecdobject)
LPECDOBJECT     lpecdobject;
{

    PITEM   pitem;

    PROBE_BUSY(bBusy);
    pitem = (PITEM)lpecdobject;
    if (--pitem->ref)
        return ECD_OK;

    if (IsWindow(pitem->hwnd))
        DestroyWindow (pitem->hwnd);
    return ECD_OK;
}


int FAR PASCAL  ItemGetData (lpecdobject, cfFormat, lphandle)
LPECDOBJECT     lpecdobject;
WORD            cfFormat;
LPHANDLE        lphandle;
{

    PITEM   pitem;

    // PROBE_BUSY(bBusy);

    // asking data for emtyp object.
    pitem = (PITEM)lpecdobject;

    if (pitem->cmdShape  == NULL||
        pitem->cmdColor == NULL)
        return ECD_ERROR_MEMORY;

    if (cfFormat == cfNative){

        if (!(*lphandle = GetNative (pitem)))
            return ECD_ERROR_MEMORY;

        return ECD_OK;
    }


    if (cfFormat == CF_BITMAP){

        if (!(*lphandle = (HANDLE)GetBitmap (pitem)))
            return ECD_ERROR_MEMORY;

        return ECD_OK;
    }

    if (cfFormat == CF_METAFILEPICT){

        if (!(*lphandle = GetPicture (pitem)))
            return ECD_ERROR_MEMORY;

        return ECD_OK;
    }

    if (cfFormat == cfLink || cfFormat == cfOwnerLink){

        if (!(*lphandle = GetLink (pitem)))
            return ECD_ERROR_MEMORY;

        return ECD_OK;
    }
    return ECD_ERROR_MEMORY;          // this is actually unknow format.

}


int FAR PASCAL   ItemSetTargetDevice (lpecdobject, hdata)
LPECDOBJECT     lpecdobject;
HANDLE          hdata;
{
    LPSTR   lpdata;

    lpdata = (LPSTR)GlobalLock (hdata);
    // Print the lpdata here.
    GlobalUnlock (hdata);
    GlobalFree (hdata);
    return ECD_OK;

}

int FAR PASCAL  ItemSetData (lpecdobject, cfFormat, hdata)
LPECDOBJECT     lpecdobject;
WORD            cfFormat;
HANDLE          hdata;
{

    LPITEM   lpitem;
    PITEM    pitem;

    PROBE_BUSY(bBusy);
    pitem = (PITEM)lpecdobject;

    if (cfFormat != cfNative)
        return ECD_ERROR_MEMORY;


    lpitem = (LPITEM)GlobalLock (hdata);
    if (lpitem){
        pitem->cmdShape = lpitem->cmdShape;
        pitem->cmdColor = lpitem->cmdColor;
        SetItemName (pitem, (LPSTR)pitem->name);
        // This is not necessary.
        ShowWindow (pitem->hwnd, TRUE);
        InvalidateRect (pitem->hwnd, (LPRECT)NULL, TRUE);
        GlobalUnlock (hdata);
    }

    GlobalFree (hdata);
    return ECD_OK;
}

ECDCLIPFORMAT   FAR PASCAL ItemEnumFormats (lpecdobject, cfFormat)
LPECDOBJECT     lpecdobject;
ECDCLIPFORMAT   cfFormat;
{
    if (cfFormat == 0)
        return cfLink;

    if (cfFormat == cfLink)
        return cfOwnerLink;

    if (cfFormat == cfOwnerLink)
        return CF_BITMAP;

    if (cfFormat == CF_BITMAP)
        return CF_METAFILEPICT;

    if (cfFormat == CF_METAFILEPICT)
        return cfNative;

    //if (cfFormat == cfNative)
    //    return NULL;

    return NULL;
}

BOOL DestroyItem (hwnd)
HWND    hwnd;
{
    PITEM   pitem;
    HANDLE  hitem;


    pitem = (PITEM)GetWindowLong (hwnd, 0);
    if (pitem->aName)
        GlobalDeleteAtom (pitem->aName);

    LocalUnlock (hitem = pitem->hitem);
    LocalFree (hitem);
    return TRUE;        // return something

}

void    PaintItem (hwnd)
HWND    hwnd;
{

    HDC             hdc;
    PITEM           pitem;
    RECT            rc;
    PAINTSTRUCT     ptSt;
    HPEN            hpen;
    HPEN            holdpen;


    BeginPaint (hwnd, (LPPAINTSTRUCT)&ptSt);
    hdc = GetDC (hwnd);

    // Do not paint anything for the whole document item
    // For document item the name is null.

    pitem = (PITEM)GetWindowLong (hwnd, 0);

    GetClientRect (hwnd, (LPRECT)&rc);
    PatBlt (hdc, 0,0, rc.right, rc.bottom, WHITENESS);
    SelectObject (hdc, hbrColor [ pitem->cmdColor - IDM_RED]);
    hpen = CreatePen (PS_SOLID, 9, 0x00808080);
    holdpen = SelectObject (hdc, hpen);

    switch (pitem->cmdShape){
        case IDM_ROUNDRECT:
            RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

        case IDM_RECT:
            Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWRECT:
            SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
            Rectangle (hdc, rc.left, rc.top, rc.right, rc.bottom);
            break;

        case IDM_HALLOWROUNDRECT:
            SelectObject (hdc, GetStockObject (HOLLOW_BRUSH));
            RoundRect (hdc, rc.left, rc.top, rc.right, rc.bottom,
                    (rc.right - rc.left) >> 2, (rc.bottom - rc.top) >> 2);
            break;

    }

    hpen = SelectObject (hdc, holdpen);
    DeleteObject (hpen);

    ReleaseDC (hwnd, hdc);
    EndPaint (hwnd, (LPPAINTSTRUCT)&ptSt);
}



void    SendSrvrChangeMsg (psrvr, options)
PSRVR   psrvr;
WORD    options;
{

    HWND    hwnd;

    // if we are releasing the document, do not do anything
    if (psrvr->lhsrvr == NULL)
        return;

    hwnd = GetWindow (psrvr->hwnd, GW_CHILD);
    while (hwnd){
        SendDocChangeMsg ((PDOC)GetWindowLong (hwnd, 0), options);
        hwnd = GetWindow (hwnd, GW_HWNDNEXT);

    }

}

void    SendDocRenameMsg (psrvr, options)
PSRVR   psrvr;
WORD    options;
{

    HWND    hwnd;
    PITEM   pitem;
    PDOC    pdoc;
    char    buf[128];

    // if we are releasing the document, do not do anything
    if (psrvr->lhsrvr == NULL)
        return;

    hwnd = GetWindow (psrvr->hwnd, GW_CHILD);
    pdoc = (PDOC)GetWindowLong (hwnd, 0);

    // if we are releasing the document, do not do anything
    if (pdoc->lhdoc == NULL)
        return;

    hwnd = GetWindow (pdoc->hwnd, GW_CHILD);

    while (hwnd){
        pitem = (PITEM)GetWindowLong (hwnd, 0);
        // Sending rename to obe item is sufficient
        if (pitem->lpecdclient){
            (*pitem->lpecdclient->lpvtbl->CallBack) (pitem->lpecdclient, opti
                    (LPECDOBJECT)pitem);

            return;
        }
        hwnd = GetWindow (hwnd, GW_HWNDNEXT);
    }

    // reregister the document if there are no callbacks.
    GetWindowText (pdoc->hwnd, (LPSTR)buf, 128);
    DeleteDoc (pdoc);
    CreateDocFromFile (psrvr, (LPSTR)buf, NULL);
    return;
}

void    SendDocChangeMsg (pdoc, options)
PDOC    pdoc;
WORD    options;
{

    HWND    hwnd;

    // if we are releasing the document, do not do anything
    if (pdoc->lhdoc == NULL)
        return;

    hwnd = GetWindow (pdoc->hwnd, GW_CHILD);
    while (hwnd){
        SendItemChangeMsg ((PITEM)GetWindowLong (hwnd, 0), options);
        hwnd = GetWindow (hwnd, GW_HWNDNEXT);

    }

}


void    SendItemChangeMsg (pitem, options)
PITEM   pitem;
WORD    options;
{

    if (pitem->lpecdclient)
        (*pitem->lpecdclient->lpvtbl->CallBack) (pitem->lpecdclient, options,
                (LPECDOBJECT)pitem);
}


SHAPES.C
CD-ROM Disc Path:   \SAMPCODE\OLE\MISHAPES\SHAPES.C

#define SERVERONLY
#include "windows.h"
#include "ecd.h"
#include "shapes.h"
#include <string.h>


char FileName[128];
char PathName[128];
char OpenName[128];
char DefPath[128];
char DefSpec[13] = "*.shax104";
char DefExt[] = ".txt";
char str[255];

RECT    dragRect;
POINT   dragPt;
HWND    hwndMain;
BOOL    fCapture = FALSE;

HBRUSH  hbrColor [5];

char    *pcolors [5]  ={"RED",
                        "GREEN",
                        "BLUE",
                        "BLACK",
                        "YELLOW"
                       };
char    *pshapes [4] = {
                        ":RECTANGLE",
                        ":ROUNDRECT"
                        ":HOLLOWRECT",
                        ":HOLLOWROUNDRECT"
                       };


WORD        cfLink;
WORD        cfOwnerLink;
WORD        cfNative;
WORD        cShapes = 0;
BOOL        bBusy   = FALSE;


HANDLE hInst;
HANDLE hAccTable;


//////////////////////////////////////////////////////////////////////////
//
// Right thing to do is to wait till the termination came from the client sid
// This is lot more cleaner.
//
// (c) Copyright Microsoft Corp. 1990 - All Rights Reserved
//
/////////////////////////////////////////////////////////////////////////


int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE  hInstance;
HANDLE  hPrevInstance;
LPSTR   lpCmdLine;
int nCmdShow;
{
    MSG msg;



    if (!hPrevInstance)
        if (!InitApplication(hInstance))
            return (FALSE);




    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    if (!InitServer (hwndMain, hInstance))
        return FALSE;

    if (!ProcessCmdLine (hwndMain, lpCmdLine))
        return FALSE;

    while (GetMessage(&msg, NULL, NULL, NULL)) {

    /* Only translate message if it is not an accelerator message */

        if (!TranslateAccelerator(hwndMain, hAccTable, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    DeleteInstance ();
    return (msg.wParam);
}



BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 4;
    wc.cbWndExtra = 4;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "InitMenu";

    wc.lpszClassName = "SampleClass";
    wc.lpfnWndProc = MainWndProc;

    if (!RegisterClass(&wc))
        return NULL;


    wc.hIcon   = NULL;
    wc.hCursor = NULL;
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = "DocClass";
    wc.lpfnWndProc   = DocWndProc;

    if (!RegisterClass(&wc))
        return NULL;



    wc.hIcon   = NULL;
    wc.hCursor = NULL;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "ItemClass";
    wc.lpfnWndProc   = ItemWndProc;

    if (!RegisterClass(&wc))
        return NULL;

}



BOOL InitInstance(hInstance, nCmdShow)
HANDLE          hInstance;
int             nCmdShow;
{

    // initialse the proc tables.
    InitVTbls ();

    hbrColor [0] = CreateSolidBrush (0x000000ff);
    hbrColor [1] = CreateSolidBrush (0x0000ff00);
    hbrColor [2] = CreateSolidBrush (0x00ff0000);
    hbrColor [3] = CreateSolidBrush (0x00000000);
    hbrColor [4] = CreateSolidBrush (0x00ff00ff);

    // register clipboard formats.
    cfLink      = RegisterClipboardFormat("ObjectLink");
    cfOwnerLink = RegisterClipboardFormat("OwnerLink");
    cfNative    = RegisterClipboardFormat("Native");


    hInst = hInstance;
    hAccTable = LoadAccelerators(hInst, "SampleAcc");

    hwndMain = CreateWindow(
        "SampleClass",
        "Sample miServer Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );


    if (!hwndMain)
        return (FALSE);

    ShowWindow(hwndMain, nCmdShow);
    UpdateWindow(hwndMain);
    return (TRUE);

}

void    DeleteInstance ()
{

    // Free the proc table instances.
    FreeVTbls ();

    DeleteObject (hbrColor [0]);
    DeleteObject (hbrColor [1]);
    DeleteObject (hbrColor [2]);
    DeleteObject (hbrColor [3]);
    DeleteObject (hbrColor [4]);

}

// main window or server related routiens

long FAR PASCAL MainWndProc(hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout, lpOpenDlg, lpSaveDlg;

    int     Return;
    PITEM   pitem;
    PDOC    pdoc;



    switch (message) {
        case WM_COMMAND:
            switch (wParam) {


                case IDM_NEWITEM:
                    pdoc = (PDOC)GetWindowLong (GetWindow (hwnd, GW_CHILD), 0
                    pitem = CreateNewItem  (pdoc, IDM_RECT, IDM_RED, TRUE);
                    SetNewItemName (pitem);
                    BringWindowToTop (pitem->hwnd);
                    break;

                case IDM_RED:
                case IDM_GREEN:
                case IDM_BLUE:
                case IDM_BLACK:
                case IDM_YELLOW:

                    pitem = (PITEM)GetWindowLong (
                            GetWindow (GetWindow(hwnd, GW_CHILD), GW_CHILD),
                    pitem->cmdColor = wParam;
                    InvalidateRect (pitem->hwnd, (LPRECT)NULL,  TRUE);
                    // make sure that we have the right bits on the screen
                    UpdateWindow (pitem->hwnd);
                    SendItemChangeMsg (pitem, ECD_CHANGED);
                    break;


                case IDM_RECT:
                case IDM_ROUNDRECT:
                case IDM_HALLOWRECT:
                case IDM_HALLOWROUNDRECT:

                    pitem = (PITEM)GetWindowLong (
                            GetWindow (GetWindow(hwnd, GW_CHILD), GW_CHILD),
                    pitem->cmdShape = wParam;
                    InvalidateRect (pitem->hwnd, (LPRECT)NULL,  TRUE);
                    UpdateWindow (pitem->hwnd);
                    SendItemChangeMsg (pitem, ECD_CHANGED);
                    break;

                case IDM_NEW:

                    // create another document widnwo.
                    pdoc = CreateNewDoc ((PSRVR)GetWindowLong (hwnd, 0), NULL
                    if (pdoc == NULL)
                        break;
                    pitem = CreateNewItem (pdoc, IDM_RECT, IDM_RED, TRUE);
                    SetNewItemName (pitem);
                    BringWindowToTop (pdoc->hwnd);
                    break;


                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst, "AboutBox", hwnd, lpProcAbout);
                    FreeProcInstance(lpProcAbout);
                    break;

                case IDM_OPEN:
                    /* Call OpenDlg() to get the filename */

                    lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
                    Return = DialogBox(hInst, "Open", hwnd, lpOpenDlg);
                    FreeProcInstance(lpOpenDlg);

                    if (!CreateDocFromFile ((PSRVR)GetWindowLong (hwnd, 0), (
                        MessageBox (
                              hwndMain,
                              "reading from file failed",
                              "Server Sample Sample Application",
                               MB_OK);


                    break;

                case IDM_SAVE:

                    lpSaveDlg = MakeProcInstance((FARPROC) SaveDlg, hInst);
                    Return = DialogBox(hInst, "Save", hwnd, lpSaveDlg);
                    FreeProcInstance(lpSaveDlg);

                    SaveDocIntoFile (pdoc = (PDOC) (GetWindowLong (GetWindow
                        (LPSTR)OpenName);

                    // send message for save
                    SendSrvrChangeMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_SA
                    SendDocRenameMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_REN
                    break;


                case IDM_SAVEAS:
                case IDM_PRINT:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "Server Sample Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;



                case IDM_EXIT:
                    SendSrvrChangeMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_CL
                    DeleteServer ((PSRVR)GetWindowLong (hwnd, 0));
                    break;

                /* edit menu commands */

                case IDM_UNDO:
                case IDM_CUT:
                case IDM_COPY:

                    CutCopyItem (hwnd);
                    break;

                case IDM_PASTE:
                case IDM_CLEAR:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "Server Sample  Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;

                case IDC_EDIT:
                    if (HIWORD (lParam) == EN_ERRSPACE) {
                        MessageBox (
                              GetFocus ()
                            , "Out of memory."
                            , "server Sample  Sample Application"
                            , MB_ICONHAND | MB_OK
                        );
                    }
                    break;

            }
            break;

        case WM_SIZE:
            if (wParam == SIZENORMAL)
                ReSizeAllDocs (hwnd, LOWORD (lParam), HIWORD (lParam));

            break;

        case WM_CLOSE:
            SendSrvrChangeMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_CLOSED);
            DeleteServer ((PSRVR)GetWindowLong (hwnd, 0));
            break;

        case WM_DESTROY:
            PostQuitMessage (0);
            break;

        default:
            return (DefWindowProc(hwnd, message, wParam, lParam));
    }
    return (NULL);
}





HANDLE FAR PASCAL SaveDlg (hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned message;
WORD     wParam;
LONG     lParam;
{

    switch (message) {
        case WM_COMMAND:
            switch (wParam) {

                case IDOK:
                    GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);

                    AddExt(OpenName, DefExt);
                    EndDialog(hDlg, TRUE);
                    return (TRUE);

                case IDCANCEL:
                    EndDialog(hDlg, NULL);
                    return (FALSE);
            }
            break;

        case WM_INITDIALOG:                        /* message: initialize
            SetDlgItemText(hDlg, IDC_EDIT, (LPSTR)"shape1.sha");
            SendDlgItemMessage(hDlg,               /* dialog handle      */
                IDC_EDIT,                          /* where to send message
                EM_SETSEL,                         /* select characters
                NULL,                              /* additional information
                MAKELONG(0, 0x7fff));              /* entire contents      */
            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE); /* Indicates the focus is set to a control */
    }
    return FALSE;
}




HANDLE FAR PASCAL OpenDlg(hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned message;
WORD     wParam;
LONG     lParam;
{
    HANDLE hFile=1;     /* Temp value for return */

    switch (message) {
        case WM_COMMAND:
            switch (wParam) {

                case IDC_LISTBOX:
                    switch (HIWORD(lParam)) {

                        case LBN_SELCHANGE:
                            /* If item is a directory name, append "*.*" */
                            if (DlgDirSelect(hDlg, str, IDC_LISTBOX))
                                strcat(str, DefSpec);

                            SetDlgItemText(hDlg, IDC_EDIT, str);
                            SendDlgItemMessage(hDlg,
                                IDC_EDIT,
                                EM_SETSEL,
                                NULL,
                                MAKELONG(0, 0x7fff));
                            break;

                        case LBN_DBLCLK:
                            goto openfile;
                    }
                    return (TRUE);

                case IDOK:
openfile:
                    GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);
                    if (strchr(OpenName, '*') || strchr(OpenName, '?')) {
                        SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,
                            (LPSTR) OpenName);
                        if (str[0])
                            strcpy(DefPath, str);
                        ChangeDefExt(DefExt, DefSpec);
                        UpdateListBox(hDlg);
                        return (TRUE);
                    }

                    if (!OpenName[0]) {
                        MessageBox(hDlg, "No filename specified.",
                            NULL, MB_OK | MB_ICONHAND);
                        return (TRUE);
                    }

                    AddExt(OpenName, DefExt);

                    /* The routine to open the file would go here, and the */
                    /* file handle would be returned instead of NULL.
                    EndDialog(hDlg, hFile);
                    return (TRUE);

                case IDCANCEL:
                    EndDialog(hDlg, NULL);
                    return (FALSE);
            }
            break;

        case WM_INITDIALOG:                        /* message: initialize
            UpdateListBox(hDlg);
            SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
            SendDlgItemMessage(hDlg,               /* dialog handle      */
                IDC_EDIT,                          /* where to send message
                EM_SETSEL,                         /* select characters
                NULL,                              /* additional information
                MAKELONG(0, 0x7fff));              /* entire contents      */
            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE); /* Indicates the focus is set to a control */
    }
    return FALSE;
}



void UpdateListBox(hDlg)
HWND hDlg;
{
    strcpy(str, DefPath);
    strcat(str, DefSpec);
    DlgDirList(hDlg, str, IDC_LISTBOX, IDC_PATH, 0x4010);

    /* To ensure that the listing is made for a subdir. of
     * current drive dir...
     */
    if (!strchr (DefPath, ':'))
  DlgDirList(hDlg, DefSpec, IDC_LISTBOX, IDC_PATH, 0x4010);

    /* Remove the '..' character from path if it exists, since this
     * will make DlgDirList move us up an additional level in the tree
     * when UpdateListBox() is called again.
     */
    if (strstr (DefPath, ".."))
  DefPath[0] = '\0';

    SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
}


void ChangeDefExt(Ext, Name)
PSTR Ext, Name;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr)
        if (!strchr(pTptr, '*') && !strchr(pTptr, '?'))
            strcpy(Ext, pTptr);
}


void SeparateFile(hDlg, lpDestPath, lpDestFileName, lpSrcFileName)
HWND hDlg;
LPSTR lpDestPath, lpDestFileName, lpSrcFileName;
{
    LPSTR lpTmp;
    char  cTmp;

    lpTmp = lpSrcFileName + (long) lstrlen(lpSrcFileName);
    while (*lpTmp != ':' && *lpTmp != '\\' && lpTmp > lpSrcFileName)
        lpTmp = AnsiPrev(lpSrcFileName, lpTmp);
    if (*lpTmp != ':' && *lpTmp != '\\') {
        lstrcpy(lpDestFileName, lpSrcFileName);
        lpDestPath[0] = 0;
        return;
    }
    lstrcpy(lpDestFileName, lpTmp + 1);
    cTmp = *(lpTmp + 1);
    lstrcpy(lpDestPath, lpSrcFileName);
     *(lpTmp + 1) = cTmp;
    lpDestPath[(lpTmp - lpSrcFileName) + 1] = 0;
}



void AddExt(Name, Ext)
PSTR Name, Ext;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr != '.')
        strcat(Name, Ext);
}


BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:
            return (TRUE);

        case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
                EndDialog(hDlg, TRUE);
                return (TRUE);
            }
            break;
    }
    return (FALSE);
}


void   DrawDragRect (hwnd)
HWND    hwnd;
{

        HDC hdc;

        hdc = GetDC(hwnd);
        InvertRect (hdc, (LPRECT)&dragRect);
        ReleaseDC (hwnd, hdc);

}

void    ReSizeAllDocs (hwndSrvr, width, height)
HWND    hwndSrvr;
int     width;
int     height;
{
    HWND    hwnd;
    RECT    rc;


    hwnd = GetWindow (hwndSrvr, GW_CHILD);
    while (hwnd){
        GetWindowRect (hwnd, (LPRECT)&rc);
        ScreenToClient (hwndSrvr, (LPPOINT)&rc);
        MoveWindow (hwnd, rc.left, rc.top,
            width , height, TRUE);

        hwnd = GetWindow (hwnd, GW_HWNDNEXT);
    }

}
void    ReSizeAllItems (hwndDoc, width, height)
HWND    hwndDoc;
int     width;
int     height;
{
    HWND    hwnd;
    RECT    rc;


    hwnd = GetWindow (hwndDoc, GW_CHILD);
    while (hwnd){
        GetWindowRect (hwnd, (LPRECT)&rc);
        ScreenToClient (hwndDoc, (LPPOINT)&rc);
        MoveWindow (hwnd, rc.left, rc.top,
            width >> 1, height >> 1, TRUE);

        hwnd = GetWindow (hwnd, GW_HWNDNEXT);
    }

}

long FAR PASCAL ItemWndProc (hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
{
        POINT   pt;
        HWND    hwndParent;


    switch (message) {
        case WM_PAINT:
            PaintItem (hwnd);
            break;


        case WM_SIZE:
            break;

        case WM_DESTROY:
            DestroyItem (hwnd);
            break;

        case WM_RBUTTONDOWN:


            hwndParent = GetParent (hwnd);
            GetWindowRect (hwnd, (LPRECT) &dragRect);
            ScreenToClient (hwndParent, (LPPOINT)&dragRect);
            ScreenToClient (hwndParent, (LPPOINT)&dragRect.right);

            DrawDragRect (hwndParent);

            dragPt.x = LOWORD(lParam);
            dragPt.y = HIWORD(lParam);

            ClientToScreen (hwnd, (LPPOINT)&dragPt);
            ScreenToClient (hwndParent, (LPPOINT)&dragPt);

            SetCapture (hwnd);
            fCapture = TRUE;
            break;

        case WM_MOUSEMOVE:
            if (!fCapture)
                break;

            hwndParent = GetParent (hwnd);
            DrawDragRect (hwndParent);
            pt.x = LOWORD(lParam);
            pt.y = HIWORD(lParam);

            ClientToScreen (hwnd, (LPPOINT)&pt);
            ScreenToClient (hwndParent, (LPPOINT)&pt);

            OffsetRect ((LPRECT)&dragRect, pt.x - dragPt.x,
                                        pt.y - dragPt.y);

            dragPt.x = pt.x;
            dragPt.y = pt.y;


            DrawDragRect (hwndParent);
            break;


        case WM_RBUTTONUP:
            if (!fCapture)
                return TRUE;

            hwndParent = GetParent (hwnd);
            fCapture = FALSE;
            ReleaseCapture ();
            DrawDragRect (hwndParent);

            MoveWindow (hwnd, dragRect.left, dragRect.top,
                        dragRect.right - dragRect.left,
                        dragRect.bottom - dragRect.top, TRUE);

             // fall thru

        case WM_LBUTTONDOWN:
             BringWindowToTop (hwnd);
             break;

        default:
            return (DefWindowProc(hwnd, message, wParam, lParam));
    }
    return (NULL);
}


BOOL    SaveDocIntoFile (pdoc, lpstr)
PDOC    pdoc;
LPSTR   lpstr;
{


    HWND    hwnd;
    int     fh;
    PITEM   pitem;


    if ((fh =_lcreat (lpstr, 0)) <= 0)
        return FALSE;

    hwnd = GetWindow (pdoc->hwnd, GW_CHILD);

    while (hwnd) {
        pitem = (PITEM) GetWindowLong (hwnd, 0);
        if (!pitem->aName)
            SetNewItemName (pitem);

        if (_lwrite (fh, (LPSTR)pitem, sizeof (ITEM)) <= 0)
            break;

        hwnd = GetWindow (hwnd, GW_HWNDNEXT);
    }
    _lclose (fh);

    SetWindowText (pdoc->hwnd, (LPSTR)lpstr);
    return TRUE;
}


PDOC    CreateDocFromFile (psrvr, lpstr, lhdoc)
PSRVR       psrvr;
LPSTR       lpstr;
LHDOCUMENT  lhdoc;
{

    int     fh;
    ITEM    item;
    PITEM   pitem;
    PDOC    pdoc;


    if ((fh =_lopen (lpstr, OF_READ)) <= 0)
        return FALSE;

    if (!(pdoc = CreateNewDoc (psrvr, lhdoc, lpstr)))
        return FALSE;

    cShapes = 0;
    while (TRUE) {
        if (_lread (fh, (LPSTR)&item, sizeof (ITEM)) <= 0)
            break;

        pitem = CreateNewItem (pdoc, item.cmdShape, item.cmdColor, TRUE);
        SetItemName (pitem, (LPSTR)item.name);
        cShapes++;
    }
    _lclose (fh);


    return pdoc;
}

// doc related routines

PDOC    CreateNewDoc (psrvr, lhdoc, lptitle)
PSRVR   psrvr;
LONG    lhdoc;
LPSTR   lptitle;
{

    RECT        rc;
    HMENU       hMenu;
    HWND        hwnd;

    hwnd = psrvr->hwnd;

    // first set the menu.
    hMenu = GetMenu (hwnd);
    DestroyMenu (hMenu);

    hMenu = LoadMenu (hInst, (LPSTR)"SampleMenu");
    SetMenu (hwnd, hMenu);
    DrawMenuBar (hwnd);

    GetClientRect (hwnd, (LPRECT)&rc);
    if (IsIconic (psrvr->hwnd)){
        // create some reasonale height/wdith for satisfying the
        // data request in iconic mode
        rc.right = GetSystemMetrics (SM_CXSCREEN) >> 1;
        rc.bottom   = GetSystemMetrics (SM_CYSCREEN) >> 1;
    }
    InflateRect ((LPRECT)&rc, -5, -5);

    hwnd = CreateWindow(
        "DocClass",
        "New",
        WS_SYSMENU | WS_CAPTION | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,

        rc.left,
        rc.top,
        (rc.right - rc.left),
        (rc.bottom - rc.top),
        psrvr->hwnd,
        NULL,
        hInst,
        NULL
    );

    SetWindowText (hwnd, lptitle);
    return InitDoc (hwnd, lhdoc);
}

long FAR PASCAL DocWndProc(hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    HWND    hwndChild;
    HWND    hwndParent;
    HMENU   hMenu;

    switch (message) {

        case WM_SIZE:
            if (wParam == SIZENORMAL)
                ReSizeAllItems (hwnd, LOWORD (lParam), HIWORD (lParam));
            break;

        case WM_CLOSE:
            SendDocChangeMsg ((PDOC)GetWindowLong (hwnd, 0), ECD_CLOSED);
            DeleteDoc ((PDOC)GetWindowLong (hwnd, 0));
            break;

        case WM_DESTROY:

            hwndParent = GetParent (hwnd);
            hwndChild = GetWindow(hwndParent, GW_CHILD);

            if (GetWindow (hwndChild, GW_HWNDNEXT))
                break;          // some more doc windows.

            // first set the menu.
            hMenu  = GetMenu (hwndMain);
            DestroyMenu (hMenu);

            // we do not ahve any more doc windows.
            hMenu = LoadMenu (hInst, (LPSTR)"InitMenu");
            SetMenu (hwndMain, hMenu);
            DrawMenuBar (hwndMain);
            break;



        case WM_LBUTTONDOWN:
            BringWindowToTop (hwnd);
            break;

        default:
            return (DefWindowProc(hwnd, message, wParam, lParam));
    }
    return (NULL);
}


SHAPES.C
CD-ROM Disc Path:   \SAMPCODE\OLE\SHAPES\SHAPES.C

#define SERVERONLY
#include "windows.h"
#include "ecd.h"
#include "shapes.h"
#include <string.h>


char FileName[128];
char PathName[128];
char OpenName[128];
char DefPath[128];
char DefSpec[13] = "*.shax104";
char DefExt[] = ".txt";
char str[255];

RECT    dragRect;
POINT   dragPt;
HWND    hwndMain;
BOOL    fCapture = FALSE;

HBRUSH  hbrColor [5];

char    *pcolors [5]  ={"RED",
                        "GREEN",
                        "BLUE",
                        "BLACK",
                        "YELLOW"
                       };
char    *pshapes [4] = {
                        ":RECTANGLE",
                        ":ROUNDRECT"
                        ":HOLLOWRECT",
                        ":HOLLOWROUNDRECT"
                       };


WORD        cfLink;
WORD        cfOwnerLink;
WORD        cfNative;
WORD        cShapes = 0;
BOOL        bBusy   = FALSE;


HANDLE hInst;
HANDLE hAccTable;


//////////////////////////////////////////////////////////////////////////
//
// Right thing to do is to wait till the termination came from the client sid
// This is lot more cleaner.
//
// (c) Copyright Microsoft Corp. 1990 - All Rights Reserved
//
/////////////////////////////////////////////////////////////////////////


int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE  hInstance;
HANDLE  hPrevInstance;
LPSTR   lpCmdLine;
int nCmdShow;
{
    MSG msg;



    if (!hPrevInstance)
        if (!InitApplication(hInstance))
            return (FALSE);




    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

    if (!InitServer (hwndMain, hInstance))
        return FALSE;

    if (!ProcessCmdLine (hwndMain, lpCmdLine))
        return FALSE;

    while (GetMessage(&msg, NULL, NULL, NULL)) {

    /* Only translate message if it is not an accelerator message */

        if (!TranslateAccelerator(hwndMain, hAccTable, &msg)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    DeleteInstance ();
    return (msg.wParam);
}



BOOL InitApplication(hInstance)
HANDLE hInstance;
{
    WNDCLASS  wc;

    wc.style = NULL;
    wc.lpfnWndProc = MainWndProc;
    wc.cbClsExtra = 4;
    wc.cbWndExtra = 4;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName =  "InitMenu";

    wc.lpszClassName = "SampleClass";
    wc.lpfnWndProc = MainWndProc;

    if (!RegisterClass(&wc))
        return NULL;


    wc.hIcon   = NULL;
    wc.hCursor = NULL;
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = "DocClass";
    wc.lpfnWndProc   = DocWndProc;

    if (!RegisterClass(&wc))
        return NULL;



    wc.hIcon   = NULL;
    wc.hCursor = NULL;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "ItemClass";
    wc.lpfnWndProc   = ItemWndProc;

    if (!RegisterClass(&wc))
        return NULL;

}



BOOL InitInstance(hInstance, nCmdShow)
HANDLE          hInstance;
int             nCmdShow;
{

    // initialse the proc tables.
    InitVTbls ();

    hbrColor [0] = CreateSolidBrush (0x000000ff);
    hbrColor [1] = CreateSolidBrush (0x0000ff00);
    hbrColor [2] = CreateSolidBrush (0x00ff0000);
    hbrColor [3] = CreateSolidBrush (0x00000000);
    hbrColor [4] = CreateSolidBrush (0x00ff00ff);

    // register clipboard formats.
    cfLink      = RegisterClipboardFormat("ObjectLink");
    cfOwnerLink = RegisterClipboardFormat("OwnerLink");
    cfNative    = RegisterClipboardFormat("Native");


    hInst = hInstance;
    hAccTable = LoadAccelerators(hInst, "SampleAcc");

    hwndMain = CreateWindow(
        "SampleClass",
        "Sample Server Application",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL
    );


    if (!hwndMain)
        return (FALSE);

    ShowWindow(hwndMain, nCmdShow);
    UpdateWindow(hwndMain);
    return (TRUE);

}

void    DeleteInstance ()
{

    // Free the proc table instances.
    FreeVTbls ();

    DeleteObject (hbrColor [0]);
    DeleteObject (hbrColor [1]);
    DeleteObject (hbrColor [2]);
    DeleteObject (hbrColor [3]);
    DeleteObject (hbrColor [4]);

}

// main window or server related routiens

long FAR PASCAL MainWndProc(hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpProcAbout, lpOpenDlg, lpSaveDlg;

    int     Return;
    PITEM   pitem;
    PDOC    pdoc;



    switch (message) {
        case WM_COMMAND:
            switch (wParam) {


                case IDM_NEWITEM:
                    pdoc = (PDOC)GetWindowLong (GetWindow (hwnd, GW_CHILD), 0
                    pitem = CreateNewItem  (pdoc, IDM_RECT, IDM_RED, TRUE);
                    SetNewItemName (pitem);
                    BringWindowToTop (pitem->hwnd);
                    break;

                case IDM_RED:
                case IDM_GREEN:
                case IDM_BLUE:
                case IDM_BLACK:
                case IDM_YELLOW:

                    pitem = (PITEM)GetWindowLong (
                            GetWindow (GetWindow(hwnd, GW_CHILD), GW_CHILD),
                    pitem->cmdColor = wParam;
                    InvalidateRect (pitem->hwnd, (LPRECT)NULL,  TRUE);
                    // make sure that we have the right bits on the screen
                    UpdateWindow (pitem->hwnd);
                    SendItemChangeMsg (pitem, ECD_CHANGED);
                    break;


                case IDM_RECT:
                case IDM_ROUNDRECT:
                case IDM_HALLOWRECT:
                case IDM_HALLOWROUNDRECT:

                    pitem = (PITEM)GetWindowLong (
                            GetWindow (GetWindow(hwnd, GW_CHILD), GW_CHILD),
                    pitem->cmdShape = wParam;
                    InvalidateRect (pitem->hwnd, (LPRECT)NULL,  TRUE);
                    UpdateWindow (pitem->hwnd);
                    SendItemChangeMsg (pitem, ECD_CHANGED);
                    break;

                case IDM_NEW:

                    // create another document widnwo.
                    pdoc = CreateNewDoc ((PSRVR)GetWindowLong (hwnd, 0), NULL
                    if (pdoc == NULL)
                        break;
                    pitem = CreateNewItem (pdoc, IDM_RECT, IDM_RED, TRUE);
                    SetNewItemName (pitem);
                    BringWindowToTop (pdoc->hwnd);
                    break;


                case IDM_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst, "AboutBox", hwnd, lpProcAbout);
                    FreeProcInstance(lpProcAbout);
                    break;

                case IDM_OPEN:
                    /* Call OpenDlg() to get the filename */

                    lpOpenDlg = MakeProcInstance((FARPROC) OpenDlg, hInst);
                    Return = DialogBox(hInst, "Open", hwnd, lpOpenDlg);
                    FreeProcInstance(lpOpenDlg);

                    if (!CreateDocFromFile ((PSRVR)GetWindowLong (hwnd, 0), (
                        MessageBox (
                              hwndMain,
                              "reading from file failed",
                              "Server Sample Sample Application",
                               MB_OK);


                    break;

                case IDM_SAVE:

                    lpSaveDlg = MakeProcInstance((FARPROC) SaveDlg, hInst);
                    Return = DialogBox(hInst, "Save", hwnd, lpSaveDlg);
                    FreeProcInstance(lpSaveDlg);

                    SaveDocIntoFile (pdoc = (PDOC) (GetWindowLong (GetWindow
                        (LPSTR)OpenName);

                    // send message for save
                    SendSrvrChangeMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_SA
                    SendDocRenameMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_REN
                    break;


                case IDM_SAVEAS:
                case IDM_PRINT:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "Server Sample Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;



                case IDM_EXIT:
                    SendSrvrChangeMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_CL
                    DeleteServer ((PSRVR)GetWindowLong (hwnd, 0));
                    break;

                /* edit menu commands */

                case IDM_UNDO:
                case IDM_CUT:
                case IDM_COPY:

                    CutCopyItem (hwnd);
                    break;

                case IDM_PASTE:
                case IDM_CLEAR:
                    MessageBox (
                          GetFocus(),
                          "Command not implemented",
                          "Server Sample  Sample Application",
                          MB_ICONASTERISK | MB_OK);
                    break;

                case IDC_EDIT:
                    if (HIWORD (lParam) == EN_ERRSPACE) {
                        MessageBox (
                              GetFocus ()
                            , "Out of memory."
                            , "server Sample  Sample Application"
                            , MB_ICONHAND | MB_OK
                        );
                    }
                    break;

            }
            break;

        case WM_SIZE:
            if (wParam == SIZENORMAL)
                ReSizeAllDocs (hwnd, LOWORD (lParam), HIWORD (lParam));

            break;

        case WM_CLOSE:
            SendSrvrChangeMsg ((PSRVR)GetWindowLong (hwnd, 0), ECD_CLOSED);
            DeleteServer ((PSRVR)GetWindowLong (hwnd, 0));
            break;

        case WM_DESTROY:
            PostQuitMessage (0);
            break;

        default:
            return (DefWindowProc(hwnd, message, wParam, lParam));
    }
    return (NULL);
}





HANDLE FAR PASCAL SaveDlg (hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned message;
WORD     wParam;
LONG     lParam;
{

    switch (message) {
        case WM_COMMAND:
            switch (wParam) {

                case IDOK:
                    GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);

                    AddExt(OpenName, DefExt);
                    EndDialog(hDlg, TRUE);
                    return (TRUE);

                case IDCANCEL:
                    EndDialog(hDlg, NULL);
                    return (FALSE);
            }
            break;

        case WM_INITDIALOG:                        /* message: initialize
            SetDlgItemText(hDlg, IDC_EDIT, (LPSTR)"shape1.sha");
            SendDlgItemMessage(hDlg,               /* dialog handle      */
                IDC_EDIT,                          /* where to send message
                EM_SETSEL,                         /* select characters
                NULL,                              /* additional information
                MAKELONG(0, 0x7fff));              /* entire contents      */
            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE); /* Indicates the focus is set to a control */
    }
    return FALSE;
}




HANDLE FAR PASCAL OpenDlg(hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned message;
WORD     wParam;
LONG     lParam;
{
    HANDLE hFile=1;     /* Temp value for return */

    switch (message) {
        case WM_COMMAND:
            switch (wParam) {

                case IDC_LISTBOX:
                    switch (HIWORD(lParam)) {

                        case LBN_SELCHANGE:
                            /* If item is a directory name, append "*.*" */
                            if (DlgDirSelect(hDlg, str, IDC_LISTBOX))
                                strcat(str, DefSpec);

                            SetDlgItemText(hDlg, IDC_EDIT, str);
                            SendDlgItemMessage(hDlg,
                                IDC_EDIT,
                                EM_SETSEL,
                                NULL,
                                MAKELONG(0, 0x7fff));
                            break;

                        case LBN_DBLCLK:
                            goto openfile;
                    }
                    return (TRUE);

                case IDOK:
openfile:
                    GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);
                    if (strchr(OpenName, '*') || strchr(OpenName, '?')) {
                        SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,
                            (LPSTR) OpenName);
                        if (str[0])
                            strcpy(DefPath, str);
                        ChangeDefExt(DefExt, DefSpec);
                        UpdateListBox(hDlg);
                        return (TRUE);
                    }

                    if (!OpenName[0]) {
                        MessageBox(hDlg, "No filename specified.",
                            NULL, MB_OK | MB_ICONHAND);
                        return (TRUE);
                    }

                    AddExt(OpenName, DefExt);

                    /* The routine to open the file would go here, and the */
                    /* file handle would be returned instead of NULL.
                    EndDialog(hDlg, hFile);
                    return (TRUE);

                case IDCANCEL:
                    EndDialog(hDlg, NULL);
                    return (FALSE);
            }
            break;

        case WM_INITDIALOG:                        /* message: initialize
            UpdateListBox(hDlg);
            SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
            SendDlgItemMessage(hDlg,               /* dialog handle      */
                IDC_EDIT,                          /* where to send message
                EM_SETSEL,                         /* select characters
                NULL,                              /* additional information
                MAKELONG(0, 0x7fff));              /* entire contents      */
            SetFocus(GetDlgItem(hDlg, IDC_EDIT));
            return (FALSE); /* Indicates the focus is set to a control */
    }
    return FALSE;
}



void UpdateListBox(hDlg)
HWND hDlg;
{
    strcpy(str, DefPath);
    strcat(str, DefSpec);
    DlgDirList(hDlg, str, IDC_LISTBOX, IDC_PATH, 0x4010);

    /* To ensure that the listing is made for a subdir. of
     * current drive dir...
     */
    if (!strchr (DefPath, ':'))
  DlgDirList(hDlg, DefSpec, IDC_LISTBOX, IDC_PATH, 0x4010);

    /* Remove the '..' character from path if it exists, since this
     * will make DlgDirList move us up an additional level in the tree
     * when UpdateListBox() is called again.
     */
    if (strstr (DefPath, ".."))
  DefPath[0] = '\0';

    SetDlgItemText(hDlg, IDC_EDIT, DefSpec);
}


void ChangeDefExt(Ext, Name)
PSTR Ext, Name;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr)
        if (!strchr(pTptr, '*') && !strchr(pTptr, '?'))
            strcpy(Ext, pTptr);
}


void SeparateFile(hDlg, lpDestPath, lpDestFileName, lpSrcFileName)
HWND hDlg;
LPSTR lpDestPath, lpDestFileName, lpSrcFileName;
{
    LPSTR lpTmp;
    char  cTmp;

    lpTmp = lpSrcFileName + (long) lstrlen(lpSrcFileName);
    while (*lpTmp != ':' && *lpTmp != '\\' && lpTmp > lpSrcFileName)
        lpTmp = AnsiPrev(lpSrcFileName, lpTmp);
    if (*lpTmp != ':' && *lpTmp != '\\') {
        lstrcpy(lpDestFileName, lpSrcFileName);
        lpDestPath[0] = 0;
        return;
    }
    lstrcpy(lpDestFileName, lpTmp + 1);
    cTmp = *(lpTmp + 1);
    lstrcpy(lpDestPath, lpSrcFileName);
     *(lpTmp + 1) = cTmp;
    lpDestPath[(lpTmp - lpSrcFileName) + 1] = 0;
}



void AddExt(Name, Ext)
PSTR Name, Ext;
{
    PSTR pTptr;

    pTptr = Name;
    while (*pTptr && *pTptr != '.')
        pTptr++;
    if (*pTptr != '.')
        strcat(Name, Ext);
}


BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:
            return (TRUE);

        case WM_COMMAND:
      if (wParam == IDOK
                || wParam == IDCANCEL) {
                EndDialog(hDlg, TRUE);
                return (TRUE);
            }
            break;
    }
    return (FALSE);
}


void   DrawDragRect (hwnd)
HWND    hwnd;
{

        HDC hdc;

        hdc = GetDC(hwnd);
        InvertRect (hdc, (LPRECT)&dragRect);
        ReleaseDC (hwnd, hdc);

}

void    ReSizeAllDocs (hwndSrvr, width, height)
HWND    hwndSrvr;
int     width;
int     height;
{
    HWND    hwnd;
    RECT    rc;


    hwnd = GetWindow (hwndSrvr, GW_CHILD);
    while (hwnd){
        GetWindowRect (hwnd, (LPRECT)&rc);
        ScreenToClient (hwndSrvr, (LPPOINT)&rc);
        MoveWindow (hwnd, rc.left, rc.top,
            width , height, TRUE);

        hwnd = GetWindow (hwnd, GW_HWNDNEXT);
    }

}
void    ReSizeAllItems (hwndDoc, width, height)
HWND    hwndDoc;
int     width;
int     height;
{
    HWND    hwnd;
    RECT    rc;


    hwnd = GetWindow (hwndDoc, GW_CHILD);
    while (hwnd){
        GetWindowRect (hwnd, (LPRECT)&rc);
        ScreenToClient (hwndDoc, (LPPOINT)&rc);
        MoveWindow (hwnd, rc.left, rc.top,
            width >> 1, height >> 1, TRUE);

        hwnd = GetWindow (hwnd, GW_HWNDNEXT);
    }

}

long FAR PASCAL ItemWndProc (hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
{
        POINT   pt;
        HWND    hwndParent;


    switch (message) {
        case WM_PAINT:
            PaintItem (hwnd);
            break;


        case WM_SIZE:
            break;

        case WM_DESTROY:
            DestroyItem (hwnd);
            break;

        case WM_RBUTTONDOWN:


            hwndParent = GetParent (hwnd);
            GetWindowRect (hwnd, (LPRECT) &dragRect);
            ScreenToClient (hwndParent, (LPPOINT)&dragRect);
            ScreenToClient (hwndParent, (LPPOINT)&dragRect.right);

            DrawDragRect (hwndParent);

            dragPt.x = LOWORD(lParam);
            dragPt.y = HIWORD(lParam);

            ClientToScreen (hwnd, (LPPOINT)&dragPt);
            ScreenToClient (hwndParent, (LPPOINT)&dragPt);

            SetCapture (hwnd);
            fCapture = TRUE;
            break;

        case WM_MOUSEMOVE:
            if (!fCapture)
                break;

            hwndParent = GetParent (hwnd);
            DrawDragRect (hwndParent);
            pt.x = LOWORD(lParam);
            pt.y = HIWORD(lParam);

            ClientToScreen (hwnd, (LPPOINT)&pt);
            ScreenToClient (hwndParent, (LPPOINT)&pt);

            OffsetRect ((LPRECT)&dragRect, pt.x - dragPt.x,
                                        pt.y - dragPt.y);

            dragPt.x = pt.x;
            dragPt.y = pt.y;


            DrawDragRect (hwndParent);
            break;


        case WM_RBUTTONUP:
            if (!fCapture)
                return TRUE;

            hwndParent = GetParent (hwnd);
            fCapture = FALSE;
            ReleaseCapture ();
            DrawDragRect (hwndParent);

            MoveWindow (hwnd, dragRect.left, dragRect.top,
                        dragRect.right - dragRect.left,
                        dragRect.bottom - dragRect.top, TRUE);

             // fall thru

        case WM_LBUTTONDOWN:
             BringWindowToTop (hwnd);
             break;

        default:
            return (DefWindowProc(hwnd, message, wParam, lParam));
    }
    return (NULL);
}


BOOL    SaveDocIntoFile (pdoc, lpstr)
PDOC    pdoc;
LPSTR   lpstr;
{


    HWND    hwnd;
    int     fh;
    PITEM   pitem;


    if ((fh =_lcreat (lpstr, 0)) <= 0)
        return FALSE;

    hwnd = GetWindow (pdoc->hwnd, GW_CHILD);

    while (hwnd) {
        pitem = (PITEM) GetWindowLong (hwnd, 0);
        if (!pitem->aName)
            SetNewItemName (pitem);

        if (_lwrite (fh, (LPSTR)pitem, sizeof (ITEM)) <= 0)
            break;

        hwnd = GetWindow (hwnd, GW_HWNDNEXT);
    }
    _lclose (fh);

    SetWindowText (pdoc->hwnd, (LPSTR)lpstr);
    return TRUE;
}


PDOC    CreateDocFromFile (psrvr, lpstr, lhdoc)
PSRVR       psrvr;
LPSTR       lpstr;
LHDOCUMENT  lhdoc;
{

    int     fh;
    ITEM    item;
    PITEM   pitem;
    PDOC    pdoc;


    if ((fh =_lopen (lpstr, OF_READ)) <= 0)
        return FALSE;

    if (!(pdoc = CreateNewDoc (psrvr, lhdoc, lpstr)))
        return FALSE;

    cShapes = 0;
    while (TRUE) {
        if (_lread (fh, (LPSTR)&item, sizeof (ITEM)) <= 0)
            break;

        pitem = CreateNewItem (pdoc, item.cmdShape, item.cmdColor, TRUE);
        SetItemName (pitem, (LPSTR)item.name);
        cShapes++;
    }
    _lclose (fh);


    return pdoc;
}

// doc related routines

PDOC    CreateNewDoc (psrvr, lhdoc, lptitle)
PSRVR   psrvr;
LONG    lhdoc;
LPSTR   lptitle;
{

    RECT        rc;
    HMENU       hMenu;
    HWND        hwnd;

    hwnd = psrvr->hwnd;

    // first set the menu.
    hMenu = GetMenu (hwnd);
    DestroyMenu (hMenu);

    hMenu = LoadMenu (hInst, (LPSTR)"SampleMenu");
    SetMenu (hwnd, hMenu);
    DrawMenuBar (hwnd);

    GetClientRect (hwnd, (LPRECT)&rc);
    if (IsIconic (psrvr->hwnd)){
        // create some reasonale height/wdith for satisfying the
        // data request in iconic mode
        rc.right = GetSystemMetrics (SM_CXSCREEN) >> 1;
        rc.bottom   = GetSystemMetrics (SM_CYSCREEN) >> 1;
    }
    InflateRect ((LPRECT)&rc, -5, -5);

    hwnd = CreateWindow(
        "DocClass",
        "New",
        WS_SYSMENU | WS_CAPTION | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,

        rc.left,
        rc.top,
        (rc.right - rc.left),
        (rc.bottom - rc.top),
        psrvr->hwnd,
        NULL,
        hInst,
        NULL
    );

    SetWindowText (hwnd, lptitle);
    return InitDoc (hwnd, lhdoc);
}

long FAR PASCAL DocWndProc(hwnd, message, wParam, lParam)
HWND hwnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    HWND    hwndChild;
    HWND    hwndParent;
    HMENU   hMenu;

    switch (message) {

        case WM_SIZE:
            if (wParam == SIZENORMAL)
                ReSizeAllItems (hwnd, LOWORD (lParam), HIWORD (lParam));
            break;

        case WM_CLOSE:
            SendDocChangeMsg ((PDOC)GetWindowLong (hwnd, 0), ECD_CLOSED);
            DeleteDoc ((PDOC)GetWindowLong (hwnd, 0));
            break;

        case WM_DESTROY:

            hwndParent = GetParent (hwnd);
            hwndChild = GetWindow(hwndParent, GW_CHILD);

            if (GetWindow (hwndChild, GW_HWNDNEXT))
                break;          // some more doc windows.

            // first set the menu.
            hMenu  = GetMenu (hwndMain);
            DestroyMenu (hMenu);

            // we do not ahve any more doc windows.
            hMenu = LoadMenu (hInst, (LPSTR)"InitMenu");
            SetMenu (hwndMain, hMenu);
            DrawMenuBar (hwndMain);
            break;



        case WM_LBUTTONDOWN:
            BringWindowToTop (hwnd);
            break;

        default:
            return (DefWindowProc(hwnd, message, wParam, lParam));
    }
    return (NULL);
}




Microsoft Windows Sample `C' Source Code


ACSRESRC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\RESOURCE\ACSRESRC.C

/*
 * Name: acsresrc.c
 * Function (s) demonstrated in this program: AccessResource (), FindResource
 *                                           SizeofResource ().
 * Description  :
 *         FindResource is used first to locate and identify the resource
 *         item.  SizeofResource is used to determine how many bytes need
 *         to be read to obtain the resource item, and finally
 *         AccessResource () is used to get the handle and set the file
 *         pointer to the beginning of the selected resource.  AccessResource
 *         opens the file (resource) as a result, so it must be explicitely
 *         closed.  In this case, "It works!" is displayed in a MessageBox ()
 *         upon successful completion, "It failed" displays if unsuccessful.
 * Additional Comments: Note that _lclose () must be used to close the file
 *         (resource).
 */

#include <windows.h>
#include "acsresrc.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);
int     FAR PASCAL _lclose (int);
int     FAR PASCAL _lread (HANDLE, LPSTR, short);

static char  szBuffer[8];
static int  ErrorCheck;
static char  szResName [] = "HotStuff";

int    PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int      nCmdShow;
  {
  static char  szAppName [] = "Resources";
  HWND       hWnd;
  WNDCLASS   wndclass;
  MSG        msg;
  HMENU      hMenu;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hMenu = LoadMenu (hInstance, "ResMenu");

  hWnd = CreateWindow (szAppName, "AccessResource",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0,
                      NULL, hMenu, hInstance, NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND      hWnd;
unsigned  iMessage;
WORD      wParam;
LONG      lParam;
  {
  static HANDLE hInstance, hResource;
  int  hFile;
  char  szStuff[20], szSuccess[20];
  short sRes;

  switch (iMessage)
    {
    case WM_CREATE:
      hInstance = GetWindowWord (hWnd, GWW_HINSTANCE);
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_EXECUTE:
/* FindResource is used first to locate and identify the resource
        item.  SizeofResource is used to determine how many bytes need
        to be read to obtain the resource item, and finally
        AccessResource () is used to get the handle and set the file
        pointer to the beginning of the selected resource.  AccessResource ()
        opens the file (resource) as a result, so it must be explicitely
        closed.
     */
          hResource = FindResource (hInstance, "HotStuff", RT_RCDATA);
          sRes = SizeofResource (hInstance, hResource);
          hFile = AccessResource (hInstance, hResource);
          ErrorCheck = _lread (hFile, (LPSTR)szStuff, sRes);
          ErrorCheck = _lclose (hFile);
          if (hFile < 1)
            {
            ErrorCheck = sprintf (szStuff, "It failed");
            ErrorCheck = sprintf (szSuccess, "Error");
            }
    else
            ErrorCheck = sprintf (szSuccess, "Item read");
          MessageBox (GetFocus (), szStuff, szSuccess, MB_OK);
        }
        break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


ADDATOM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\ADDATOM.C

/*
 * Function (s) demonstrated in this program: AddAtom
 * Compiler version: MSC v5.10
 * Description: Program adds a character string to the atom table and creates
 *              a new atom that uniquely identifies the string.
 */

#include <windows.h>
#include "addatom.h"

int     sprintf (LPSTR, LPSTR, int);
long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int         nCmdShow;
  {
  static char   szAppName [] = "AddAtom";
  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG msg;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hMenu = LoadMenu (hInstance, "OurMenu");
  hWnd = CreateWindow (szAppName, "AddAtom Demonstration",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT,  0,
                      NULL, hMenu, hInstance, NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  int  AtomMaxSize = 20;
  ATOM  lpIDForAtom;
  WORD ActualAtomSize;
  int  hToAtom;
  BOOL  bTableAdded;
  char  szBuff[20];

  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == IDM_EXECUTE)
        {
        SetFocus (hWnd);
        lpIDForAtom = AddAtom ( (LPSTR)"Hello World");
        ActualAtomSize = GetAtomName (lpIDForAtom, (LPSTR)szBuff, AtomMaxSize
        MessageBox (GetFocus (), (LPSTR)szBuff, (LPSTR)"Atom added was...", M
        hToAtom = GetAtomHandle (lpIDForAtom);
        lpIDForAtom = DeleteAtom (lpIDForAtom);
        if (lpIDForAtom == NULL)
          MessageBox (GetFocus (), (LPSTR)"Success", (LPSTR)"Atom Deleted", M
        else
          MessageBox (GetFocus (), (LPSTR)"Failure", (LPSTR)"Atom not deleted
        }
      else
        return (DefWindowProc (hWnd, iMessage, wParam, lParam));
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


ADDFONT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\FONTS\ADDFONT.C

/*
 * Name               : AddFont.c
 * Function(s) demonstrated in this program :
 *     AddFontResource (), RemoveFontResource (), SendMessage ().
 * Description        : AddFontResource loads an external file of fonts,
 *                      returning a short integer of fonts that have been
 *                      added.  SendMessage sends a WM_FONTCHANGE message
 *                      to notify other windows of the change.
 *                      RemoveFontResource is used to remove the resource
 *                      that was added.  The resource may be added multiple
 *                      times, and deleted once for every time it was added.
 *                      If you attempt to delete it furthermore, an error
 *                      message comes up indicating that the resource is not
 *                      available to delete.
 *
 * NOTE:                Script.fon is required to be in the same directory.
 *
 */

#include <windows.h>
#include "addfont.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);
int     sprintf (PSTR, PSTR, int);

static char  szBuffer[] = "script.fon";
static int  ErrorCheck;
static char  szResName [] = "ResMenu";

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int         nCmdShow;
  {
  static char   szAppName [] = "FontResources";
  HWND      hWnd;
  WNDCLASS  wndclass;
  MSG       msg;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hWnd = CreateWindow (szAppName, "The Joy of FontResources",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0,
                      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  static HANDLE hInstance, hResource;
  int  hFile;
  char  szBuf[50];
  short  sRes;
  HMENU hMenu;
  switch (iMessage)
    {
    case WM_CREATE:
      hInstance = GetWindowWord (hWnd, GWW_HINSTANCE);
      hMenu = LoadMenu (hInstance, "ResMenu");
      SetMenu (hWnd, hMenu);
      DrawMenuBar (hWnd);
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_ADDFONT:
          ErrorCheck = AddFontResource ( (LPSTR)szBuffer);
          SendMessage (-1, WM_FONTCHANGE, 0, 0L);
          ErrorCheck = sprintf (szBuf, "%i", ErrorCheck);
          MessageBox (GetFocus (), szBuf, "Number of added Fonts", MB_OK);
          break;

        case IDM_REMOVEFONT:
          sRes = RemoveFontResource ( (LPSTR)szBuffer);
          if (sRes != NULL)
            {
            ErrorCheck = sprintf (szBuf, "%i:  indicating the FontResource wa
            MessageBox (GetFocus (), szBuf, "RemoveFontResource returns", MB_
            }
    else
            MessageBox (GetFocus (), "Problem removing Font!", "Error", MB_OK
          SendMessage (-1, WM_FONTCHANGE, 0, 0L);
    break;
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


ADWIRE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\ADWIRE.C

/*
 *
 *   Function (s) demonstrated in this program:
 *        AdjustWindowRect ()
 *
 *   Compiler version:
 *        Microsoft C 5.1
 *
 *   Description:
 *        This function demonstrates the use of the AdjustWindowRect function
 *        It will compute the required size of the window rectangle based on
 *        the desired client-rectangle size.  The window rectangle will then
 *        passed to the CreateWindow function to create a Window whose client
 *        area is the desired size.
 *
 *
 */

#include <windows.h>

BOOL FAR PASCAL InitCreateWindow (HANDLE, HANDLE, int);
long  FAR PASCAL CreateWindowProc (HANDLE, unsigned, WORD, LONG);

int  PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int  nCmdShow;
{
  MSG msg;

  InitCreateWindow (hInstance, hPrevInstance, nCmdShow);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
  }
  exit (msg.wParam);
}


BOOL FAR PASCAL InitCreateWindow (hInstance, hPrevInstance, cmdShow)
HANDLE   hInstance;
HANDLE   hPrevInstance;
int  cmdShow;
{
  WNDCLASS  wcCreateWindowClass;
  HWND  hWnd;

  wcCreateWindowClass.lpszClassName = (LPSTR) "CreateWindow";
  wcCreateWindowClass.hInstance     = hInstance;
  wcCreateWindowClass.lpfnWndProc   = CreateWindowProc;
  wcCreateWindowClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcCreateWindowClass.hIcon         = NULL;
  wcCreateWindowClass.lpszMenuName  = (LPSTR) NULL;
  wcCreateWindowClass.hbrBackground = GetStockObject (BLACK_BRUSH);
  wcCreateWindowClass.style         = CS_HREDRAW | CS_VREDRAW;
  wcCreateWindowClass.cbClsExtra    = 0;
  wcCreateWindowClass.cbWndExtra    = 0;

  RegisterClass ( (LPWNDCLASS) & wcCreateWindowClass);

  hWnd = CreateWindow ( (LPSTR) "CreateWindow", (LPSTR) "AdjustWindowRect",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, cmdShow);         /* Display this window on the screen  *
  UpdateWindow (hWnd);                              /* Cause a paint message

  return TRUE;
}


long  FAR PASCAL CreateWindowProc (hWnd, message, wParam, lParam)
HWND        hWnd;
unsigned  message;
WORD        wParam;
LONG        lParam;
{
  switch (message)
  {
  case WM_PAINT:
    PaintCreate (hWnd);
    break;

  case WM_DESTROY:
    PostQuitMessage (0);
    break;

  default:
    return (DefWindowProc (hWnd, message, wParam, lParam));
    break;
  }
  return (0L);
}


PaintCreate (hWnd)  /*  The Paint Procedure  */
HWND    hWnd;
{
  PAINTSTRUCT  ps;
  HDC          hDC;
  BOOL         bMenu;
  long  lStyle;
  HANDLE       hOldBrush, hBrush;
  RECT         lpRect;

  BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);

  hDC = ps.hdc;                                  /* Get the Display Context
  lStyle = WS_TILED;
  bMenu = 0;
  hBrush         = GetStockObject (BLACK_BRUSH);  /* Get a Black brush     */
  hOldBrush      = SelectObject (hDC, hBrush);   /* Select the new brush  */

  SetMapMode (hDC, MM_ANISOTROPIC);              /* Set the mapping mode  */
  SetWindowExt (hDC, 200, 200);           /* Set Extent of viewing area. */
  GetClientRect (hWnd, (LPRECT) & lpRect);     /* Get size of client area. */
  SetViewportExt (hDC, lpRect.right, lpRect.bottom); /* Set extent of viewpor
  AdjustWindowRect (&lpRect, lStyle, bMenu);
  TextOut (hDC, 10, 10,
      (LPSTR)"Smallest rectangle that will encompass the entire Window.",
      strlen ("Smallest rectangle that will encompass the entire Window."));

  ValidateRect (hWnd, (LPRECT) NULL);   /* Disable any more paint messages  *
  EndPaint (hWnd, (LPPAINTSTRUCT) & ps);

  SelectObject (hDC, hOldBrush);                /*  Replace the old brush  */

  return TRUE;
}




ADWIRE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\ADWIRE.C

/*
 *
 *   Function (s) demonstrated in this program:
 *        AdjustWindowRect ()
 *
 *   Compiler version:
 *        Microsoft C 5.1
 *
 *   Description:
 *        This function demonstrates the use of the AdjustWindowRect function
 *        It will compute the required size of the window rectangle based on
 *        the desired client-rectangle size.  The window rectangle will then
 *        passed to the CreateWindow function to create a Window whose client
 *        area is the desired size.
 *
 *
 */

#include <windows.h>

BOOL FAR PASCAL InitCreateWindow (HANDLE, HANDLE, int);
long  FAR PASCAL CreateWindowProc (HANDLE, unsigned, WORD, LONG);

int  PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int  nCmdShow;
{
  MSG msg;

  InitCreateWindow (hInstance, hPrevInstance, nCmdShow);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
  }
  exit (msg.wParam);
}


BOOL FAR PASCAL InitCreateWindow (hInstance, hPrevInstance, cmdShow)
HANDLE   hInstance;
HANDLE   hPrevInstance;
int  cmdShow;
{
  WNDCLASS  wcCreateWindowClass;
  HWND  hWnd;

  wcCreateWindowClass.lpszClassName = (LPSTR) "CreateWindow";
  wcCreateWindowClass.hInstance     = hInstance;
  wcCreateWindowClass.lpfnWndProc   = CreateWindowProc;
  wcCreateWindowClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcCreateWindowClass.hIcon         = NULL;
  wcCreateWindowClass.lpszMenuName  = (LPSTR) NULL;
  wcCreateWindowClass.hbrBackground = GetStockObject (BLACK_BRUSH);
  wcCreateWindowClass.style         = CS_HREDRAW | CS_VREDRAW;
  wcCreateWindowClass.cbClsExtra    = 0;
  wcCreateWindowClass.cbWndExtra    = 0;

  RegisterClass ( (LPWNDCLASS) & wcCreateWindowClass);

  hWnd = CreateWindow ( (LPSTR) "CreateWindow", (LPSTR) "AdjustWindowRect",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, cmdShow);         /* Display this window on the screen  *
  UpdateWindow (hWnd);                              /* Cause a paint message

  return TRUE;
}


long  FAR PASCAL CreateWindowProc (hWnd, message, wParam, lParam)
HWND        hWnd;
unsigned  message;
WORD        wParam;
LONG        lParam;
{
  switch (message)
  {
  case WM_PAINT:
    PaintCreate (hWnd);
    break;

  case WM_DESTROY:
    PostQuitMessage (0);
    break;

  default:
    return (DefWindowProc (hWnd, message, wParam, lParam));
    break;
  }
  return (0L);
}


PaintCreate (hWnd)  /*  The Paint Procedure  */
HWND    hWnd;
{
  PAINTSTRUCT  ps;
  HDC          hDC;
  BOOL         bMenu;
  long  lStyle;
  HANDLE       hOldBrush, hBrush;
  RECT         lpRect;

  BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);

  hDC = ps.hdc;                                  /* Get the Display Context
  lStyle = WS_TILED;
  bMenu = 0;
  hBrush         = GetStockObject (BLACK_BRUSH);  /* Get a Black brush     */
  hOldBrush      = SelectObject (hDC, hBrush);   /* Select the new brush  */

  SetMapMode (hDC, MM_ANISOTROPIC);              /* Set the mapping mode  */
  SetWindowExt (hDC, 200, 200);           /* Set Extent of viewing area. */
  GetClientRect (hWnd, (LPRECT) & lpRect);     /* Get size of client area. */
  SetViewportExt (hDC, lpRect.right, lpRect.bottom); /* Set extent of viewpor
  AdjustWindowRect (&lpRect, lStyle, bMenu);
  TextOut (hDC, 10, 10,
      (LPSTR)"Smallest rectangle that will encompass the entire Window.",
      strlen ("Smallest rectangle that will encompass the entire Window."));

  ValidateRect (hWnd, (LPRECT) NULL);   /* Disable any more paint messages  *
  EndPaint (hWnd, (LPPAINTSTRUCT) & ps);

  SelectObject (hDC, hOldBrush);                /*  Replace the old brush  */

  return TRUE;
}




ALLOCRES.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\RESOURCE\ALLOCRES.C

/*
 * Name: allocres.c
 * Function (s) demonstrated : AllocResource (), FindResource (),
 *                             SizeofResource (), AccessResource ().
 * Windows version    : 2.03
 * Compiler version   : 5.1
 * Description        :
 *         FindResource is used first to locate and identify the resource
 *         item.  SizeofResource is used to determine how many bytes need
 *         to be read to obtain the resource item, AllocResource () is used
 *         to allocate memory for the resource, and finally AccessResource ()
 *         allows us to read the resource in directly.
 *
 */

#include <windows.h>
#include "AllocRes.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);
int     FAR PASCAL _lclose (int);
int     FAR PASCAL _lread (HANDLE, LPSTR, short);

static char  szBuffer[8];
static int  ErrorCheck;
static char  szResName [] = "HotStuff";

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int         nCmdShow;
  {
  static char szAppName [] = "Resources";
  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG         msg;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hWnd = CreateWindow (szAppName, "The Joy of Resources",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0,
                      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND      hWnd;
unsigned  iMessage;
WORD      wParam;
LONG      lParam;
  {
  static HANDLE hInstance, hResource, hGlobRes;
  int  hFile;
  char  far *szStuff, szSuccess[20];
  short  sRes;
  HMENU  hMenu;

  switch (iMessage)
    {
    case WM_CREATE:
      hInstance = GetWindowWord (hWnd, GWW_HINSTANCE);
      hMenu = LoadMenu (hInstance, "ResMenu");
      SetMenu (hWnd, hMenu);
      DrawMenuBar (hWnd);
      break;
    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_EXECUTE:
      /*  FindResource is used first to locate and identify the resource
       *  item.  SizeofResource is used to determine how many bytes need
       *  to be read to obtain the resource item, AllocResource () reserves
       *  the memory to store the resource and AccessResource () permits
       *  reading of the resource.
       */
          hResource = FindResource (hInstance, "HotStuff", RT_RCDATA);
          sRes = SizeofResource (hInstance, hResource);
          hGlobRes = AllocResource (hInstance, hResource, (DWORD)sRes);
          ErrorCheck = sprintf (szStuff, "%i", hGlobRes);
          MessageBox (GetFocus (), szStuff, "hGlobRes returns...", MB_OK);
          szStuff = GlobalLock (hGlobRes);
          hFile = AccessResource (hInstance, hResource);
          ErrorCheck = _lread (hFile, (LPSTR)szStuff, sRes);
          ErrorCheck = GlobalUnlock (hGlobRes);
          hGlobRes = GlobalFree (hGlobRes);
          ErrorCheck = _lclose (hFile);
          if (hFile < 1)
            {
            ErrorCheck = sprintf (szStuff, "It failed");
            ErrorCheck = sprintf (szSuccess, "Error");
            }
    else
            ErrorCheck = sprintf (szSuccess, "Item read");
          MessageBox (GetFocus (), szStuff, szSuccess, MB_OK);
          break;

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

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


ANSI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\ANSI.C

/*
 *
 *   Function (s) demonstrated in this program:
 *        AnsiLower (LPSTR)
 *        AnsiUpper (LPSTR)
 *        AnsiToOem (LPSTR, LPSTR)
 *        AnsiNext (LPSTR)
 *        AnsiPrev (LPSTR, LPSTR)
 *        OemToAnsi (LPSTR, LPSTR)
 */

#include <windows.h>
#include <stdio.h>

#define MAXSTRING 80

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int      cmdShow;
  {
  HWND      hWnd;
  WNDCLASS  wndclass;
  MSG       msg;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = "ANSI";

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hWnd = CreateWindow ("ANSI",
                      "Ansi Functions",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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


long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HDC         hDC;
  HMENU       hMenu;
  TEXTMETRIC  tm;
  char  szAnsiBuff[MAXSTRING];
  char  szOemBuff[MAXSTRING];

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"Display", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_INITMENU:
      InvalidateRect (hWnd, NULL, TRUE);
      break;

    case WM_COMMAND:
      if (wParam == 100)
        {
        hDC = GetDC (hWnd);
        GetTextMetrics (hDC, (LPTEXTMETRIC) & tm);
        sprintf (szAnsiBuff, "A Sample String: aBcDwXyZ ⌐½«▓│║");
        TextOut (hDC, 1, tm.tmHeight * 1, (LPSTR)"ANSI Character Set", 18);
        TextOut (hDC, 1, tm.tmHeight * 2, (LPSTR)szAnsiBuff, 31);

        AnsiToOem ( (LPSTR)szAnsiBuff, (LPSTR)szOemBuff);
        TextOut (hDC, 1, tm.tmHeight * 4,
            (LPSTR)"ANSI Characters Converted to Nearest OEM Characters by An
            67);
        TextOut (hDC, 1, tm.tmHeight * 5, (LPSTR)szOemBuff, 31);

        OemToAnsi ( (LPSTR)szOemBuff, (LPSTR)szAnsiBuff);
        TextOut (hDC, 1, tm.tmHeight * 7,
            (LPSTR)"OEM Characters Converted to Nearest ANSI Characters by Oe
            67);
        TextOut (hDC, 1, tm.tmHeight * 8, (LPSTR)szAnsiBuff, 31);

  /* Convert original ANSI string to all lower case. */
        TextOut (hDC, 1, tm.tmHeight * 10,
            (LPSTR)"Original ANSI String Processed by AnsiLower ()", 46);
        TextOut (hDC, 1, tm.tmHeight * 11, AnsiLower ( (LPSTR)szAnsiBuff), 31

  /* Convert lower case ANSI string to all upper case. */
        TextOut (hDC, 1, tm.tmHeight * 13,
            (LPSTR)"Lower Case ANSI String Processed by AnsiUpper ()", 48);
        TextOut (hDC, 1, tm.tmHeight * 14, AnsiUpper ( (LPSTR)szAnsiBuff), 31

  /* Use AnsiNext () and AnsiPrev (). */
        TextOut (hDC, 1, tm.tmHeight * 16,
            (LPSTR)"Display String Starting at Next Char After Fifth Char Usi
            71);
        TextOut (hDC, 1, tm.tmHeight * 17, AnsiNext ( (LPSTR) & szAnsiBuff[4]
            26);

        TextOut (hDC, 1, tm.tmHeight * 19,
            (LPSTR)"Display String Starting at Char Previous to Fifth Char Us
            72);
        TextOut (hDC, 1, tm.tmHeight * 20, AnsiPrev ( (LPSTR)szAnsiBuff,
            (LPSTR) & szAnsiBuff[4]), 27);

        ReleaseDC (hWnd, hDC);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


ANSI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\ANSI.C

/*
 *
 *   Function (s) demonstrated in this program:
 *        AnsiLower (LPSTR)
 *        AnsiUpper (LPSTR)
 *        AnsiToOem (LPSTR, LPSTR)
 *        AnsiNext (LPSTR)
 *        AnsiPrev (LPSTR, LPSTR)
 *        OemToAnsi (LPSTR, LPSTR)
 */

#include <windows.h>
#include <stdio.h>

#define MAXSTRING 80

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int      cmdShow;
  {
  HWND      hWnd;
  WNDCLASS  wndclass;
  MSG       msg;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = "ANSI";

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hWnd = CreateWindow ("ANSI",
                      "Ansi Functions",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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


long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HDC         hDC;
  HMENU       hMenu;
  TEXTMETRIC  tm;
  char  szAnsiBuff[MAXSTRING];
  char  szOemBuff[MAXSTRING];

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"Display", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_INITMENU:
      InvalidateRect (hWnd, NULL, TRUE);
      break;

    case WM_COMMAND:
      if (wParam == 100)
        {
        hDC = GetDC (hWnd);
        GetTextMetrics (hDC, (LPTEXTMETRIC) & tm);
        sprintf (szAnsiBuff, "A Sample String: aBcDwXyZ ⌐½«▓│║");
        TextOut (hDC, 1, tm.tmHeight * 1, (LPSTR)"ANSI Character Set", 18);
        TextOut (hDC, 1, tm.tmHeight * 2, (LPSTR)szAnsiBuff, 31);

        AnsiToOem ( (LPSTR)szAnsiBuff, (LPSTR)szOemBuff);
        TextOut (hDC, 1, tm.tmHeight * 4,
            (LPSTR)"ANSI Characters Converted to Nearest OEM Characters by An
            67);
        TextOut (hDC, 1, tm.tmHeight * 5, (LPSTR)szOemBuff, 31);

        OemToAnsi ( (LPSTR)szOemBuff, (LPSTR)szAnsiBuff);
        TextOut (hDC, 1, tm.tmHeight * 7,
            (LPSTR)"OEM Characters Converted to Nearest ANSI Characters by Oe
            67);
        TextOut (hDC, 1, tm.tmHeight * 8, (LPSTR)szAnsiBuff, 31);

  /* Convert original ANSI string to all lower case. */
        TextOut (hDC, 1, tm.tmHeight * 10,
            (LPSTR)"Original ANSI String Processed by AnsiLower ()", 46);
        TextOut (hDC, 1, tm.tmHeight * 11, AnsiLower ( (LPSTR)szAnsiBuff), 31

  /* Convert lower case ANSI string to all upper case. */
        TextOut (hDC, 1, tm.tmHeight * 13,
            (LPSTR)"Lower Case ANSI String Processed by AnsiUpper ()", 48);
        TextOut (hDC, 1, tm.tmHeight * 14, AnsiUpper ( (LPSTR)szAnsiBuff), 31

  /* Use AnsiNext () and AnsiPrev (). */
        TextOut (hDC, 1, tm.tmHeight * 16,
            (LPSTR)"Display String Starting at Next Char After Fifth Char Usi
            71);
        TextOut (hDC, 1, tm.tmHeight * 17, AnsiNext ( (LPSTR) & szAnsiBuff[4]
            26);

        TextOut (hDC, 1, tm.tmHeight * 19,
            (LPSTR)"Display String Starting at Char Previous to Fifth Char Us
            72);
        TextOut (hDC, 1, tm.tmHeight * 20, AnsiPrev ( (LPSTR)szAnsiBuff,
            (LPSTR) & szAnsiBuff[4]), 27);

        ReleaseDC (hWnd, hDC);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


ANYPOPUP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\ANYPOPUP.C

/*
 *   This program demonstrates the use of the AnyPopup () function.
 *   AnyPopup () determines if a popup window is present on the screen, even
 *   if hidden. AnyPop () is called in response to choosing the "AnyPopup?"
 *   menu option. To create a popup, choose the "Create Popup" menu option.
 *   This function can also be tested by bringing up another application
 *   which creates a popup window.
 */

#include "windows.h"
#include "anypopup.h"

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);
long    FAR PASCAL PopupProc (HWND, unsigned, WORD, LONG);

HWND hPopup = NULL;   /* handle to the popup window */
HANDLE hInst;

BOOL HelloInit (hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));

  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon          = LoadIcon (hInstance, NULL);
  pHelloClass->lpszMenuName      = (LPSTR)"anypopup";
  pHelloClass->lpszClassName     = (LPSTR)"AnyPopup";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon          = LoadIcon (hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName  = (LPSTR)"CHILD A";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc   = PopupProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree ( (HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
  }

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  HelloInit (hInstance);

  hInst = hInstance;

  hWnd = CreateWindow ( (LPSTR)"AnyPopup", "AnyPopup ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0,
                      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  switch (message)
    {
    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_ANYPOPUP:
                /* are there any  popup windows present in the system ? */
          if (AnyPopup ())  /* if yes, say so */
            MessageBox (NULL, (LPSTR)"there ARE popup windows present",
                       (LPSTR)"AnyPopup () says...", MB_OK);
          else
            MessageBox (NULL, (LPSTR)"there are NOT popup windows present",
                       (LPSTR)"AnyPopup () says...", MB_OK);
          break;

        case IDM_CREATEPOPUP:     /*  Create a popup Window  */
          hPopup = CreateWindow ( (LPSTR)"CHILD A",
                                  (LPSTR)"Child A (WS_POPUP)", WS_POPUP |
                                  WS_VISIBLE | WS_CAPTION | WS_CLIPSIBLINGS |
                                  WS_BORDER | WS_SYSMENU, 45, 60, 250, 200,
                                  hWnd, NULL, hInst, NULL);
          break;
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }

long    FAR PASCAL PopupProc (hChildAWnd, message, wParam, lParam)
HWND      hChildAWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  switch (message)
    {
    default:
      return DefWindowProc (hChildAWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


APP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\HOOKS\JOURNAL\APP.C

/*  APP.c
    Skeleton Application
    Windows Toolkit Version 2.00
    Copyright (c) Microsoft 1987
*/

#include "windows.h"
#include "APP.h"

char szAppName[10];
char szAbout[10];
char szMessage[15];
int MessageLength;
HANDLE hInst;
FARPROC lpprocAbout;

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL About( HWND, unsigned, WORD, LONG );


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    if (!hPrevInstance) {
        /* Call initialization procedure if this is the first instance */
        if (!Init( hInstance ))
            return FALSE;
        }
    else {
        /* ONLY ONE INSTANCE */
        return FALSE;
        }

    hWnd = CreateWindow((LPSTR)szAppName,
                        (LPSTR)szMessage,
                        WS_OVERLAPPEDWINDOW,
                        400,               /*  x - ignored for tiled windows
                        0,                 /*  y - ignored for tiled windows
                        CW_USEDEFAULT,     /* cx - ignored for tiled windows
                        0,                 /* cy - ignored for tiled windows
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Save instance handle for DialogBox */
    hInst = hInstance;

    /* Insert "About..." into system menu */
    hMenu = GetSystemMenu(hWnd, FALSE);
    ChangeMenu(hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
    ChangeMenu(hMenu, 0, (LPSTR)szAbout, IDSABOUT, MF_APPEND | MF_STRING);

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}
/*
*/


/* Procedure called when the application is loaded for the first time */
BOOL Init( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pAPPClass;

    /* Load strings from resource */
    LoadString( hInstance, IDSNAME, (LPSTR)szAppName, 10 );
    LoadString( hInstance, IDSABOUT, (LPSTR)szAbout, 10 );
    MessageLength = LoadString( hInstance, IDSTITLE, (LPSTR)szMessage, 15 );

    pAPPClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pAPPClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pAPPClass->hIcon          = LoadIcon( hInstance, MAKEINTRESOURCE(APPICON)
    pAPPClass->lpszMenuName   = (LPSTR)szAppName;
    pAPPClass->lpszClassName  = (LPSTR)szAppName;
    pAPPClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pAPPClass->hInstance      = hInstance;
    pAPPClass->style          = CS_HREDRAW | CS_VREDRAW;
    pAPPClass->lpfnWndProc    = WndProc;

    if (!RegisterClass( (LPWNDCLASS)pAPPClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pAPPClass );
    return TRUE;        /* Initialization succeeded */
}
/*
*/


APP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\HOOKS\MENUHELP\APP.C

/*  APP.c
    Skeleton Application
    Windows Toolkit Version 2.00
    Copyright (c) Microsoft 1987
*/

#include "windows.h"
#include "APP.h"

char szAppName[10];
char szAbout[10];
char szMessage[15];
int MessageLength;
HANDLE hInst;
FARPROC lpprocAbout;

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL About( HWND, unsigned, WORD, LONG );


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    if (!hPrevInstance) {
        /* Call initialization procedure if this is the first instance */
        if (!Init( hInstance ))
            return FALSE;
        }
    else {
        /* Copy data from previous instance */
        GetInstanceData( hPrevInstance, (PSTR)szAppName, 10 );
        GetInstanceData( hPrevInstance, (PSTR)szAbout, 10 );
        GetInstanceData( hPrevInstance, (PSTR)szMessage, 15 );
        GetInstanceData( hPrevInstance, (PSTR)&MessageLength, sizeof(int) );
        }

    hWnd = CreateWindow((LPSTR)szAppName,
                        (LPSTR)szMessage,
                        WS_OVERLAPPEDWINDOW,
                        400,               /*  x - ignored for tiled windows
                        0,                 /*  y - ignored for tiled windows
                        CW_USEDEFAULT,     /* cx - ignored for tiled windows
                        0,                 /* cy - ignored for tiled windows
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Save instance handle for DialogBox */
    hInst = hInstance;

    /* Insert "About..." into system menu */
    hMenu = GetSystemMenu(hWnd, FALSE);
    ChangeMenu(hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
    ChangeMenu(hMenu, 0, (LPSTR)szAbout, IDSABOUT, MF_APPEND | MF_STRING);

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}
/*
*/


/* Procedure called when the application is loaded for the first time */
BOOL Init( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pAPPClass;

    /* Load strings from resource */
    LoadString( hInstance, IDSNAME, (LPSTR)szAppName, 10 );
    LoadString( hInstance, IDSABOUT, (LPSTR)szAbout, 10 );
    MessageLength = LoadString( hInstance, IDSTITLE, (LPSTR)szMessage, 15 );

    pAPPClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pAPPClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pAPPClass->hIcon          = LoadIcon( hInstance, (LPSTR)szAppName );
    pAPPClass->lpszMenuName   = (LPSTR)szAppName;
    pAPPClass->lpszClassName  = (LPSTR)szAppName;
    pAPPClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pAPPClass->hInstance      = hInstance;
    pAPPClass->style          = CS_HREDRAW | CS_VREDRAW;
    pAPPClass->lpfnWndProc    = WndProc;

    if (!RegisterClass( (LPWNDCLASS)pAPPClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pAPPClass );
    return TRUE;        /* Initialization succeeded */
}
/*
*/


APPCMD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\HOOKS\MENUHELP\APPCMD.C

#include "windows.h"
#include "APP.h"

void APPCommand( HWND, WORD, LONG );


void APPCommand( hWnd, wParam, lParam )
HWND hWnd;
WORD wParam;
LONG lParam;
{
        MessageBox ( hWnd, (LPSTR)"Item Selected!",
                           (LPSTR)"Menu", MB_OK );
        return;
}


APPPAINT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\HOOKS\JOURNAL\APPPAINT.C

#include "windows.h"
#include "APP.h"

extern char szMessage[];
extern int MessageLength;

void APPPaint( HWND, WORD, LONG );


void APPPaint(  hWnd, wParam, lParam )
HWND hWnd;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;
    RECT rRect;

    BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
/*
    GetClientRect( hWnd, (LPRECT)&rRect );
    ScrollWindow( hWnd, 0, -rRect.bottom, (LPRECT)NULL, (LPRECT)NULL);
*/
    EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
}
/*
*/


APPPAINT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\HOOKS\MENUHELP\APPPAINT.C

#include "windows.h"
#include "APP.h"

extern char szMessage[];
extern int MessageLength;

void APPPaint( HWND, WORD, LONG );


void APPPaint(  hWnd, wParam, lParam )
HWND hWnd;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
    TextOut( ps.hdc,
             (short)10,
             (short)10,
             (LPSTR)szMessage,
             (short)MessageLength );
    EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
}
/*
*/


APPPAINT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\APPPAINT.C

#include "windows.h"
#include "APP.h"

extern char szMessage[];
extern int MessageLength;

void APPPaint( HWND, WORD, LONG );


void APPPaint(  hWnd, wParam, lParam )
HWND hWnd;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
    TextOut( ps.hdc,
             (short)10,
             (short)10,
             (LPSTR)szMessage,
             (short)MessageLength );
    EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
}
/*
*/


ARCC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\ARCC.C

/*
 *  Function Name:   Arc
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   The program below will draw an arc.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_Arc (hWnd, hDC)
HWND hWnd;
HDC hDC;
  {
  BOOL      bDrawn;
  int   xScreen, yScreen;

  xScreen = GetSystemMetrics (SM_CXSCREEN);
  yScreen = GetSystemMetrics (SM_CYSCREEN);

  bDrawn = Arc (hDC, xScreen / 3, yScreen / 3, (2 * xScreen) / 3, (2 * yScree
      (2 * xScreen) / 5, (2 * yScreen) / 5, xScreen / 2, yScreen / 2);  /* fu

  if (bDrawn != TRUE)
    MessageBeep (MB_OK);  /*  Couldn't Draw the ARC, so BEEP!!!  */

  return;
  }


/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit (hInstance)
HANDLE hInstance;
  {
  WNDCLASS   wcClass;

  wcClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcClass.lpfnWndProc    = WndProc;
  wcClass.cbClsExtra     = 0;
  wcClass.cbWndExtra     = 0;
  wcClass.hInstance      = hInstance;
  wcClass.hIcon          = LoadIcon (hInstance, NULL);
  wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
  wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  wcClass.lpszMenuName   = (LPSTR)NULL;
  wcClass.lpszClassName  = (LPSTR)"Arc";

  if (!RegisterClass ( (LPWNDCLASS) & wcClass))
    return FALSE;

  return TRUE;
  }


int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  if (!hPrevInstance)
    if (!WinInit (hInstance))
      return FALSE;

  hWnd = CreateWindow ( (LPSTR)"Arc", (LPSTR)"Arc ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0,
                      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      CALL_Arc (hWnd, ps.hdc);
      ValidateRect (hWnd, (LPRECT) NULL);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


ATOM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\ATOM.C

/*  Atom.c
 *
 * This program is designed to be used in conjunction with atom2. These
 * two programs will demonstrate the use of atoms. Atoms are integers
 * that uniquely identify character strings. Atoms are stored in tables.
 * These two programs will share certain global atom tables.
 *
 */
#include "windows.h"
#include "stdio.h"
#include "process.h"

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
       int     IDForAtom;
     int    IDForAtom2;
     int    ActualAtomSize;
     int    AtomMaxSize = 20;
     int     MB_Return;
       HANDLE  hToAtom;
       BOOL     bTableAdded;
       char    szTempBuff[80];
     char    szMainBuff[80];

   bTableAdded = InitAtomTable(101);
      /* Only neccessary if you want more than 37 entries in your atom
       * table. NOTE: 101 is the number of possible entries and should
       * be PRIME
       */

  /* Deal with local atoms  */
  IDForAtom = AddAtom((LPSTR)"This is an Example String");

  IDForAtom = FindAtom((LPSTR)"This is an Example String");
  ActualAtomSize = GetAtomName(IDForAtom, (LPSTR)szTempBuff, AtomMaxSize);
  hToAtom = GetAtomHandle(IDForAtom);

  IDForAtom = DeleteAtom(IDForAtom);

  /* Deal with global atoms  */
  IDForAtom2 = GlobalAddAtom((LPSTR)"This is another");

  sprintf ( szMainBuff, "%s%s%d%s%d", szTempBuff,"ID is : ",IDForAtom,
    "\nID2 is : ", IDForAtom2);
  MB_Return = MessageBox(NULL, (LPSTR)szMainBuff, (LPSTR)"Atom Example", MB_O
  MB_Return = MessageBox(NULL, (LPSTR)"Continue test by Running Atom2", (LPST
}


ATOM2.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\ATOM2.C

/*  Atom2.c
 *
 * This program is designed to be used in conjunction with atom. These
 * two programs will demonstrate the use of atoms. Atoms are integers
 * that uniquely identify character strings. Atoms are stored in tables.
 * These two programs will share certain global atom tables.
 *
 * NOTE: Run atom first.
 *
 */
#include "windows.h"

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  int    IDForAtom;
  int    ActualAtomSize;
  int    AtomMaxSize = 20;
  int    MB_Return;
  HANDLE  hToAtom;
  BOOL    bTableAdded;
  char    szMainBuff[80];
  char    szbuff[20];

  IDForAtom = GlobalFindAtom((LPSTR)"This is another");
  ActualAtomSize = GlobalGetAtomName(IDForAtom, (LPSTR)szbuff, AtomMaxSize);

  sprintf ( szMainBuff, "%s%s%s%d","string retrieved: ",szbuff," ID is : ",ID
  MB_Return = MessageBox(NULL, (LPSTR)szMainBuff, (LPSTR)"Atom2 Example", MB_
  IDForAtom = GlobalDeleteAtom(IDForAtom);
}


ATOMICS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\ATOMICS.C

/*
 * Function (s) demonstrated in this program: AddAtom ()
 *                                           GlobalAddAtom ()
 *                                           FindAtom ()
 *                                           GlobalFindAtom ()
 *                                           GetAtomName ()
 *                                           GlobalGetAtomName ()
 *                                           GetAtomHandle ()
 *                                           DeleteAtom ()
 *                                           GlobalDeleteAtom ()
 * Compiler version: MSC v5.10
 * Description: This program demonstrates the various atom functions availabl
 *              in the Windows 2.03 Software Development Kit.
 */

#include <windows.h>
#include "process.h"
#include "atomics.h"

long  FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int  nCmdShow;
{
  static char  szAppName [] = "SampleWindow";
  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG msg;
  HMENU hMenu;

  if (!hPrevInstance)
  {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass (&wndclass))
      return FALSE;
  }

  hMenu = LoadMenu (hInstance, "MainMenu");
  hWnd = CreateWindow (szAppName, "The wonders of atoms", WS_OVERLAPPEDWINDOW
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
      NULL, hMenu, hInstance, NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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


long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned  iMessage;
WORD     wParam;
LONG     lParam;
{
  int  IDForAtom, IDForAtom2, ActualAtomSize, AtomMaxSize = 20, MB_Return;
  HANDLE   hToAtom;
  BOOL     bTableAdded;
  char  szbuff[20];

  switch (iMessage)
  {
  case WM_COMMAND:
    switch (wParam)
    {
    case IDM_EXECUTE:
      bTableAdded = InitAtomTable (101);
/* Only neccessary if you want more
                 than 37 entries in your atom table
                 note: 101 is the number of possible
                 entries and should be PRIME */

      IDForAtom = AddAtom ( (LPSTR)"String");
/* Add the string "String" to the atom table */

      IDForAtom2 = GlobalAddAtom ( (LPSTR)"String2");
/* Add the string "String2" to the Atom table,
                 making it accessible to other applications. */

      IDForAtom = FindAtom ( (LPSTR)"String");
/* Search through the atom table and return the atom
                  corresponding to the character string pointed
                  to by (LPSTR)"String". */
      ActualAtomSize = GetAtomName (IDForAtom, (LPSTR)szbuff, AtomMaxSize);
/* Retrieve a copy of the char string that corresponds to the
                  atom specified by IDForAtom  */
      hToAtom = GetAtomHandle (IDForAtom);
      IDForAtom = DeleteAtom (IDForAtom);
      MB_Return = MessageBox (NULL, (LPSTR)szbuff,
          (LPSTR)"Atom Example", MB_OK);
      IDForAtom = GlobalFindAtom ( (LPSTR)"String2");
      ActualAtomSize = GlobalGetAtomName (IDForAtom, (LPSTR)szbuff,
          AtomMaxSize);
      MB_Return = MessageBox (NULL, (LPSTR)szbuff,
          (LPSTR)"Global Atom Example", MB_OK);
      IDForAtom2 = GlobalDeleteAtom (IDForAtom2);
    }
    break;

  case WM_DESTROY:
    PostQuitMessage (0);
    break;

  default:
    return DefWindowProc (hWnd, iMessage, wParam, lParam);
  }
  return (0L);
}




BGNPAINT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\BGNPAINT.C

/*
 *
 *   bgnpaint.c, jeffst, v1.00, 6-Dec-1987
 *
 *   This program demonstrates the use of the BeginPaint() function.
 *   BeginPaint() prepares the given window for painting and fills the paint
 *   structure with information about the painting. BeginPaint() sets the
 *   clipping region to exclude any area outside the update region. This
 *   is demonstrated in this program by a call to ValidateRect() immediately
 *   before the BeginPaint() call. BeginPaint() is called in response to a
 *   WM_PAINT message in HelloWndProc. This is standard for most window
 *   procedures in Windows applications.
 *
 *   Microsoft Product Support Services
 *   Windows Version 2.0 function demonstration application
 *   Copyright (c) Microsoft 1987
 *
 */

#include "windows.h"

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"BeginPaint";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"BeginPaint",
      (LPSTR)"BeginPaint()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;  /* paint structure filled by BeginPaint() */
    RECT rExcludeRect;  /* area to validate */
    switch (message)
    {
    case WM_SYSCOMMAND:
            return DefWindowProc( hWnd, message, wParam, lParam );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
  rExcludeRect.top    = 0;
  rExcludeRect.left   = 50;
  rExcludeRect.bottom = 100;
  rExcludeRect.right  = 80;
   /* remove the area described by rExcludeRect from update region */
  ValidateRect(hWnd,(LPRECT)&rExcludeRect);

   /****  prepare window for painting       ****/
  BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
  TextOut(ps.hdc,
    5,
    5,
    (LPSTR)"This line of text messed up by ValidateRect()",
    45);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


BIFF.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\BIFF\BIFF.C

/*  biff.c
    biff Application
    Windows Toolkit Version 2.10
    Copyright (c) Microsoft 1989 */

/*  This IS the old HELLO application with
    just one piece of code added to bring
    up a dialog box when a key is pressed.
    See bigg.c for more information.
 */

#include "windows.h"
#include "biff.h"

char szAppName[10];
char szAbout[10];
char szMessage[20];
int MessageLength;

HWND    hWnd;
HANDLE  hInst;
FARPROC lpprocAbout;

extern  void FAR GetBiff(HWND, HANDLE);

long FAR PASCAL BiffWndProc(HWND, WORD, WORD, LONG);
BOOL FAR PASCAL BiffDlgProc(HWND, WORD, WORD, LONG);

BOOL FAR PASCAL About( HWND hDlg, WORD wMessage, WORD wParam, LONG lParam )
{
    switch (wMessage) {
        case WM_INITDIALOG:
            break;
        case WM_COMMAND:
            EndDialog(hDlg, TRUE);
            break;
        default:
            return FALSE;
            break;
        }
    return(TRUE);
}


void BiffPaint( hDC )
HDC hDC;
{
    TextOut( hDC, 10, 10,
             (LPSTR)"Press any key to bring up dialog.", 33 );
}


/* Procedure called when the application is loaded for the first time */
BOOL BiffInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pbiffClass;

    /* Load strings from resource */
    LoadString( hInstance, IDSNAME, (LPSTR)szAppName, 10 );
    LoadString( hInstance, IDSABOUT, (LPSTR)szAbout, 10 );
    MessageLength = LoadString( hInstance, IDSTITLE, (LPSTR)szMessage, 15 );

    pbiffClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pbiffClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pbiffClass->hIcon          = LoadIcon( hInstance, MAKEINTRESOURCE(BIFFICO
    pbiffClass->lpszMenuName   = (LPSTR)NULL;
    pbiffClass->lpszClassName  = (LPSTR)szAppName;
    pbiffClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pbiffClass->hInstance      = hInstance;
    pbiffClass->style          = CS_HREDRAW | CS_VREDRAW;
    pbiffClass->lpfnWndProc    = BiffWndProc;

    if (!RegisterClass( (LPWNDCLASS)pbiffClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pbiffClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HMENU hMenu;

    if (!hPrevInstance) {
        /* Call initialization procedure if this is the first instance */
        if (!BiffInit( hInstance ))
            return FALSE;
        }
    else {
        /* Copy data from previous instance */
        GetInstanceData( hPrevInstance, (PSTR)szAppName, 10 );
        GetInstanceData( hPrevInstance, (PSTR)szAbout, 10 );
        GetInstanceData( hPrevInstance, (PSTR)szMessage, 15 );
        GetInstanceData( hPrevInstance, (PSTR)&MessageLength, sizeof(int) );
        }

    hWnd = CreateWindow((LPSTR)szAppName,
                        (LPSTR)szMessage,
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Save instance handle for DialogBox */
    hInst = hInstance;

    /* Insert "About..." into system menu */
    hMenu = GetSystemMenu(hWnd, FALSE);
    ChangeMenu(hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
    ChangeMenu(hMenu, 0, (LPSTR)szAbout, IDSABOUT, MF_APPEND | MF_STRING);

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL BiffWndProc( HWND hWnd, WORD wMessage, WORD wParam, LONG lPar
{
    PAINTSTRUCT ps;

    switch (wMessage)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        case IDSABOUT:
            lpprocAbout = MakeProcInstance( (FARPROC)About, hInst );
            DialogBox( hInst, MAKEINTRESOURCE(ABOUTBOX), hWnd, lpprocAbout );
            FreeProcInstance(lpprocAbout);
            break;
        default:
            return DefWindowProc( hWnd, wMessage, wParam, lParam );
        }
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_RBUTTONDOWN:
    case WM_CHAR:

        GetBiff(hWnd, hInst);
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        BiffPaint( ps.hdc );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, wMessage, wParam, lParam );
        break;
    }
    return(0L);
}


BIGG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\BIFF\BIGG.C

/*
   This module was designed to work as a standalone
   program.  What it does is promts you for BIFF
   record information and then builds a biff buffer
   that is copied to the Clipboard and also creates
   a BIFF.XLS file.
*/

#include "windows.h"
 "winexp.h"  /* needed for file i/o functions */
 "stdlib.h"  /* needed for atof function */
#include "bigg.h"

#define BUFLENGTH  100

extern  HWND  hWnd;

int     iRow;               /*         INT value from edit control */
int     iColumn;            /*         INT value from edit control */
WORD    wInt;               /* BOOL or INT value from edit control */
int     iTextLength;        /*    length of text from edit control */
char    szText[40];         /*              text from edit control */
char    cBuffer[BUFLENGTH];
int     iLastButton;
int     iRadioButton;
int     PlaceBiffOnClipboard( HANDLE );
int     iLength;
LPSTR   lpData, lpDataInit;
FARPROC lpprocBiffDlgProc;

struct BIFFINTEGER FAR *lpBiffInt;
struct BIFFNUMBER  FAR *lpBiffNumber;
struct BIFFSTRING  FAR *lpBiffString;
struct BIFFFORMULA FAR *lpBiffFormula;

/* ------ formal declarations -------- */

BOOL FAR PASCAL BiffDlgProc( HWND, WORD, WORD, LONG );
HANDLE FillBiffBuffer( void );
void   CreateBiffBOF(void);
void   CreateBiffDIM( int, int, int, int );
void   SaveBiffData(  int, int, int);
void   CloseBiff(void);
int    DumpStuff(void);
void   lstrncpy(LPSTR, LPSTR, int);

/* -----------------------------------------
     Entry point of this module.
 ------------------------------------------- */
void FAR GetBiff(HWND hWnd, HANDLE hInst)
{
   lpprocBiffDlgProc = MakeProcInstance( (FARPROC)BiffDlgProc, hInst );
   DialogBox( hInst, MAKEINTRESOURCE(BIFFDLG), hWnd, lpprocBiffDlgProc );
   FreeProcInstance(lpprocBiffDlgProc);
}

/* -----------------------------------------
     Process Biff dialog box.
 ------------------------------------------- */
BOOL FAR PASCAL BiffDlgProc( HWND hDlg, WORD wMessage, WORD wParam, LONG lPar
{
   BOOL bResult;  /* Translated flag */

   switch (wMessage) {

   case WM_INITDIALOG:

       SetDlgItemText(hDlg, IDTEXT, (LPSTR)szText);

       CheckRadioButton(hDlg, IDBOOL, IDFORMULA, iLastButton);
           iRadioButton = iLastButton;

       /* formula is not implemented so it is disabled */
       EnableWindow( GetDlgItem(hDlg,IDFORMULA), FALSE );

       break;

   case WM_COMMAND:

       switch (wParam) {

       case IDOK:

           iRow = GetDlgItemInt(hDlg, IDROW , (BOOL FAR *)&bResult, FALSE);
           if (bResult == FALSE) /* display an error. */
               MessageBox( hDlg,
                           (LPSTR)"Non-numeric character or exceeded max!",
                           (LPSTR)"Row Error!", MB_OK );
           if(iRow) iRow--;  // make ZERO based

           iColumn = GetDlgItemInt(hDlg, IDCOLUMN, (BOOL FAR *)&bResult, FALS
           if (bResult == FALSE) /* display an error. */
               MessageBox( hDlg,
                           (LPSTR)"Non-numeric character or exceeded max!",
                           (LPSTR)"Column Error!", MB_OK );

           if(iColumn)  iColumn--; // make ZERO based

           iLastButton = iRadioButton;
           switch (iRadioButton) {
              case IDBOOL:
                   wInt = GetDlgItemInt(hDlg, IDTEXT, (BOOL FAR *)&bResult, F
                   if (bResult == FALSE) /* display an error. */
                       MessageBox( hDlg,
                              (LPSTR)"Something is wrong with BOOL value!",
                              (LPSTR)"BOOL Error!", MB_OK );
                   break;

              case IDINT:
                   wInt = GetDlgItemInt(hDlg, IDTEXT, (BOOL FAR *)&bResult, F
                   if (bResult == FALSE) /* display an error. */
                   MessageBox( hDlg,
                              (LPSTR)"Must be 0 - 65535!",
                              (LPSTR)"Integer Error!", MB_OK );
                   break;

              case IDBLANK:
              case IDLABEL:
              case IDNUMBER:
              case IDFORMULA:

                   break;

              default:
                     MessageBox( hDlg,"Wrong data type", NULL, MB_OK);
           }
           iTextLength = GetDlgItemText(hDlg, IDTEXT, (LPSTR)szText, 40);
           szText[iTextLength+1] = '\0';

           PlaceBiffOnClipboard( FillBiffBuffer() );

           EndDialog(hDlg, TRUE);
           return(TRUE);

       case IDCANCEL:
               EndDialog(hDlg, FALSE);
               return(TRUE);

       case IDBLANK:
       case IDLABEL:
       case IDBOOL:
       case IDINT:
       case IDNUMBER:
       case IDFORMULA:
               CheckRadioButton(hDlg, IDBLANK, IDFORMULA,
                  (iRadioButton = wParam));
               return(TRUE);
               break;
       }
   default:
           return(FALSE);
   }
   return(TRUE);
}


/* ----------------------------------------------------------
   Place the biff buffer to the clipboard in BIFF format
 ------------------------------------------------------------ */
int  PlaceBiffOnClipboard(HANDLE hBiffBuffer)
{
  WORD     wCBFormat;
  int      iResult;
  unsigned long  ulLength;

  if (hBiffBuffer == 0)
    return FALSE;

  ulLength = (unsigned long)iLength;
  hBiffBuffer = GlobalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT, ulLength );
  if (!hBiffBuffer) {
     MessageBox(GetFocus(), "Not enough memory.", NULL, MB_OK);
     return FALSE;
  }
  if ( lpData = GlobalLock(hBiffBuffer) ) {
    lstrncpy( lpData ,lpDataInit, iLength );
  }
  GlobalUnlock(hBiffBuffer);

  if ( OpenClipboard(hWnd) == 0) {
    MessageBox( GetFocus(), (LPSTR)"Opening clipboard", NULL, MB_OK);
    return FALSE;
  }
  EmptyClipboard();
  wCBFormat = RegisterClipboardFormat ( (LPSTR)"Biff" );
  iResult   = SetClipboardData(wCBFormat,hBiffBuffer);
  CloseClipboard();
  return TRUE;

}

/* ----------------------
   Fill the Biff buffer
 ------------------------ */
HANDLE FillBiffBuffer()
{

  lpDataInit = lpData = cBuffer;  /* set starting address to fill */
  CreateBiffBOF();
  CreateBiffDIM(iRow, iRow, iColumn, iColumn);
  SaveBiffData(iRadioButton, iRow, iColumn);
  CloseBiff();

  DumpStuff();
  return TRUE;

}


/* --------------------------------------------------
   Creates a BOF record,
 ---------------------------------------------------- */
void CreateBiffBOF()
{

   *lpData++ = 0x9 ; *lpData++ = 0x0 ; // rec type
   *lpData++ = 0x4 ; *lpData++ = 0x0 ; // rec length

   *lpData++ = 0x2 ; *lpData++ = 0x0 ; // version #
   *lpData++ = 0x10; *lpData++ = 0x0 ; // 10 = XLS, 20 = XLC, 40 = XLM

}

/* -----------------------------------------------------------
   Creates a Dimension record,
   Currently, this dialog does not:
      1] ask for more than ONE cell.
      2] limits range to two characters.
 ------------------------------------------------------------- */
void CreateBiffDIM(int iFirstRow, int iLastRow, int iFirstCol, int iLastCol)
{

   *lpData++ = 0x0;  *lpData++ = 0x0; // rec type
   *lpData++ = 0x8;  *lpData++ = 0x0; // rec length

   *lpData++ = LOBYTE(iFirstRow);  *lpData++ = 0x0; // HIBYTE(iFirstRow);
   *lpData++ = LOBYTE(iLastRow+1); *lpData++ = 0x0; // HIBYTE(iLastRow+1);
   *lpData++ = LOBYTE(iFirstCol);  *lpData++ = 0x0; // HIBYTE(iFirstCol);
   *lpData++ = LOBYTE(iLastCol+1); *lpData++ = 0x0; // HIBYTE(iLastCol+1);

}

/* --------------------------------------------------
   Creates a Data record,
 ---------------------------------------------------- */
void SaveBiffData(int iType, int iRow, int iCol)
{

  switch (iType) {

   case IDBLANK:   /* make a blank record */

         *lpData++ = 0x1;  *lpData++ = 0x0;// rec type
         *lpData++ = 0x7;  *lpData++ = 0x0;// rec length

         *lpData++ = LOBYTE(iRow); *lpData++ = 0x0; // HIBYTE(iRow); // row
         *lpData++ = LOBYTE(iCol); *lpData++ = 0x0; // HIBYTE(iCol); // col

         *lpData++ = 0x0;  // rec attribute
         *lpData++ = 0x0;
         *lpData++ = 0x0;

         break;


   case IDBOOL:    /* make a boolean record */

         *lpData++ = 0x5;  *lpData++ = 0x0;// rec type
         *lpData++ = 0x9;  *lpData++ = 0x0;// rec length

         *lpData++ = LOBYTE(iRow); *lpData++ = 0x0; // HIBYTE(iRow); // row
         *lpData++ = LOBYTE(iCol); *lpData++ = 0x0; // HIBYTE(iCol); // col

         *lpData++ = 0x0;  // rec attribute
         *lpData++ = 0x0;
         *lpData++ = 0x0;
         *lpData++ = (BYTE)(wInt?0x1:0x0); // data
         *lpData++ = 0x0;

         break;

   case IDINT:     /* make an integer record */
         lpBiffInt = lpData;

         lpBiffInt->wRecType   = 2;
         lpBiffInt->wRecLength = 9;
         lpBiffInt->wRow       = iRow;
         lpBiffInt->wColumn    = iCol;
         lpBiffInt->cAttrib[0] = 0;
         lpBiffInt->cAttrib[1] = 0;
         lpBiffInt->cAttrib[2] = 0;
         lpBiffInt->wInteger   = wInt;

         lpData = lpData + lpBiffInt->wRecLength + 4;

         break;

   case IDNUMBER:  /* make a number record */

         lpBiffNumber = lpData;

         lpBiffNumber->wRecType   =  3;
         lpBiffNumber->wRecLength = 15;
         lpBiffNumber->wRow       = iRow;
         lpBiffNumber->wColumn    = iCol;
         lpBiffNumber->cAttrib[0] = 0;
         lpBiffNumber->cAttrib[1] = 0;
         lpBiffNumber->cAttrib[2] = 0;
         lpBiffNumber->dNumber    = atof((PSTR)szText);

         lpData = lpData + lpBiffNumber->wRecLength + 4;

         break;

   case IDLABEL:   /* make a label (text) record */

         lpBiffString = lpData;

         lpBiffString->wRecType    = 4;
         lpBiffString->wRecLength  = iTextLength+1 + 8;
         lpBiffString->wRow        = iRow;
         lpBiffString->wColumn     = iCol;
         lpBiffString->cAttrib[0]  = 0;
         lpBiffString->cAttrib[1]  = 0;
         lpBiffString->cAttrib[2]  = 0;
         lpBiffString->bTextLength = (BYTE)LOWORD(iTextLength);
         lstrncpy( lpBiffString->cLabel, szText, iTextLength+1 );

         lpData = lpData + lpBiffString->wRecLength + 4 ;

         break;

   case IDFORMULA:  /* make a formula record */ // put here for future use

         lpBiffFormula = lpData;

         lpBiffFormula->wRecType     = 32;
         lpBiffFormula->wRecLength   = iTextLength+1 + 8;
         lpBiffFormula->wRow         = iRow;
         lpBiffFormula->wColumn      = iCol;
         lpBiffFormula->cAttrib[0]   = 0x0;
         lpBiffFormula->cCurValue[0] = 0x0;
         lpBiffFormula->bRecalc      = 0;
         lpBiffFormula->bTextLength  = (BYTE)LOWORD(iTextLength);
         lstrncpy( lpBiffFormula->cLabel, szText, iTextLength+1 );

         lpData = lpData + lpBiffFormula->wRecLength + 4 ;

         break;

   } /* end switch */

}

/* ---------------------
   Create an EOF record.
 ----------------------- */
void CloseBiff()
{
   *lpData++ = 0xa;  // rec type
   *lpData++ = 0x0;
   *lpData++ = 0x0;
   *lpData++ = 0x0;

}


/* --------------------------------------------------
   Dump buffer to a file.
 ---------------------------------------------------- */
int DumpStuff()
{
   OFSTRUCT OFFile;
   int      iFile;

   iFile = OpenFile((LPSTR)"dump.xls",
                    (LPOFSTRUCT)&OFFile,OF_CREATE|OF_WRITE);
   if (iFile == -1) {
     MessageBox (GetFocus(),(LPSTR)"OpenFile failed.", NULL, MB_OK);
     return(FALSE);
   }
   iLength = lpData-lpDataInit;
   if (_lwrite(iFile, lpDataInit, iLength) != iLength ) {
     MessageBox (GetFocus(),(LPSTR)"write",(LPSTR)"failed",MB_OK);
   }
   _lclose(iFile);

}

/* ---------------------
   Copy number of bytes.
 ----------------------- */

void lstrncpy(LPSTR lpDest, LPSTR lpSrc, int n)
{
    while (n--)
      *lpDest++ = *lpSrc++;
}



BIT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\BIT.C

/*
 *
 * Functions: hDC CreateDC(lpString, lpString, lpString, lpString)
 *        hDC CreateCompatibleDC(hDC)
 *    HBITMAP LoadBitmap(hInstance, lpString)
 *    hObject SelectObject(hDC, hObject)
 *       BOOL StretchBlt(hDC,X,Y,nWidth,nHeight,hDC,
 *           XSrc,YSrc,XSrcWidth,YSrcHeight,dwROP)
 *       BOOL BitBlt(hDC,X,Y,nWidth,nHeight,hDC,XSrc,YSrc,dwROP)
 *       BOOL DeleteDC(hDC)
 *       BOOL DeleteObject(hObject)
 */
#include "windows.h"
#include "stdio.h"

int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
{
  HDC     oneDC, screenDC;
  HBITMAP hWorld;
  int  Index;
  char  LoadBitmapString [40];

  screenDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  oneDC = CreateCompatibleDC(screenDC);
  Index = 1;
  sprintf (LoadBitmapString, "WORLD%i", Index);
  hWorld = LoadBitmap(hInstance, LoadBitmapString);
  SelectObject(oneDC, hWorld);
  StretchBlt(screenDC, 250, 140, 99, 99, oneDC, 0, 0, 99, 99, SRCCOPY);
/*
    StretchBlt(screenDC, 150, 75, 51, 100, oneDC, 0, 0, 51, 31, SRCCOPY);
    BitBlt(screenDC, 75, 75, 52, 32, oneDC, 0, 0, SRCCOPY);
*/
  DeleteDC(oneDC);
  DeleteDC(screenDC);
  DeleteObject(hWorld);
  return 0;
}




BUILDDCB.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\BUILDDCB.C

/*
 *
 * Function(s) demonstrated in this program: BuildCommDCB
 *
 * Windows version:  2.03
 *
 * Windows SDK version:  2.00
 *
 * Compiler version:  C 5.10
 *
 * Description:  This function translates the definition string specified
 *    by the parameter into appropriate device-control block codes and places
 *   these codes in the device control block specified by the other parmeter.
 *
 * Additional Comments:
 *
 */

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "BuildDCB.h"


HWND     hWndParent1;
HANDLE   hInstMain;

char  szOutputBuffer1 [70];
char  szOutputBuffer2 [500];
char  szMode          [40] = "COM1:9600,N,8,1";


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct {
  char  *szMessage;
} Messages [] = {
  "About\0",
  "     This is a sample application to demonstrate the\n\
use of the BuildCommDCB Windows function.",

  "Help Message",
  "     This program uses the BuildCommDCB Windows\n\
function to build a device control block from the\n\
given string.  Use the menu to invoke this function.",

};


/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
HWND     hWnd;
int  MessageNumber;
{
  sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
  sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
  MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}


/****************************************************************************

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance ;
LPSTR       lpszCmdLine ;
int  nCmdShow ;
{
  static char  szAppName [] = "BuildDCB" ;
  HWND        hWnd ;
  WNDCLASS    wndclass ;
  MSG msg;
  short  xScreen, yScreen ;

  if (!hPrevInstance)
  {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
    wndclass.lpfnWndProc   = WndProc ;
    wndclass.cbClsExtra    = 0 ;
    wndclass.cbWndExtra    = 0 ;
    wndclass.hInstance     = hInstance ;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName  = szAppName ;
    wndclass.lpszClassName = szAppName ;

    if (!RegisterClass (&wndclass))
      return FALSE ;
  }

  xScreen = GetSystemMetrics (SM_CXSCREEN) ;
  yScreen = GetSystemMetrics (SM_CYSCREEN) ;

hWndParent1 = CreateWindow (szAppName,     /* window class name       */
"BuildCommDCB",             /* window caption          */
WS_OVERLAPPEDWINDOW,        /* window style            */
CW_USEDEFAULT,              /* initial x position      */
0,                          /* initial y position      */
CW_USEDEFAULT,              /* initial x size          */
0,                          /* initial y size          */
NULL,                       /* parent window handle    */
NULL,                       /* window menu handle      */
hInstance,                  /* program instance handle */
  NULL) ;                     /* create parameters       */

  ShowWindow (hWndParent1, nCmdShow) ;
  UpdateWindow (hWndParent1) ;

  hInstMain = hInstance;

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


/****************************************************************************

long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned  iMessage ;
WORD     wParam ;
LONG     lParam ;
{
  HMENU       hMenu;
  HDC         hDC;
  DCB         CommDCB;
  int  ComVal;
  PAINTSTRUCT ps;

  switch (iMessage)
  {
  case WM_CREATE:
    hMenu = GetSystemMenu (hWnd, FALSE);

    ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
        MF_APPEND | MF_STRING);
    break;

  case WM_SYSCOMMAND:
    switch (wParam)
    {
    case IDM_ABOUT:
      ProcessMessage (hWnd, 0);
      break;
    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
    }
    break;

  case WM_COMMAND:
    switch (wParam)
    {
    case IDM_BUILDDCB:
      sprintf(szOutputBuffer1, "Definition string = COM1:9600,N,8,1");
      MessageBox (hWnd, szOutputBuffer1, "BuildCommDCB", MB_OK);
      ComVal = BuildCommDCB ((LPSTR)szMode, (DCB FAR * ) & CommDCB);
      sprintf (szOutputBuffer2, "%s%s%s%i",
          "     If the return value is 0 then the BuildCommDCB ",
          "function was performed correctly.\n\n",
          "               The return value = ", ComVal);
      MessageBox (hWnd, szOutputBuffer2, "BuildCommDCB", MB_OK);
      break;

    case IDM_HELP:
      ProcessMessage (hWnd, 2);
      break;
    }
    break;

  case WM_PAINT:
    BeginPaint(hWnd, (LPPAINTSTRUCT) & ps);
    EndPaint(hWnd, (LPPAINTSTRUCT) & ps);
    break;

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
  return (0L);
}





BWINTTOP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\BWINTTOP.C

/*
 *  This program demonstrates the use of the function BringWindowToTop.
 *  It brings a popup style or child style window to the top of a stack
 *  of overlapping windows.
 */

#include "windows.h"

/* Registering the parent and child window classes */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
  WNDCLASS   wcParentClass, wcChildClass;

/* registering the parent window class */
  wcParentClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
  wcParentClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
  wcParentClass.lpszMenuName   = (LPSTR)NULL;
  wcParentClass.lpszClassName  = (LPSTR)"Parent";
  wcParentClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  wcParentClass.hInstance      = hInstance;
  wcParentClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcParentClass.lpfnWndProc    = DefWindowProc;
  wcParentClass.cbClsExtra     = 0;
  wcParentClass.cbWndExtra     = 0;

  RegisterClass( (LPWNDCLASS) & wcParentClass );

/* registering the child window class */
  wcChildClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
  wcChildClass.hIcon          = (HICON)NULL;
  wcChildClass.lpszMenuName   = (LPSTR)NULL;
  wcChildClass.lpszClassName  = (LPSTR)"Child";
  wcChildClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  wcChildClass.hInstance      = hInstance;
  wcChildClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcChildClass.lpfnWndProc    = DefWindowProc;
  wcChildClass.cbClsExtra     = 0;
  wcChildClass.cbWndExtra     = 0;

  RegisterClass( (LPWNDCLASS) & wcChildClass );
  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  HWND  hParent, hChild1, hChild2;     /* Handles to the windows */

  WinInit (hInstance);

/* creating the parent window */
  hParent = CreateWindow((LPSTR)"Parent",
      (LPSTR)"Parent Window",
      WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
    50,                /* x         */
50,                /* y         */
600,               /* width     */
250,               /* height    */
  (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
  );

/* Make window visible according to the way the app is activated */
  ShowWindow( hParent, cmdShow );
  UpdateWindow( hParent );

/* creating the child windows */
  hChild1 = CreateWindow ((LPSTR) "Child",
      (LPSTR) "Child #1",
      WS_CHILD | WS_CLIPSIBLINGS | WS_CAPTION | WS_VISIBLE,
    50,                 /* x         */
50,                 /* y         */
100,                /* width     */
50,                 /* height    */
  (HWND) hParent,     /* parent of this window   */
  (HMENU) 1,          /* child window identifier */
  (HANDLE) hInstance, /* handle to window instance */
  (LPSTR) NULL);      /* no params to pass on    */

  hChild2 = CreateWindow ((LPSTR) "Child",
      (LPSTR) "Child #2",
      WS_CHILD | WS_CLIPSIBLINGS | WS_CAPTION | WS_VISIBLE,
    60,                 /* x          */
60,                 /* y          */
100,                /* width      */
50,                 /* height     */
  (HWND) hParent,     /* parent of this window   */
  (HMENU) 2,          /* child window identifier */
  (HANDLE) hInstance, /* handle to window instance */
  (LPSTR) NULL);      /* no params to pass on    */


/* Bring the bottom window to the top */
  MessageBox (hParent, (LPSTR)"Before bringing the bottom window up",
      (LPSTR)"Ready ?", MB_OK);

  BringWindowToTop (hChild2);

  MessageBox (hParent, (LPSTR)"Child #2 has been brought up!",
      (LPSTR)"Done", MB_OK);

  return 0;
}




CALLMSGF.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\CALLMSGF.C

/*
 *
 * Function (s) demonstrated in this program: CallMsgFilter, SetWindowsHook,
 *    UnhookWindowsHook
 * Compiler version:  C 5.10
 * Description:  This function calls the Message Filter with the given messag
 *    The message filter is inserted in the Message Filter chain by use of
 *    the SetWindowsHook, and removed using the UnhookWindowsHook.
 *
 */

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "CallMsgF.h"

extern HWND   hWndMain;

HWND     hWndMain;
HANDLE   hInstMain;

char  szOutputBuffer1 [70];
char  szOutputBuffer2 [500];

/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct   {
  char  *szMessage;
  } Messages [] =   {
"About",
"     This is a sample  application to  demonstrate\n\
the use of the CallMsgFilter, SetWindowsHook, and\n\
UnhookWindowsHook Windows functions.",

"Help Message",
"     This program uses the CallMsgFilter Windows\n\
function to send a special message to the main\n\
window.  To test this function use the menu to\n\
select the option to invoke the function.",

"CallMsgFilter",
"     This message was passed to the main window\n\
by the message filter."

};


/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
HWND     hWnd;
int  MessageNumber;
  {
  sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
  sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
  MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
  }


/****************************************************************************

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int  nCmdShow;
  {
  static char  szAppName [] = "CallMsgF";
  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG msg;
  short xScreen, yScreen;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = szAppName;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

    xScreen = GetSystemMetrics (SM_CXSCREEN);
    yScreen = GetSystemMetrics (SM_CYSCREEN);

    hWndMain = CreateWindow (szAppName,       /* window class name       */
               "CallMsgFilter",               /* window caption          */
                WS_OVERLAPPEDWINDOW,          /* window style            */
                CW_USEDEFAULT,                /* initial x position      */
                0,                            /* initial y position      */
                CW_USEDEFAULT,                /* initial x size          */
                0,                            /* initial y size          */
                NULL,                         /* parent window handle    */
                NULL,                         /* window menu handle      */
                hInstance,                    /* program instance handle */
                NULL);                        /* create parameters       */

    ShowWindow (hWndMain, nCmdShow);
    UpdateWindow (hWndMain);

    hInstMain = hInstance;

    InitHook (hInstMain);

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

    KillHook ();

    return (msg.wParam);
}


/****************************************************************************

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned  iMessage;
WORD     wParam;
LONG     lParam;
  {
  HMENU       hMenu;
  MSG         msg;

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = GetSystemMenu (hWnd, FALSE);
      ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT, MF_APPEND | MF_STRING);
      break;

    case WM_SYSCOMMAND:
      switch (wParam)
        {
        case IDM_ABOUT:
          ProcessMessage (hWnd, 0);
          break;
        default:
          return DefWindowProc (hWnd, iMessage, wParam, lParam);
        }
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_CALLMSGFILTER:
          MessageBox (hWnd, "Calling the Message Filter.",
                      "CallMsgFilter", MB_OK);
          msg.hwnd    = hWnd;
          msg.message = WM_COMMAND;
          msg.wParam  = IDM_FILTERMSG;
          msg.lParam  = 0L;

          CallMsgFilter (&msg, HC_ACTION);
          break;

        case IDM_FROMMSGFILTER:
          ProcessMessage (hWnd, 4);
          break;

        case IDM_HELP:
          ProcessMessage (hWnd, 2);
          break;
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


CALLMSGH.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\CALLMSGH.C

#include <windows.h>
#include "callmsgh.h"

HANDLE   hTASK;
FARPROC  lpfnMessageFilterHook;
FARPROC  lpfnOldMessageFilterHook;
HWND     hWnd;

/****************************************************************************
void FAR PASCAL InitHook (hTask)
HANDLE hTask;
  {
  hTASK = hTask;
  lpfnMessageFilterHook = MakeProcInstance ( (FARPROC)CallMsgMessageFilter,
      LIBINST);
  lpfnOldMessageFilterHook = SetWindowsHook (WH_MSGFILTER,
      lpfnMessageFilterHook);
  }


/****************************************************************************

BOOL FAR PASCAL KillHook ()
  {
  BOOL  fSuccess;

  fSuccess = UnhookWindowsHook (WH_MSGFILTER, lpfnMessageFilterHook);
  if (fSuccess)
    {
    FreeProcInstance (lpfnMessageFilterHook);
    MessageBox (GetFocus (), "Message filter Unhooked.",
        "Hook", MB_OK);
    }
  return fSuccess;
  }


/****************************************************************************

DWORD FAR PASCAL CallMsgMessageFilter (nCode, wParam, lParam)
int  nCode;
WORD  wParam;
LONG  lParam;
  {
  if (nCode == HC_ACTION)
    {
    hWnd = FindWindow (NULL, "CallMsgFilter");
    PostMessage (hWnd, WM_COMMAND, IDM_FROMMSGFILTER, 0L);
    return TRUE;
    }
  else
    return DefHookProc (nCode, wParam, lParam, &lpfnOldMessageFilterHook);
  }


CATCH.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CATCH.C

/*
 * Function(s) demonstrated in this program: Catch, Throw
 * Compiler version:  C 5.10
 * Description:  The Catch function catches the current execution environment
 *    and stores it in a buffer.  The Throw function jump to an execution
 *         state described by the parameter.
 *
 */

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "Catch.h"

HWND     hWndParent1;
HANDLE   hInstMain;

char  szOutputBuffer1 [70];
char  szOutputBuffer2 [500];
CATCHBUF CatchBuf;
int  CatchVal;

/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct   {
  char  *szMessage;
  } Messages [] =   {
  "About",
  "     This is a sample application to demonstrate the\n\
use of the Catch and Throw Windows functions.",

  "Help Message",
  "     This program uses the Catch Windows function\n\
to copy the current state of the execution environment.\n\
Then the Throw Windows function is used to return to\n\
the original execution environment.  Use the menu to\n\
invoke this function.",

  };


/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
HWND    hWnd;
int  MessageNumber;
  {
  sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
  sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
  MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
  }


/****************************************************************************

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int  nCmdShow;
  {
  static char  szAppName [] = "Catch";
  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG msg;
  short xScreen, yScreen;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = szAppName;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  xScreen = GetSystemMetrics (SM_CXSCREEN);
  yScreen = GetSystemMetrics (SM_CYSCREEN);

hWndParent1 = CreateWindow (szAppName,         /* window class name       */
                           "Catch N Throw",    /* window caption          */
                           WS_OVERLAPPEDWINDOW,/* window style            */
                           CW_USEDEFAULT,      /* initial x position      */
                           0,                  /* initial y position      */
                           CW_USEDEFAULT,      /* initial x size          */
                           0,                  /* initial y size          */
                           NULL,               /* parent window handle    */
                           NULL,               /* window menu handle      */
                           hInstance,          /* program instance handle */
                           NULL);              /* create parameters       */

  ShowWindow (hWndParent1, nCmdShow);
  UpdateWindow (hWndParent1);

  hInstMain = hInstance;

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


/****************************************************************************

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HMENU       hMenu;

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = GetSystemMenu (hWnd, FALSE);

      ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                  MF_APPEND | MF_STRING);
      break;

    case WM_SYSCOMMAND:
      switch (wParam)
        {
        case IDM_ABOUT:
          ProcessMessage (hWnd, 0);
          break;
        default:
          return DefWindowProc (hWnd, iMessage, wParam, lParam);
        }
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_CATCH:
          if (CatchVal = Catch((LPCATCHBUF)CatchBuf))
            {
            switch (CatchVal)
              {
              case ID_ERROR:
                MessageBox(hWnd,
                           "This message made possible by the Throw function"
                           "Catch N Throw",
                           MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
                break;
              }
            return 0L;
            }
          MessageBox (hWnd, "    About to use Throw to make a jump",
                      "Catch N Throw", MB_OK);
          Throw((LPCATCHBUF)CatchBuf, ID_ERROR);
          break;

        case IDM_HELP:
          ProcessMessage (hWnd, 2);
          break;
        }
      break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

      default:
        return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


CHECKDLG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\CHECKDLG.C

/*
 *
 *   checkdlg.c
 *
 *   This program demonstrates the use of the CheckDlgButton() function.
 *   CheckDlgButton() checks, unchecks, or disables dlg controls (where
 *   applicable). CheckDlgButton() is called from DialogBoxProc() in
 *   this sample application.
 *
 */

#include "windows.h"
#include "checkdlg.h"

HANDLE hInst;

FARPROC lpprocDialog;
long    FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

BOOL FAR PASCAL DialogBoxProc(hDlg, message, wParam, lParam)
HWND      hDlg;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  switch (message)
    {
    case WM_INITDIALOG:
      return TRUE;
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case ID_BUTTON1:
          break;

        case ID_BUTTON2:
          /* gray button with ID_BUTTON2 id */
          CheckDlgButton(hDlg, ID_BUTTON1, 2);
          break;

        case ID_BUTTON3:
          /* uncheck button with ID_BUTTON2 id */
          CheckDlgButton(hDlg, ID_BUTTON1, 0);
          break;

        case ID_BUTTON4:
          /* check button with ID_BUTTON2 id */
          CheckDlgButton(hDlg, ID_BUTTON1, 1);
          break;

        case ID_OK:
          EndDialog(hDlg, TRUE);
          break;
        }
      break;

    default:
      return FALSE;
    }
  }

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit(hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc(LPTR, sizeof(WNDCLASS));

  pHelloClass->hCursor        = LoadCursor(NULL, IDC_ARROW);
  pHelloClass->hIcon          = LoadIcon(hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)"min";
  pHelloClass->lpszClassName  = (LPSTR)"CheckDlgButton";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass((LPWNDCLASS)pHelloClass))
    return FALSE;     /* Initialization failed */

  LocalFree((HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
  }


int     PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  HelloInit(hInstance);
  hWnd = CreateWindow((LPSTR)"CheckDlgButton",
                      (LPSTR)"CheckDlgButton()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */
  hInst = hInstance;

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
    }
  return (int)msg.wParam;
  }


/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc(hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_COMMAND:
      lpprocDialog = MakeProcInstance((FARPROC)DialogBoxProc, hInst);
      DialogBox(hInst, MAKEINTRESOURCE(2), hWnd, lpprocDialog);
      FreeProcInstance((FARPROC)lpprocDialog);
      break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
      break;
    }
  return(0L);
  }


CHILDFP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SPAWN\CHILDFP.C

/*
 * Function(s) demonstrated in this program: ChildWindowFromPoint
 * Compiler version:  C 5.10
 * Description:  This function determines which, if any, of the child windows
 *               belonging to the given parent window contains the specified
 *               point.
 * Additional Comments:  This program also illustrates the subclassing of
 *                       windows.
 */

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "childfp.h"

char  szMessageBuffer [150] = "    Demo Program (ChildWindowFromPoint).";

char    szHelpBuffer [200] = "     Choose to enter point coordinates, or\n\
let the computer choose random coordinates.\n\
The program will use the ChildWindowFromPoint\n\
function to compute which window the point\n\
resides in.";

HWND     hWndMain, hWndChild1, hWndChild2, hX, hY, hOK2;
HANDLE   hInstMain;
FARPROC  lpProcEnterPoint;
FARPROC  lpProcNewEnterPoint;
FARPROC  lpProcOldX;
FARPROC  lpProcOldY;

char  szXValue [40];
char  szYValue [40];

/****************************************************************************

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE  hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int     nCmdShow;
  {
  static char   szAppName [] = "ChildFp";
  static char   szChildClass [] = "ChildFpChild";

  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG msg;
  short xScreen, yScreen;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = szAppName;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;

    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = ChildWndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = NULL;
    wndclass.hCursor       = LoadCursor (NULL, IDC_CROSS);
    wndclass.hbrBackground = GetStockObject (LTGRAY_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szChildClass;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  xScreen = GetSystemMetrics (SM_CXSCREEN);
  yScreen = GetSystemMetrics (SM_CYSCREEN);

  hWnd = CreateWindow (szAppName,                /* window class name       *
                      "Child Window From Point", /* window caption          *
                      WS_OVERLAPPEDWINDOW,       /* window style            *
                      CW_USEDEFAULT,             /* initial x position      *
                      0,                         /* initial y position      *
                      CW_USEDEFAULT,             /* initial x size          *
                      0,                         /* initial y size          *
                      NULL,                      /* parent window handle    *
                      NULL,                      /* window menu handle      *
                      hInstance,                 /* program instance handle *
                      NULL);                     /* create parameters       *

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

  hWndMain  = hWnd;
  hInstMain = hInstance;

  hWndChild1 = CreateWindow (szChildClass, "Child 1", WS_CHILD |
                             WS_CAPTION | WS_SYSMENU |
                             WS_THICKFRAME | WS_MAXIMIZEBOX |
                             WS_CLIPSIBLINGS,
                             xScreen / 9, yScreen / 8,
                             xScreen / 3, yScreen / 2,
                             hWndMain, 1, hInstance, NULL);

  ShowWindow (hWndChild1, SW_SHOWNORMAL);
  UpdateWindow (hWndChild1);

  hWndChild2 = CreateWindow (szChildClass, "Child 2", WS_CHILD |
                             WS_CAPTION | WS_SYSMENU |
                             WS_THICKFRAME | WS_MAXIMIZEBOX |
                             WS_CLIPSIBLINGS,
                             5 * xScreen / 9, yScreen / 8,
                             xScreen / 3, yScreen / 2,
                             hWndMain, 1, hInstance, NULL);

  ShowWindow (hWndChild2, SW_SHOWNORMAL);
  UpdateWindow (hWndChild2);

  lpProcEnterPoint    = MakeProcInstance (EnterPointDlgProc, hInstance);
  lpProcNewEnterPoint = MakeProcInstance (NewEnterPointDlgProc, hInstance);

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

/****************************************************************************

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HMENU         hMenu;
  POINT         pt;
  static int    xClient, yClient;
  char          szOutputBuffer [40];

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = GetSystemMenu (hWnd, FALSE);
      ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT, MF_APPEND | MF_STRING);
      break;

    case WM_SIZE:
      xClient = LOWORD (lParam);
      yClient = HIWORD (lParam);
      sprintf (szOutputBuffer, "Width = %i, Height = %i", xClient, yClient);
      MessageBox (hWnd, szOutputBuffer, "Client Window Dimensions", MB_OK);
      break;

    case WM_LBUTTONDBLCLK:
      break;

    case WM_SYSCOMMAND:
      switch (wParam)
        {
        case IDM_ABOUT:
          MessageBox (hWnd, szMessageBuffer, (LPSTR)"About", MB_OK);
          break;
        default:
        return DefWindowProc (hWnd, iMessage, wParam, lParam);
        }
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_CHOOSERANDOM:
          pt.x = pt.y = -1;
          while (((pt.x < 0) || (pt.x > xClient)) || ((pt.y < 0) ||
                 (pt.y > yClient)))
            {
            pt.x = (rand () / 47);
            pt.y = (rand () / 102);
            }
          hWnd = ChildWindowFromPoint (hWnd, pt);
          sprintf (szOutputBuffer, "The Point [%i, %i]", pt.x, pt.y);
          if (hWnd == hWndChild1)
            MessageBox (hWnd, "is in Child Window 1", szOutputBuffer,
                        MB_OK);
          else
            if (hWnd == hWndChild2)
              MessageBox (hWnd, "is in Child Window 2", szOutputBuffer,
                          MB_OK);
            else
              MessageBox (hWnd, "is not in a Child Window",
                          szOutputBuffer, MB_OK);
          break;

        case IDM_CHOOSE:
          pt.x = pt.y = -1;
          while (((pt.x < 0) || (pt.x > xClient)) || ((pt.y < 0) ||
                 (pt.y > yClient)))
            {
            DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                       lpProcEnterPoint);
            pt.x = atoi (szXValue);
            pt.y = atoi (szYValue);
            }
          hWnd = ChildWindowFromPoint (hWnd, pt);
          sprintf (szOutputBuffer, "The Point [%i, %i]", pt.x, pt.y);
          if (hWnd == hWndChild1)
            MessageBox (hWnd, "is in Child Window 1", szOutputBuffer,
                        MB_OK);
          else
            if (hWnd == hWndChild2)
              MessageBox (hWnd, "is in Child Window 2", szOutputBuffer,
                          MB_OK);
          else
            MessageBox (hWnd, "is not in a Child Window",
                        szOutputBuffer, MB_OK);
          break;

        case IDM_HELP:
          MessageBox (hWnd, szHelpBuffer, "Help Message", MB_OK);
          break;
        }
      break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }

/****************************************************************************

long    FAR PASCAL ChildWndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  return DefWindowProc (hWnd, iMessage, wParam, lParam);
  }


/****************************************************************************

BOOL FAR PASCAL EnterPointDlgProc (hDlg, iMessage, wParam, lParam)
HWND     hDlg;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  switch (iMessage)
    {
    case WM_INITDIALOG:
      SendDlgItemMessage (hDlg, IDD_X, EM_LIMITTEXT, (WORD)40, 0L);
      SendDlgItemMessage (hDlg, IDD_Y, EM_LIMITTEXT, (WORD)40, 0L);

      hX = GetDlgItem (hDlg, IDD_X);
      lpProcOldX = (FARPROC) GetWindowLong (hX, GWL_WNDPROC);
      SetWindowLong (hX, GWL_WNDPROC, (LONG) lpProcNewEnterPoint);
      SendMessage (hX, EM_SETSEL, 0, MAKELONG (0, 32767));
      hY = GetDlgItem (hDlg, IDD_Y);
      lpProcOldY = (FARPROC) GetWindowLong (hY, GWL_WNDPROC);
      SetWindowLong (hY, GWL_WNDPROC, (LONG) lpProcNewEnterPoint);
      SendMessage (hY, EM_SETSEL, 0, MAKELONG (0, 32767));
      hOK2 = GetDlgItem (hDlg, IDOK);

      return TRUE;
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDD_X:
          break;

        case IDD_Y:
          break;

        case IDOK:
          GetDlgItemText (hDlg, IDD_X, szXValue, 10);
          GetDlgItemText (hDlg, IDD_Y, szYValue, 10);
          EndDialog (hDlg, TRUE);
          break;

        default:
          return FALSE;
        }
    default:
      return FALSE;
    }
  return TRUE;
  }


/****************************************************************************

BOOL FAR PASCAL NewEnterPointDlgProc  (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  switch (iMessage)
    {
    case WM_GETDLGCODE:
      return (DLGC_WANTALLKEYS);

    case WM_CHAR:
      if ((wParam == VK_TAB) || (wParam == VK_RETURN))
        {
        SendMessage (hWndMain, WM_USER, 0, 0L);
        SetFocus (FindNextWindow (hWnd));
        return TRUE;
        }
      else
        {
        if (hWnd == hX)
          return ((BOOL)CallWindowProc (lpProcOldX, hWnd,
                  iMessage, wParam, lParam));
        if (hWnd == hY)
          return ((BOOL)CallWindowProc (lpProcOldY, hWnd,
                  iMessage, wParam, lParam));
        }
      break;

    default:
      if (hWnd == hX)
        return ((BOOL)CallWindowProc (lpProcOldX, hWnd,
                iMessage, wParam, lParam));
      if (hWnd == hY)
        return ((BOOL)CallWindowProc (lpProcOldY, hWnd,
                iMessage, wParam, lParam));
    }
  }


/****************************************************************************

HWND FindNextWindow (hWnd)
HWND   hWnd;
  {
  if (hWnd == hX)
    return hY;
  if (hWnd == hY)
    return hOK2;
  return NULL;
  }


CHMENU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\CHMENU.C

/*
 *  Function Name:   ChangeMenu
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   The program below will add new items to a menu.
 */

#include "windows.h"

long    FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_ChangeMenu(hWnd)
HWND hWnd;
  {
  HMENU     hSubItem;
  HMENU     hCurrentWindowMenu;
  unsigned  wIDNewItem1, wIDNewItem2;    /* assign items numbers for ID */
  BOOL      bChanged1;

  hCurrentWindowMenu = CreateMenu();
  hSubItem           = CreateMenu();
    /* menu heading created. */
  bChanged1 = ChangeMenu (hCurrentWindowMenu, NULL, (LPSTR) "Heading",
      hSubItem, MF_APPEND | MF_BYPOSITION | MF_POPUP);

  if (bChanged1 == FALSE)
    MessageBox(hWnd, (LPSTR)"ChangeMenu failed", (LPSTR)"ERROR", MB_ICONHAND)

   /* 2 items added under Heading */
  ChangeMenu (hSubItem, NULL, (LPSTR) "Item1", wIDNewItem1,
              MF_APPEND | MF_BYCOMMAND | MF_STRING);
  ChangeMenu (hSubItem, NULL, (LPSTR) "Item2", wIDNewItem2,
              MF_APPEND | MF_BYCOMMAND | MF_STRING);
  SetMenu(hWnd, hCurrentWindowMenu);

  return;
  }

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit(hInstance)
HANDLE hInstance;
  {
  WNDCLASS   wcClass;

  wcClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcClass.lpfnWndProc    = WndProc;
  wcClass.cbClsExtra     = 0;
  wcClass.cbWndExtra     = 0;
  wcClass.hInstance      = hInstance;
  wcClass.hIcon          = LoadIcon(hInstance, NULL);
  wcClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  wcClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  wcClass.lpszMenuName   = (LPSTR)NULL;
  wcClass.lpszClassName  = (LPSTR)"ChangeMenu";

  if (!RegisterClass((LPWNDCLASS) & wcClass))
    return FALSE;

  return TRUE;
  }

int     PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE  hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  if (!hPrevInstance)
    {
    if (!WinInit(hInstance))
      return FALSE;
    }

  hWnd = CreateWindow((LPSTR)"ChangeMenu",
                     (LPSTR)"ChangeMenu()",
                     WS_OVERLAPPEDWINDOW,
                     CW_USEDEFAULT,
                     CW_USEDEFAULT,
                     CW_USEDEFAULT,
                     CW_USEDEFAULT,
                     (HWND)NULL,        /* no parent */
                     (HMENU)NULL,       /* use class menu */
                     (HANDLE)hInstance, /* handle to window instance */
                     (LPSTR)NULL );     /* no params to pass on */

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

        /* Procedures which make up the window class. */
long    FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  switch (message)
    {
    case WM_CREATE:
      CALL_ChangeMenu (hWnd); /* Change the menu when the window is created *
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
      break;
    }
  return(0L);
  }


CHORD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CHORD.C

/*
 *   This program demonstrates the use of the Chord() function.
 *   Chord() draws a chord. Chord() is called in response to a WM_PAINT
 *   message in HelloWndProc();
 */

#include "windows.h"

long    FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit(hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc(LPTR, sizeof(WNDCLASS));

  pHelloClass->hCursor        = LoadCursor(NULL, IDC_ARROW);
  pHelloClass->hIcon             = LoadIcon(hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName   = (LPSTR)"Chord";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass((LPWNDCLASS)pHelloClass))
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  LocalFree((HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
  }


int     PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int      cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  HelloInit(hInstance);
  hWnd = CreateWindow((LPSTR)"Chord",
                      (LPSTR)"Chord()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL );     /* no params to pass on */

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

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

  return (int)msg.wParam;
  }


/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc(hWnd, message, wParam, lParam)
HWND       hWnd;
unsigned   message;
WORD       wParam;
LONG       lParam;
  {
  PAINTSTRUCT ps;
  BOOL bDrawn;       /* was the chord drawn? */

  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    case WM_PAINT:
      BeginPaint(hWnd, (LPPAINTSTRUCT) & ps);
      bDrawn = Chord(ps.hdc, 5, 5, 100, 100, 0, 22, 150, 22);
                  /***** draw the chord *****/
      if (!bDrawn)
        MessageBox(NULL,
                   (LPSTR)"Chord failed!",
                   (LPSTR)"Chord info:",
                   MB_OK);          /* Tell User it didn't work */
      EndPaint(hWnd, (LPPAINTSTRUCT) & ps);
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
      break;
    }
  return(0L);
  }


CKMNUITM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\CKMNUITM.C

/*
 *   This program demonstrates the use of the CheckMenuItem() function.
 *   CheckMenuItem() checks or unchecks the given menu item. CheckMenuItem()
 *   is called in response to a WM_COMMAND message in HelloWndProc() in
 *   this sample application.
 */

#include "windows.h"
#include "ckmnuitm.h"

WORD   mOldChoice = NULL;   /* the last chosen menu item */
HMENU  hMenu;        /* handle to menu of window  */

long    FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit(hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc(LPTR, sizeof(WNDCLASS));

  pHelloClass->hCursor        = LoadCursor(NULL, IDC_ARROW);
  pHelloClass->hIcon          = LoadIcon(hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)"menucnt";
  pHelloClass->lpszClassName  = (LPSTR)"CheckMenuItem";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass((LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree((HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
  }


int     PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int      cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  HelloInit(hInstance);
  hWnd = CreateWindow((LPSTR)"CheckMenuItem",
                      (LPSTR)"CheckMenuItem()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL );     /* no params to pass on */

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

  hMenu = GetMenu(hWnd);     /* get the handle to the menu */

  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
    }
  return (int)msg.wParam;
  }


/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc(hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_COMMAND:
      switch( wParam )
        {
        case IDM_CHOICE1:
        case IDM_CHOICE2:
        case IDM_CHOICE3:
          if (mOldChoice)  /* if another menu item previously chosen */
            CheckMenuItem(hMenu, mOldChoice, MF_UNCHECKED);   /* uncheck it *
          mOldChoice = wParam;  /* keep track of this choice for later */
          CheckMenuItem(hMenu, mOldChoice, MF_CHECKED);   /* check the new ch
          break;
        }
      break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
      break;
    }
  return(0L);
  }


CKRADBTN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\CKRADBTN.C

/*
 *   This program demonstrates the use of the CheckRadioButton() function.
 *   CheckRadioButton() checks one radio button and unchecks all other radio
 *   buttons with identifiers in the range specified by the 2nd and 3rd
 *   parameters. CheckRadioButton() is called from DialogBoxProc() in this
 *   sample application.
 */

#include "windows.h"
#include "ckradbtn.h"

HANDLE hInst;

FARPROC lpprocDialog;
long    FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL DialogBoxProc(HWND, unsigned, WORD, LONG);

BOOL FAR PASCAL DialogBoxProc(hDlg, message, wParam, lParam)
HWND      hDlg;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  switch (message)
    {
    case WM_INITDIALOG:
      return TRUE;
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case ID_RADIO1:
        case ID_RADIO2:
        case ID_RADIO3:
        case ID_RADIO4:
          CheckRadioButton(hDlg, ID_RADIO1, ID_RADIO4, wParam);
              /* check the chosen radio button, uncheck the rest */
          break;

        case ID_OK:
          EndDialog(hDlg, TRUE);
          break;
        }
      break;

    default:
      return FALSE;
      break;
    }
  }


/* Procedure called when the application is loaded for the first time */
BOOL HelloInit(hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc(LPTR, sizeof(WNDCLASS));

  pHelloClass->hCursor        = LoadCursor(NULL, IDC_ARROW);
  pHelloClass->hIcon             = LoadIcon(hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)"min";
  pHelloClass->lpszClassName   = (LPSTR)"CheckRadioButton";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass((LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree((HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
  }


int     PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  HelloInit(hInstance);
  hWnd = CreateWindow((LPSTR)"CheckRadioButton",
                      (LPSTR)"CheckRadioButton()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL );     /* no params to pass on */
  hInst = hInstance;

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

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

  return (int)msg.wParam;
  }


/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
  {
  HMENU  hMenu;

  switch (message)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();  /*  Create a Menu  */
      ChangeMenu (hMenu, NULL, "Dialog", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_COMMAND:
      if (wParam == 100)
        {
        lpprocDialog = MakeProcInstance((FARPROC)DialogBoxProc, hInst);
        DialogBox(hInst, MAKEINTRESOURCE(2), hWnd, lpprocDialog);
        FreeProcInstance((FARPROC)lpprocDialog);
        break;
        }
      else
        return DefWindowProc(hWnd, message, wParam, lParam);
      break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
      break;
    }
  return(0L);
  }


CLEARCOM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\CLEARCOM.C

/*
 *
 * Function (s) demonstrated in this program: ClearCommBreak, CloseComm,
 *    OpenComm, SetCommBreak
 *
 * Compiler version:  C 5.10
 *
 * Description:  This function restores character transmission and places the
 *    transmission line in a nonbreak state.
 *
 */

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "ClearCom.h"

HWND     hWndParent1;
HANDLE   hInstMain;

char  szOutputBuffer1 [70];
char  szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct   {
  char  *szMessage;
  } Messages [] =   {
  "About\0",
  "     This is a sample application to demonstrate the\n\
use of the ClearCommBreak, CloseComm, OpenComm, and\n\
SetCommBreak Windows functions.",

      "Help Message",
  "     This program uses the ClearCommBreak Windows\n\
function to restore character transmission to the\n\
comm port and places the transmission line in a\n\
nonbreak state.  nResult should be 0 if the function\n\
was successful.  Use the menu to invoke this\n\
function.",

  };


/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
HWND     hWnd;
int  MessageNumber;
  {
  sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
  sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
  MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
  }

/****************************************************************************

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int         nCmdShow;
  {
  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG msg;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = "ClearCom";
    wndclass.lpszClassName = "ClearCom";

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hWndParent1 = CreateWindow (szAppName,          /* window class name
                             "ClearCommBreak",    /* window caption
                             WS_OVERLAPPEDWINDOW, /* window style
                             CW_USEDEFAULT,       /* initial x position
                             0,                   /* initial y position
                             CW_USEDEFAULT,       /* initial x size
                             0,                   /* initial y size
                             NULL,                /* parent window handle
                             NULL,                /* window menu handle
                             hInstance,           /* program instance handle
                             NULL);               /* create parameters

  ShowWindow (hWndParent1, nCmdShow);
  UpdateWindow (hWndParent1);

  hInstMain = hInstance;

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

/****************************************************************************

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  int    nCid;
  int    nResult;
  HMENU  hMenu;

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = GetSystemMenu (hWnd, FALSE);
      ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT, MF_APPEND | MF_STRING);
      break;

    case WM_SYSCOMMAND:
      switch (wParam)
        {
        case IDM_ABOUT:
          ProcessMessage (hWnd, 0);
          break;
        default:
          return DefWindowProc (hWnd, iMessage, wParam, lParam);
        }
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_CLEARCOM:
          nCid = OpenComm ( (LPSTR)"LPT1", 255, 256);
          sprintf (szOutputBuffer1, "nCid = %i", nCid);
          MessageBox (hWnd, szOutputBuffer1, "OpenComm", MB_OK);

          nResult = SetCommBreak (nCid);
          sprintf (szOutputBuffer1, "nResult = %i", nResult);
          MessageBox (hWnd, szOutputBuffer1, "SetCommBreak", MB_OK);

          nResult = ClearCommBreak (nCid);
          sprintf (szOutputBuffer1, "nResult = %i", nResult);
          MessageBox (hWnd, szOutputBuffer1, "ClearCommBreak", MB_OK);

          nResult = CloseComm (nCid);
          sprintf (szOutputBuffer1, "nResult = %i", nResult);
          MessageBox (hWnd, szOutputBuffer1, "CloseComm", MB_OK);
          break;

        case IDM_HELP:
          ProcessMessage (hWnd, 2);
          break;
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


CLIENTSC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SPAWN\CLIENTSC.C

/*
 *   This program demonstrates the use of the ClientToScreen () function.
 *   ClientToScreen () converts client area coordinates to screen coordinates
 *   (upper left of the screen being the origin). ClientToScreen () is called
 *   from ParentWndProc () in response to a WM_SIZE or WM_MOVE message.
 *
 */

#include <windows.h>

int     PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
long    FAR PASCAL ParentWndProc (HWND, unsigned, WORD, LONG);
long    FAR PASCAL PopupWndProc (HWND, unsigned, WORD, LONG);
int     sprintf (char *, const char *, ...);

HWND    hChild;
char    szBuff[80] = " ";   /*          used for output           */
short   nTextLength = 0;    /*   length of string for TextOut ()  */


int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG      msg;
  HWND     hParent;
  WNDCLASS wndClass;

  if (!hPrevInstance)
    {
    wndClass.style          = CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc    = ParentWndProc;
    wndClass.cbClsExtra     = 0;
    wndClass.cbWndExtra     = 0;
    wndClass.hInstance      = hInstance;
    wndClass.hIcon          = LoadIcon (NULL, NULL);
    wndClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wndClass.hbrBackground  = GetStockObject (WHITE_BRUSH);
    wndClass.lpszMenuName   = NULL;
    wndClass.lpszClassName  = "ClientToScreenParent";

    if (!RegisterClass (&wndClass))
      return FALSE;

    wndClass.style          = CS_HREDRAW | CS_VREDRAW;
    wndClass.lpfnWndProc    = PopupWndProc;
    wndClass.cbClsExtra     = 0;
    wndClass.cbWndExtra     = 0;
    wndClass.hInstance      = hInstance;
    wndClass.hIcon          = NULL;
    wndClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wndClass.hbrBackground  = GetStockObject (WHITE_BRUSH);
    wndClass.lpszMenuName   = NULL;
    wndClass.lpszClassName  = "ClientToScreenPopup";

    if (!RegisterClass (&wndClass))
      return FALSE;
    }

  hParent = CreateWindow ( (LPSTR)"ClientToScreenParent",
                         (LPSTR)"Parent Window for ClientToScreen () Demo",
                         WS_OVERLAPPEDWINDOW,
                         32,
                         200,
                         500,
                         48,
                         NULL,      /* no parent */
                         NULL,      /* use class menu */
                         hInstance, /* handle to window instance */
                         NULL);     /* no params to pass on */

  ShowWindow (hParent, cmdShow);
  UpdateWindow (hParent);

  hChild = CreateWindow ( (LPSTR)"ClientToScreenPopup",
                        (LPSTR)"Popup Window for ClientToScreen () Demo",
                        WS_POPUP | WS_CAPTION | WS_VISIBLE,
                        32,
                        256,
                        500,
                        48,
                        hParent,
                        NULL,      /* use class menu */
                        hInstance, /* handle to window instance */
                        NULL);     /* no params to pass on */

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

  return (int)msg.wParam;
  }

long    FAR PASCAL ParentWndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  POINT myPoint;       /* point structure used in calls to ClientToScreen ()

  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    case WM_MOVE:
    case WM_SIZE:
      DefWindowProc (hWnd, message, wParam, lParam);
      myPoint.x = 0;
      myPoint.y = 0;
      ClientToScreen (hWnd, (LPPOINT) & myPoint);
      nTextLength = sprintf (szBuff,
          "Screen Coordinates of Upper Left-hand Corner: (%d, %d)",
          myPoint.x,
          myPoint.y);
      InvalidateRect (hChild, NULL, TRUE);
      UpdateWindow (hChild);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    break;
    }
  return (0L);
  }

long    FAR PASCAL PopupWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_PAINT:
      BeginPaint (hWnd, &ps);
      TextOut (ps.hdc, 5, 5, szBuff, nTextLength);
      EndPaint (hWnd, &ps);
      break;
    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


CLIPBOX.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CLIPBOX.C

/*
 *  Function (s) demonstrated in this program: GetClipbox
 *  Description: This function retrieves the dimensions of the tightest
 *               bounding rectangle around the current clipping boundary.
 *               The dimensions are copied to the buffer pointed to by the
 *               last parameter.
 */

#include <windows.h>
#include <stdio.h>

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

HDC hDC;

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        cmdShow;
  {
  HWND      hWnd;
  WNDCLASS  rClass;
  MSG       msg;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = "CLIPBOX";

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hWnd = CreateWindow ("CLIPBOX",
      "GetClipBox",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      0,
      CW_USEDEFAULT,
      0,
      NULL,
      NULL,
      hInstance,
      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);
  hDC = GetDC (hWnd);

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


long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HMENU  hMenu;
  HRGN   hRgnBox;
  HRGN   hRgnCircle;
  HRGN   hRgnBoth;
  RECT   lpRect;
  short  nRgnType;

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"CheckType", 100, MF_APPEND);
      ChangeMenu (hMenu, NULL, (LPSTR)"Set Complex", 200, MF_APPEND);
      ChangeMenu (hMenu, NULL, (LPSTR)"Set Simple", 300, MF_APPEND);
      ChangeMenu (hMenu, NULL, (LPSTR)"Set Null", 400, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

  case WM_COMMAND:
    switch (wParam)
      {
      case 100:
        nRgnType = GetClipBox (hDC, (LPRECT) & lpRect);
        switch (nRgnType)
          {
          case ERROR:
            MessageBox (hWnd, (LPSTR)"Device context is not valid",
                (LPSTR)"GetClipBox", MB_OK | MB_ICONEXCLAMATION);
            break;
          case NULLREGION:
            MessageBox (hWnd, (LPSTR)"Clipping region is empty",
                (LPSTR)"GetClipBox", MB_OK);
            break;
          case SIMPLEREGION:
            MessageBox (hWnd, (LPSTR)"Clipping region is simple",
                (LPSTR)"GetClipBox", MB_OK);
            break;
          case COMPLEXREGION:
            MessageBox (hWnd, (LPSTR)"Clipping region is complexed",
                (LPSTR)"GetClipBox", MB_OK);
            break;
          }
        InvalidateRect (hWnd, (LPRECT)NULL, TRUE);
        break;

      case 200:
        hRgnBox = CreateRectRgn (50, 75, 125, 150);
        hRgnCircle = CreateEllipticRgn (50, 25, 150, 125);
        hRgnBoth = CreateRectRgn (0, 0, 0, 0);
        CombineRgn (hRgnBoth, hRgnBox, hRgnCircle, RGN_XOR);
        SelectClipRgn (hDC, hRgnBoth);
        break;

      case 300:
        hRgnBox = CreateRectRgn (200, 225, 225, 250);
        SelectClipRgn (hDC, hRgnBox);
        break;

      case 400:
        hRgnBox = CreateRectRgn (0, 0, 0, 0);
        SelectClipRgn (hDC, hRgnBox);
        break;
      }
    break;

    case WM_DESTROY:
      ReleaseDC (hWnd, hDC);
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


CLIPCHAN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPCHAN.C

/*
 *  This program demonstrates the use of ChangeClipboardChain function.
 *  This funtion removes the window specified by a handle from the chain
 *  of clipboard viewers and makes the window next in the viewer chain the
 *  descendent of the removing window's ancestor.
 */

#include <windows.h>

long    FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);

static char  szAppName[] = "clipchan";
static char  szFuncName[] = "ChangeClipboardChain";

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  WNDCLASS rClass;
  HWND     hWnd;
  MSG      msg;
  HMENU    hMenu;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = (LPSTR) NULL;
    rClass.lpszClassName = (LPSTR) szAppName;

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, (LPSTR)"Clipboard Chain", 100, MF_APPEND);

  hWnd = CreateWindow (szAppName,            /* window class name       */
                      szFuncName,                 /* window caption
                      WS_OVERLAPPEDWINDOW,        /* window style
                      CW_USEDEFAULT,              /* initial x position
                      0,                          /* initial y position
                      CW_USEDEFAULT,              /* initial x size
                      0,                          /* initial y size
                      NULL,                       /* parent window handle
                      hMenu,                      /* window menu handle
                      hInstance,                  /* program instance handle
                      NULL);                     /* create parameters       *

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND        hWnd;
unsigned    iMessage;
WORD        wParam;
LONG        lParam;
  {
  HMENU  hMenu;
  HWND   hWndStatic;
  BOOL   bRemoved;

  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == 100)
        {
        hWndStatic = SetClipboardViewer (hWnd);
        MessageBox (NULL,
            (LPSTR)"Removing current window from the viewer chain",
            (LPSTR)szFuncName, MB_OK);
        bRemoved = ChangeClipboardChain (hWnd, hWndStatic);
        if (bRemoved != 0)
          MessageBox (NULL,
              (LPSTR)"Current window removed from the viewer chain",
              (LPSTR)szFuncName, MB_OK);
        else
          MessageBox (NULL,
              (LPSTR)"Current window not removed from viewer chain",
              (LPSTR)szFuncName, MB_OK);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


CLIPCLOS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPCLOS.C

/*
 *  This program demonstrates the use of CloseClipboard function.
 *  This function close the clipboard. ClipClipboard should be called when
 *  a window has finished examining or changing the clipboard. It lets
 *  other application access the clipboard.
 */

#include <windows.h>

static char  szAppName[] = "clipclos";
static char  szFuncName[] = "CloseClipboard";

long    FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  HWND      hWnd;
  WNDCLASS  rClass;
  MSG       msg;
  HMENU     hMenu;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = (LPSTR) NULL;
    rClass.lpszClassName = (LPSTR) szAppName;

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hMenu = CreateMenu ();  /*  Add a Menu Item  */
  ChangeMenu (hMenu, NULL, (LPSTR)"Close Clipboard", 100, MF_APPEND);

  hWnd = CreateWindow (szAppName,          /* window class name       */
                      szFuncName,          /* window caption          */
                      WS_OVERLAPPEDWINDOW, /* window style            */
                      CW_USEDEFAULT,       /* initial x position      */
                      0,                   /* initial y position      */
                      CW_USEDEFAULT,       /* initial x size          */
                      0,                   /* initial y size          */
                      NULL,                /* parent window handle    */
                      hMenu,               /* window menu handle      */
                      hInstance,           /* program instance handle */
                      NULL);               /* create parameters       */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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


long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND      hWnd;
unsigned  iMessage;
WORD      wParam;
LONG      lParam;
  {
  HMENU  hMenu;
  BOOL   bClosed;

  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == 100)
        {
        OpenClipboard (hWnd);
        MessageBox (NULL, (LPSTR)"Closing clipboard", (LPSTR)szFuncName,
            MB_OK);
        bClosed = CloseClipboard ();
        if (bClosed != 0)
          MessageBox (NULL, (LPSTR)"Clipboard closed", (LPSTR)szFuncName,
               MB_OK);
        else
          MessageBox (NULL, (LPSTR)"Clipboard not closed", (LPSTR)szFuncName,
              MB_OK);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


CLIPCOUN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPCOUN.C

/*
 *  This program demonstrates the use of CountClipboardFormats function.
 *  This function retieves a count of the number of formats that the clip-
 *  board can render.
 */

#include <windows.h>
#include <stdio.h>

static char  szAppName[] = "clipcoun";
static char  szFuncName[] = "CountClipboardFormats";

long    FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = (LPSTR) NULL;
    rClass.lpszClassName = (LPSTR) szAppName;

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hWnd = CreateWindow (szAppName,
                      szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND        hWnd;
unsigned    iMessage;
WORD        wParam;
LONG        lParam;
  {
  HMENU  hMenu;
  int  nCount;
  char  szBuff[80];

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"Clipboard Formats", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_COMMAND:
      if (wParam == 100)
        {
        MessageBox (NULL, (LPSTR)"Counting clipboard formats",
                   (LPSTR)szFuncName, MB_OK);
        nCount = CountClipboardFormats ();
        sprintf (szBuff, "There is %d clipboard formats right now.", nCount);
        MessageBox (NULL, (LPSTR)szBuff, (LPSTR)szFuncName, MB_OK);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;
    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


CLIPCURS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CURSOR\CLIPCURS.C

/*
 *   This program demonstrates use of the ClipCursor () function.
 *   ClipCursor () confines movement of the cursor to the rectangle specified
 *   by the "lpRect" parameter . In WinMain (), GetClientRect () is
 *   called, then ClientToScreen () is called to convert the client area
 *   coordinates to screen coordinates (because ClipCursor () is a screen-
 *   coordinate relative function).  ClipCursor () is then called to confine
 *   the cursor to the left half of the client area.
 */

#include "windows.h"

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit (hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));

  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon          = LoadIcon (hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName  = (LPSTR)"ClipCursor";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree ( (HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
  }


int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE  hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  RECT  rClientRect;
  POINT UpperLeft;
  POINT LowerRight;

  HelloInit (hInstance);
  hWnd = CreateWindow ( (LPSTR)"ClipCursor",
                      (LPSTR)"ClipCursor ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  GetClientRect (hWnd, (LPRECT) & rClientRect);
  UpperLeft.x  = rClientRect.left;
  UpperLeft.y  = rClientRect.top;
  ClientToScreen (hWnd, (LPPOINT) & UpperLeft);

  LowerRight.x = rClientRect.bottom;
  LowerRight.y = rClientRect.right / 2;
  ClientToScreen (hWnd, (LPPOINT) & LowerRight);

  rClientRect.left   = UpperLeft.x;
  rClientRect.top    = UpperLeft.y;
  rClientRect.bottom = LowerRight.x;
  rClientRect.right  = LowerRight.y;

  ClipCursor ( (LPRECT) & rClientRect);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }


/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
  {
  switch (message)
    {
  case WM_DESTROY:
/*** release the cursor (a shared resource) to the rest of the system ***/
    ClipCursor ( (LPRECT)NULL);
    PostQuitMessage (0);
    break;

  default:
    return DefWindowProc (hWnd, message, wParam, lParam);
    break;
    }
  return (0L);
  }


CLIPDATA.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPDATA.C

/*
 *  This program demonstrates the use of GetClipboardData function.
 *  This function retieves data from the clipboard in the format given by
 *  an unsigned short interger value that specifies a data format. The
 *  clipboard must have been previously opened.
 *
 */

#include <windows.h>

static char  szAppName[] = "clipdata";
static char     szFuncName[] = "GetClipboardData";

LPSTR FAR PASCAL lstrcpy (LPSTR, LPSTR);

long    FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  HMENU    hMenu;
  MSG      msg;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = (LPSTR) NULL;
    rClass.lpszClassName = (LPSTR) szAppName;

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, (LPSTR)"Read From Clipboard", 100, MF_APPEND);

  hWnd = CreateWindow (szAppName,            /* window class name       */
                      szFuncName,            /* window caption          */
                      WS_OVERLAPPEDWINDOW,   /* window style            */
                      CW_USEDEFAULT,         /* initial x position      */
                      0,                     /* initial y position      */
                      CW_USEDEFAULT,         /* initial x size          */
                      0,                     /* initial y size          */
                      NULL,                  /* parent window handle    */
                      hMenu,                 /* window menu handle      */
                      hInstance,             /* program instance handle */
                      NULL);                 /* create parameters       */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned  iMessage;
WORD     wParam;
LONG     lParam;
  {
  HMENU  hMenu;
  HANDLE hClipData;
  HANDLE hMem;
  LPSTR  lpText;
  char  szBuffer[80];

  switch (iMessage)
    {
    case WM_CREATE:
      OpenClipboard (hWnd);
      hMem = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT,
                         (long) strlen (szFuncName));
      lpText = (LPSTR) GlobalLock (hMem);
      lstrcpy (lpText, (LPSTR) szFuncName);
      SetClipboardData (CF_TEXT, hMem);
      GlobalUnlock (hMem);
      CloseClipboard ();

    case WM_COMMAND:
      if (wParam == 100)
        {
        OpenClipboard (hWnd);
        MessageBox (hWnd, (LPSTR)"Getting clipboard data", (LPSTR)szFuncName,
            MB_OK);
        hClipData = GetClipboardData (CF_TEXT);
        if (hClipData != NULL)
          MessageBox (hWnd, (LPSTR)"Data Received", (LPSTR)szFuncName, MB_OK)
        else
          MessageBox (hWnd, (LPSTR)"There is no data", (LPSTR)szFuncName,
              MB_OK);
        CloseClipboard ();
        }
      break;

    case WM_DESTROY:
      GlobalFree (hMem);        /*  Free up the memory  */
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


CLIPEMPT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPEMPT.C

/*
 *
 *  EmptyClipboard ()
 *
 *  This program demonstrates the use of the EmptyClipboard () function.
 *  This function empties the clipboard and frees handles to data in the
 *  clipboard. It the assigns ownership of the clipboard to the window
 *  that currently has the clipboard open. The clipboard must be open
 *  when EmptyClipboard is called.
 *
 */

#include <windows.h>

long    FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hIcon         = LoadIcon  (hInstance, IDI_APPLICATION);
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hbrBackground = GetStockObject  (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = "clipempt";

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, (LPSTR)"Clear Clipboard", 100, MF_APPEND);

  hWnd = CreateWindow ("clipempt",
                      "EmptyClipboard",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      hMenu,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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


long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HMENU hMenu;

  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == 100)
        {
        OpenClipboard (hWnd);
        MessageBox (hWnd, (LPSTR)"Emptying clipboard", (LPSTR)"EmptyClipboard
                    MB_OK);
        if (EmptyClipboard ())  /*  Empty the clipboard  */
          MessageBox (hWnd, (LPSTR)"Clipboard emptied", (LPSTR)"EmptyClipboar
                      MB_OK);
        else
          MessageBox (hWnd, (LPSTR)"Clipboard not emptied",
                     (LPSTR)"EmptyClipboard", MB_OK);
        CloseClipboard  ();
        }
      break;

    case WM_DESTROY:
      PostQuitMessage  (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return  (0L);
  }


CLIPENUM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPENUM.C

/*
 *  This program demonstrates the use of EnumClipboardFormats function.
 *  This function numbers a list of formats and returns the next format in
 *  the list.
 *
 */

#include <windows.h>

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = "clipenum";

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hWnd = CreateWindow ("clipenum",            /* window class name       */
                      "EnumClipboardFormats",                 /* window capti
                      WS_OVERLAPPEDWINDOW,        /* window style
                      CW_USEDEFAULT,              /* initial x position
                      0,                          /* initial y position
                      CW_USEDEFAULT,              /* initial x size
                      0,                          /* initial y size
                      NULL,                       /* parent window handle
                      NULL,                       /* window menu handle
                      hInstance,                  /* program instance handle
                      NULL);                      /* create parameters

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HMENU hMenu;
  int  nNextFormat;

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"Number Formats", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_COMMAND:
      if (wParam == 100)
        {
        MessageBox (NULL, (LPSTR)"Getting first format in list",
                   (LPSTR)"EnumClipboardFormats", MB_OK);
        nNextFormat = EnumClipboardFormats (0);
        if (nNextFormat == 0)
          MessageBox (NULL, (LPSTR)"First format returned",
                     (LPSTR)"EnumClipboardFormats", MB_OK);
        else
          MessageBox (NULL, (LPSTR)"First format not returned",
                     (LPSTR)"EnumClipboardFormats", MB_OK);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


CLIPFORM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPFORM.C

/*
 *   This program demonstrates the use of the IsClipboardFormatAvailable
 *   function. IsClipboardFormatAvailable checks to see if the given
 *   data format is available in the clipboard. In this sample application,
 *   the format checked for in the clipboard is CF_BITMAP. IsClipboardFormat-
 *   Available is called from WinMain in this sample application. To test
 *   the function, bring up Paint and this application at the same time.
 *   If you cut anything from Paint, it goes to the clipboard and IsClipboard
 *   FormatAvailable should return TRUE. If there is no bitmap in the clipboa
 *   then IsClipBoardFormatAvailable should return FALSE. Using Paint, once
 *   you have put a bitmap in the clipboard, there will be a bitmap format
 *   in the clipboard until your windows session is ended.
 */

#include <windows.h>

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HWND      hWnd;
  WNDCLASS  wndclass;
  MSG       msg;
  HMENU     hMenu;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = "CLIPFORM";

    if (!RegisterClass (&wndclass))
      return FALSE;
    }
  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, (LPSTR)"Format", 100, MF_APPEND);

  hWnd = CreateWindow ("CLIPFORM",
                      "IsClipboardFormatAvailable",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      hMenu,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage (&msg, NULL, 0, 0))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return (int)msg.wParam;
  }

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  BOOL  bFormat;

  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == 100)
        {
        bFormat = IsClipboardFormatAvailable (CF_BITMAP);
        if (bFormat)
          MessageBox (hWnd, (LPSTR)"There IS a bitmap format available",
                     (LPSTR)"IsClipboardFormatAvailable", MB_OK);
        else
          MessageBox (hWnd, (LPSTR)"There is NOT a bitmap format available",
                     (LPSTR)"IsClipboardFormatAvailable", MB_OK);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


CLIPFORN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPFORN.C

/*
 *
 *  GetClipboardFormatName
 *
 *  clipforn.c, charlesl, v2.00, 29-Dec-1987
 *
 *  This program demonstrates the use of GetClipboardFormatName function.
 *  This function retrieves from the clipboard the name of the register
 *  format specified by an unsigned short integer. The name is copied to
 *  the buffer pointed to by long pointer.
 *
 *  Other references: CFClip.c
 *
 *  Microsoft Product Support Services
 *  Windows Version 2.0 function demonstration application
 *  Copyright (c) Microsoft 1987
 *
 */

/*************************************************************************/
/*                           INCLUDE FILES                               */
/*************************************************************************/

#include <windows.h>

/*************************************************************************/
/*                        STRUCTURE DEFINTIONS                           */
/*************************************************************************/

typedef struct
{
   int nDummy;
}
SETUPDATA;

/*************************************************************************/
/*                         GLOBAL VARIABLES                              */
/*************************************************************************/

static SETUPDATA strSetUpData;
static HANDLE hInst;
static char szFileName[] = "clipforn";
static char szFuncName[] = "GetClipboardFormatName";

/*************************************************************************/
/*                       FORWARD REFERENCES                              */
/*************************************************************************/

long FAR PASCAL WindowProc ( HANDLE , unsigned , WORD , LONG );

/*************************************************************************/
/*                         MAIN PROCEDURE                                */
/*************************************************************************/

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  MSG  msg;

  WindowInit (hInstance, hPrevInstance, cmdShow );

  while ( GetMessage((LPMSG)&msg, NULL, 0 , 0 ))
    {
    TranslateMessage((LPMSG)&msg);
    DispatchMessage((LPMSG)&msg);
    }
  exit(msg.wParam);
}

/*************************************************************************/
/*                      INITIALIZATION                                   */
/*************************************************************************/

BOOL WindowInit (hInstance , hPrevInstance , cmdShow)
HANDLE hInstance, hPrevInstance;
int cmdShow;
{
  HWND  hWnd;

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.lpfnWndProc   = WindowProc;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;
     rClass.hInstance     = hInstance;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.lpszMenuName  = (LPSTR) NULL;
     rClass.lpszClassName = (LPSTR) szFileName;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }
  else
     GetInstanceData ( hPrevInstance, (PSTR) &strSetUpData,
        sizeof ( SETUPDATA ) );

  hInst = hInstance;

  hWnd = CreateWindow ( (LPSTR) szFileName, (LPSTR) szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      (HWND) NULL, (HMENU) NULL,
                      (HANDLE) hInstance, (LPSTR) NULL );

  ShowWindow ( hWnd , cmdShow );
  UpdateWindow (hWnd);

  return TRUE;
}

/*************************************************************************/
/*                 WINDOW PROCEDURE - PROCESS MESSAGES                   */
/*************************************************************************/

long FAR PASCAL WindowProc (hWnd , message , wParam , lParam)
HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint ( hWnd, (LPPAINTSTRUCT)&ps );
        FunctionDemonstrated ( hWnd );
        EndPaint ( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage ( 0 );
        break;

    default:
        return ( DefWindowProc ( hWnd , message , wParam , lParam ) );
        break;
    }
  return ( 0L );
}

/*************************************************************************/
/*              FUNCTION DEMONSTRATED HERE - LOOK HERE                   */
/*************************************************************************/

FunctionDemonstrated ( hWnd )
HWND hWnd;
{
  WORD wFormat;
  int nCopied;
  LPSTR lpFormatName;

  MessageBox (NULL, (LPSTR)"Getting clipboard format name",
     (LPSTR)szFuncName, MB_OK);

  wFormat = RegisterClipboardFormat ( (LPSTR)"format_name" );
  nCopied = GetClipboardFormatName ( wFormat, lpFormatName, 20 );

  if ( nCopied != 0 )
      MessageBox (NULL, (LPSTR)"Format name gotten", (LPSTR)szFuncName,
         MB_OK);
  else
      MessageBox (NULL, (LPSTR)"Format does not exits", (LPSTR)szFuncName,
         MB_OK);

  return TRUE;
}



CLIPOPEN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPOPEN.C

/*
 *  OpenClipboard
 *  This program demonstrates the use of the OpenClipboard function.
 *  This function opens the clipboard for examination and prevents other
 *  applications from modifying the clipboard contents.
 */

#include <windows.h>

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;
  HMENU    hMenu;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = (LPSTR) NULL;
    rClass.lpszClassName = (LPSTR) "clipopen";

    if (!RegisterClass (&rClass))
      return FALSE;
    }
  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, (LPSTR)"Open Clipboard", 100, MF_APPEND);

  hWnd = CreateWindow ("clipopen",
                      "OpenClipboard",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      hMenu,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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


long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  BOOL  bOpened;

  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == 100)
        {
        MessageBox (NULL, (LPSTR)"Open a clipboard", (LPSTR)"OpenClipboard",
                    MB_OK);
        bOpened = OpenClipboard (hWnd);
        if (bOpened)
          MessageBox (NULL, (LPSTR)"Clipboard is open", (LPSTR)"OpenClipboard
                      MB_OK);
        else
          MessageBox (NULL, (LPSTR)"Clipboard is not open",
                     (LPSTR)"OpenClipboard", MB_OK);
        CloseClipboard ();
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


CLIPOWN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPOWN.C

/*
 *
 *  clipown.c
 *
 *  This program demonstrates the use of the GetClipboardOwner functions.
 *  This function retrieves the window handle of the current ower of clip-
 *  board.
 *
 */

#include <windows.h>

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;
  HMENU    hMenu;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = "clipown";

    if (!RegisterClass (&rClass))
      return FALSE;
    }
  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, (LPSTR)"Clipboard Owner", 100, MF_APPEND);

  hWnd = CreateWindow ("clipown",
                      "GetClipboardOwner",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      hMenu,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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


long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned  iMessage;
WORD     wParam;
LONG     lParam;
  {
  HWND  hClipWnd;

  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == 100)
        {
        MessageBox (NULL, (LPSTR)"Getting clipboard owner",
                    (LPSTR)"GetClipboardOwner", MB_OK);
        hClipWnd = GetClipboardOwner ();
        if (hClipWnd)
          MessageBox (NULL, (LPSTR)"Clipboard has an owner",
                     (LPSTR)"GetClipboardOwner", MB_OK);
        else
          MessageBox (NULL, (LPSTR)"Clipboard does not has an owner",
                     (LPSTR)"GetClipboardOwner", MB_OK);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


CLIPREG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPREG.C

/*
 *
 *  RegisterClipboardFormat
 *
 *  This program demonstrates the use of RegisterClipboardFormat function.
 *  This function registers a new clipboard format whose name is pointed to
 *  by a long pionter to a character string naming the new format. The
 *  registered format can be used in subsequent clipboard functions as valid
 *  format in which to render data, and it will appear in th clipboard's list
 *  of formats.
 */

/*************************************************************************/
/*                           INCLUDE FILES                               */
/*************************************************************************/

#include <windows.h>

/*************************************************************************/
/*                        STRUCTURE DEFINTIONS                           */
/*************************************************************************/

typedef struct
{
   int nDummy;
}
SETUPDATA;

/*************************************************************************/
/*                         GLOBAL VARIABLES                              */
/*************************************************************************/

static SETUPDATA strSetUpData;
static HANDLE hInst;
static char szFileName[] = "clipreg";
static char szFuncName[] = "RegisterClipboardFormat";

/*************************************************************************/
/*                       FORWARD REFERENCES                              */
/*************************************************************************/

long FAR PASCAL WindowProc ( HANDLE , unsigned , WORD , LONG );

/*************************************************************************/
/*                         MAIN PROCEDURE                                */
/*************************************************************************/

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  MSG  msg;

  WindowInit (hInstance, hPrevInstance, cmdShow );

  while ( GetMessage((LPMSG)&msg, NULL, 0 , 0 ))
    {
    TranslateMessage((LPMSG)&msg);
    DispatchMessage((LPMSG)&msg);
    }
  exit(msg.wParam);
}

/*************************************************************************/
/*                      INITIALIZATION                                   */
/*************************************************************************/

BOOL WindowInit (hInstance , hPrevInstance , cmdShow)
HANDLE hInstance, hPrevInstance;
int cmdShow;
{
  HWND  hWnd;

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.lpfnWndProc   = WindowProc;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;
     rClass.hInstance     = hInstance;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.lpszMenuName  = (LPSTR) NULL;
     rClass.lpszClassName = (LPSTR) szFileName;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }
  else
     GetInstanceData ( hPrevInstance, (PSTR) &strSetUpData,
        sizeof ( SETUPDATA ) );

  hInst = hInstance;

  hWnd = CreateWindow ( (LPSTR) szFileName, (LPSTR) szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      (HWND) NULL, (HMENU) NULL,
                      (HANDLE) hInstance, (LPSTR) NULL );

  ShowWindow ( hWnd , cmdShow );
  UpdateWindow (hWnd);

  return TRUE;
}

/*************************************************************************/
/*                 WINDOW PROCEDURE - PROCESS MESSAGES                   */
/*************************************************************************/

long FAR PASCAL WindowProc (hWnd , message , wParam , lParam)
HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint ( hWnd, (LPPAINTSTRUCT)&ps );
        FunctionDemonstrated ( hWnd );
        EndPaint ( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage ( 0 );
        break;

    default:
        return ( DefWindowProc ( hWnd , message , wParam , lParam ) );
        break;
    }
  return ( 0L );
}

/*************************************************************************/
/*              FUNCTION DEMONSTRATED HERE - LOOK HERE                   */
/*************************************************************************/

FunctionDemonstrated ( hWnd )
HWND hWnd;
{
  WORD wFormat;

  MessageBox (NULL, (LPSTR)"Register clipboard format", (LPSTR)szFuncName,
     MB_OK);

  wFormat = RegisterClipboardFormat ( (LPSTR)"format_name");

  if ( wFormat != 0 )
      MessageBox (NULL, (LPSTR)"Format registered", (LPSTR)szFuncName, MB_OK)
  else
      MessageBox (NULL, (LPSTR)"Format can not be registered",
         (LPSTR)szFuncName, MB_OK);

  return TRUE;
}


CLIPSET.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPSET.C

/*
 *
 *  SetClipboardData
 *
 *  This program demonstrates the use of the SetClipboardData function.
 *  This function sets a data handle into the clipboard for the data
 *  specified by the second parameter. The data is assumed to have the
 *  format specified by the frist parameter. After the clipboard data
 *  handle has been assigned, this function frees the block indentified
 *  by the second parameter.
 *
 */

#include <windows.h>

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);
int     strlen (char *);

LPSTR FAR PASCAL lstrcpy (LPSTR, LPSTR);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;
  HMENU    hMenu;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = "clipset";

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, (LPSTR)"Set Data", 100, MF_APPEND);

  hWnd = CreateWindow ("clipset",
                      "SetClipboardData",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      hMenu,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HANDLE hClipData;
  HANDLE hMem;
  LPSTR  lpText;

  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == 100)
        {
        OpenClipboard (hWnd);
        hMem = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT,
                           (long) strlen ("SetClipboardData"));
        lpText = (LPSTR) GlobalLock (hMem);
        lstrcpy (lpText, "SetClipboardData");
        EmptyClipboard ();
        MessageBox (hWnd, (LPSTR)"Setting handle to clipboard",
                    (LPSTR)"SetClipboardData", MB_OK);
        hClipData = SetClipboardData (CF_TEXT, hMem);
        if (hClipData != NULL)
          MessageBox (hWnd, (LPSTR)"Handle set", (LPSTR)"SetClipboardData",
                      MB_OK);
        else
          MessageBox (hWnd, (LPSTR)"Handle not set", (LPSTR)"SetClipboardData
                      MB_OK);
        CloseClipboard ();
        GlobalUnlock (hMem);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


CLIPVG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPVG.C

/*
 *
 *  GetClipboardViewer
 *
 *  clipvg.c
 *
 *  This program demonstrates the use of GetClipboardViewer function.
 *  This funtion retrieves the window handle of the first window in the
 *  clipboard viewer chain.
 *
 */

#include <windows.h>

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;
  HMENU    hMenu;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = "clipvg";

    if (!RegisterClass (&rClass))
      return FALSE;
    }
  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, (LPSTR)"Retrieve", 100, MF_APPEND);

  hWnd = CreateWindow ("clipvg",
                      "GetClipboardViewer",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      hMenu,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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


long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND       hWnd;
unsigned   iMessage;
WORD       wParam;
LONG       lParam;
  {
  HWND  hWndViewChain;

  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == 100)
        {
        SetClipboardViewer (hWnd);
        MessageBox (hWnd,
                    "Retreving frist window in clipboard viewer message chain
                    "GetClipboardViewer", MB_OK);
        hWndViewChain = GetClipboardViewer ();
        if (hWndViewChain)
          MessageBox (hWnd, "Got the frist window in the message chain",
                      "GetClipboardViewer", MB_OK);
        else
          MessageBox (hWnd, "No window in the message chain",
                      "GetClipboardViewer", MB_OK);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


CLIPVS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\CLIPVS.C

/*
 *
 *  SetClipboardViewer
 *
 *  clipvs.c
 *
 *  This program demonstrates the use of the SetClipboardViewer function.
 *  This function adds the window specified by handle to the window to the
 *  chain of windows that are notifed whenever the contents of the clipboard
 *  have changed.
 *
 */

#include <windows.h>

long    FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;
  HMENU    hMenu;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = (LPSTR) NULL;
    rClass.lpszClassName = (LPSTR) "clipvs";

    if (!RegisterClass (&rClass))
      return FALSE;
    }
  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, (LPSTR)"Add", 100, MF_APPEND);

  hWnd = CreateWindow ("clipvs",
                      "SetClipBoardViewer",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      hMenu,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HWND  hWndNext;

  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == 100)
        {
        MessageBox (NULL, (LPSTR)"Add window to clipboard message chain",
                   (LPSTR)"SetClipBoardViewer", MB_OK);
        hWndNext = SetClipboardViewer (hWnd);
        if (hWnd == GetClipboardViewer ())
          MessageBox (NULL, (LPSTR)"Window added the message chain",
                     (LPSTR)"SetClipBoardViewer", MB_OK);
        else
          MessageBox (NULL, (LPSTR)"Window not added the message chain",
                     (LPSTR)"SetClipBoardViewer", MB_OK);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


CLOSECOM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\CLOSECOM.C

/*
 *
 *  CloseComm
 *
 *  This program demonstrates the use of the function CloseComm.
 *  This function closes the communication device specified by the
 *  parameter and frees any memory allocated for the device's transmit
 *  and receive queues. All characters in the output queue are sent
 *  before the communication device is closed.
 *
 *  Other references: CFDial.c
 */

/*************************************************************************/
/*                           INCLUDE FILES                               */
/*************************************************************************/

#include <windows.h>

/*************************************************************************/
/*                        STRUCTURE DEFINTIONS                           */
/*************************************************************************/

typedef struct
{
   int nDummy;
}
SETUPDATA;

/*************************************************************************/
/*                         GLOBAL VARIABLES                              */
/*************************************************************************/

static SETUPDATA strSetUpData;
static HANDLE hInst;
static char szFileName[] = "closecom";
static char szFuncName[] = "CloseComm";

/*************************************************************************/
/*                       FORWARD REFERENCES                              */
/*************************************************************************/

long FAR PASCAL WindowProc ( HANDLE , unsigned , WORD , LONG );

/*************************************************************************/
/*                         MAIN PROCEDURE                                */
/*************************************************************************/

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  MSG  msg;

  WindowInit (hInstance, hPrevInstance, cmdShow );

  while ( GetMessage((LPMSG)&msg, NULL, 0 , 0 ))
    {
    TranslateMessage((LPMSG)&msg);
    DispatchMessage((LPMSG)&msg);
    }
  exit(msg.wParam);
}

/*************************************************************************/
/*                      INITIALIZATION                                   */
/*************************************************************************/

BOOL WindowInit (hInstance , hPrevInstance , cmdShow)
HANDLE hInstance, hPrevInstance;
int cmdShow;
{
  HWND  hWnd;

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.lpfnWndProc   = WindowProc;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;
     rClass.hInstance     = hInstance;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.lpszMenuName  = (LPSTR) NULL;
     rClass.lpszClassName = (LPSTR) szFileName;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }
  else
     GetInstanceData ( hPrevInstance, (PSTR) &strSetUpData,
        sizeof ( SETUPDATA ) );

  hInst = hInstance;

  hWnd = CreateWindow ( (LPSTR) szFileName, (LPSTR) szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      (HWND) NULL, (HMENU) NULL,
                      (HANDLE) hInstance, (LPSTR) NULL );

  ShowWindow ( hWnd , cmdShow );
  UpdateWindow (hWnd);

  return TRUE;
}

/*************************************************************************/
/*                 WINDOW PROCEDURE - PROCESS MESSAGES                   */
/*************************************************************************/

long FAR PASCAL WindowProc (hWnd , message , wParam , lParam)
HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint ( hWnd, (LPPAINTSTRUCT)&ps );
        FunctionDemonstrated ( );
        EndPaint ( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage ( 0 );
        break;

    default:
        return ( DefWindowProc ( hWnd , message , wParam , lParam ) );
        break;
    }
  return ( 0L );
}

/*************************************************************************/
/*              FUNCTION DEMONSTRATED HERE - LOOK HERE                   */
/*************************************************************************/

FunctionDemonstrated ( )
{
  int nCid;
  int nResult;

  nCid = OpenComm ( ( LPSTR ) "LPT1", 255, 256 );

  MessageBox ( NULL, ( LPSTR ) "Closing LPT1", ( LPSTR ) szFuncName, MB_OK );

  nResult = CloseComm ( nCid );

  if ( nResult == 0 )
     MessageBox (NULL, (LPSTR)"LPT1 closed", (LPSTR)szFuncName, MB_OK);
  else
     MessageBox (NULL, (LPSTR)"LPT1 not closed", (LPSTR)szFuncName, MB_OK);

  return TRUE;
}


CLOSESND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SOUND\CLOSESND.C

/*
 *  Function Name:   CloseSound
 *  Program Name:    CloseSnd.c
 *
 *  Description:
 *   CloseSound closes access to the play device and frees the device for
 *   opening by other applications.  the CloseSound function flushes all
 *   voice queues and frees any buffers allocated for these queues.
 */

#include "windows.h"
#include "stdio.h"

long  FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_CloseSound (hWnd)
HWND hWnd;

{
  char  szBuffer[30];
  short  nVoices; /* Specifies the number of voices available. */

  nVoices = OpenSound (); /* Opens access to play device, locks it from  */
/* further users, returns the number of voices */
/* available.                                  */

  if (nVoices == S_SERDVNA)
    MessageBox (NULL, (LPSTR) "Play device in use.", (LPSTR) "Error", MB_OK);
  else if (nVoices == S_SEROFM)
    MessageBox (NULL, (LPSTR) "Insufficient memory available.",
        (LPSTR) "Error\0", MB_OK);
  else
  {
    sprintf (szBuffer, "%d voice (s) are available.", nVoices);
    MessageBox (NULL, (LPSTR) szBuffer,
        (LPSTR)"Mission Accomplished\0", MB_OK);

    CloseSound ();    /* Closesnd closes the play device, allowing other */
/* applications to use the device.                 */
  }
  if ( (nVoices != S_SEROFM) && (nVoices != S_SERDVNA))
  {
    MessageBox (NULL, (LPSTR)"CloseSound complete, device available.",
        (LPSTR)"Mission Accomplished\0", MB_OK);
  }
  else
  {
    MessageBox (NULL, (LPSTR)"Device unavailable, try later",
        (LPSTR)"Mission Failed", MB_OK);

  }

  return;
}


/**************************************************************************/

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  CALL_CloseSound (hWnd);
  return 0;
}




CLOSEWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\CLOSEWIN.C

/*
 *
 * Function (s) demonstrated in this program: CloseWindow
 *
 * Description:  This function makes a window iconic
 *
 */

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "CloseWin.h"

HWND     hWndMain;
HANDLE   hInstMain;

char  szOutputBuffer1 [70];
char  szOutputBuffer2 [500];

struct   {
  char  *szMessage;
  } Messages [] =   {
  "About\0",
  "     This is a sample application to demonstrate the\n\
use of the CloseWindow Windows function.",

  "Help Message",
  "     This program uses the CloseWindow Windows\n\
function to minimize this window, the window is\n\
then restored to its original state.  Use the menu\n\
to test this function.",

  };

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
HWND     hWnd;
int  MessageNumber;
  {
  sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
  sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
  MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
  }

/****************************************************************************

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int     nCmdShow;
  {
  static char   szAppName [] = "CloseWin";
  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG msg;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = szAppName;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

hWndMain = CreateWindow (szAppName,        /* window class name       */
                        "CloseWindow",              /* window caption
                        WS_OVERLAPPEDWINDOW,        /* window style
                        CW_USEDEFAULT,              /* initial x position
                        0,                          /* initial y position
                        CW_USEDEFAULT,              /* initial x size
                        0,                          /* initial y size
                        NULL,                       /* parent window handle
                        NULL,                       /* window menu handle
                        hInstance,                  /* program instance handl
                        NULL);                     /* create parameters

  ShowWindow (hWndMain, nCmdShow);
  UpdateWindow (hWndMain);

  hInstMain = hInstance;

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

/****************************************************************************

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HMENU       hMenu;

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = GetSystemMenu (hWnd, FALSE);
      ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT, MF_APPEND | MF_STRING);
      break;

    case WM_SYSCOMMAND:
      switch (wParam)
        {
        case IDM_ABOUT:
          ProcessMessage (hWnd, 0);
          break;
        default:
          return DefWindowProc (hWnd, iMessage, wParam, lParam);
        }
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_CLOSEWINDOW:
          MessageBox (hWnd, "About to Use CloseWindow", "CloseWindow", MB_OK)
          CloseWindow (hWnd);
          MessageBox (hWnd, "Restoring window to original state",
                      "CloseWindow", MB_OK);
          SendMessage (hWnd, WM_SYSCOMMAND, SC_RESTORE, 0L);
          break;

        case IDM_HELP:
          ProcessMessage (hWnd, 2);
          break;
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


CMETAFIL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\CMETAFIL.C

/*
 *  This program demonstrates the use of the function CloseMetaFile.
 *  This function closes the metafile DC and creates a metafile handle
 *  that can be used to play the metafile using PlayMetaFile.
 *
 */

#include <windows.h>

long  FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

static char  szAppName[] = "cmetafil";
static char  szFuncName[] = "CloseMetaFile";

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
{
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;

  if (!hPrevInstance)
  {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = szAppName;

    if (!RegisterClass (&rClass))
      return TRUE;
  }

hWnd = CreateWindow (szAppName,            /* window class name       */
szFuncName,                 /* window caption          */
WS_OVERLAPPEDWINDOW,        /* window style            */
CW_USEDEFAULT,              /* initial x position      */
0,                          /* initial y position      */
CW_USEDEFAULT,              /* initial x size          */
0,                          /* initial y size          */
NULL,                       /* parent window handle    */
NULL,                       /* window menu handle      */
hInstance,                  /* program instance handle */
  NULL);                      /* create parameters       */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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


long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned  iMessage;
WORD     wParam;
LONG     lParam;
{
  HANDLE hMF;
  HDC    hDCMeta;
  HDC    hDC;
  HMENU  hMenu;
  BOOL   bPlayed;

  switch (iMessage)
  {
  case WM_CREATE:
    hMenu = CreateMenu ();
    ChangeMenu (hMenu, NULL, (LPSTR)"Play", 100, MF_APPEND);
    SetMenu (hWnd, hMenu);
    break;
  case WM_INITMENU:
    InvalidateRect (hWnd, NULL, TRUE);
    break;
  case WM_COMMAND:
    if (wParam == 100)
    {
      hDC = GetDC (hWnd);
      hDCMeta = CreateMetaFile ((LPSTR)"CMETAFIL.MET");
      Rectangle (hDCMeta, 10, 10, 600, 200);
      Arc (hDCMeta, 10, 10, 600, 200, 10, 15, 600, 150);
      MessageBox (GetFocus(), (LPSTR)"Creating handle to metafile",
          (LPSTR) szFuncName, MB_OK);
      hMF = CloseMetaFile (hDCMeta);
      if (hMF != NULL)
      {
  MessageBox (GetFocus(), (LPSTR)"Metafile handle created",
      (LPSTR) szFuncName, MB_OK);
  bPlayed = PlayMetaFile (hDC, hMF);
  MessageBox (GetFocus(), (LPSTR)"This is the metafile",
      (LPSTR) szFuncName, MB_OK);
      }
      else
  MessageBox (GetFocus(), (LPSTR)"Metafile handle not created",
      (LPSTR) szFuncName, MB_OK);
      DeleteMetaFile (hMF);
      ReleaseDC (hWnd, hDC);
    }
    break;
  case WM_DESTROY:
    PostQuitMessage (0);
    break;
  default:
    return DefWindowProc (hWnd, iMessage, wParam, lParam);
  }
  return (0L);
}




COPYRECT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\COPYRECT.C

/*
 * Function (s) demonstrated in this program: CopyRect
 *
 * Description:  This function copies the contents of one rectangle structure
 *     into another.
 *
 */

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <math.h>

char  szRadius  [15];
HANDLE  hInstMain;
HWND    hWndMain;

long FAR PASCAL WndProc                (HWND, unsigned, WORD, LONG);
void            DrawSquare             (HDC, RECT);

/****************************************************************************

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE  hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  nCmdShow;
  {
  static char  szAppName[] = "CopyRect";
  HWND  hWnd;
  MSG   msg;
  WNDCLASS  wndclass;

  if (!hPrevInstance)
    {
    wndclass.style          = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc    = WndProc;
    wndclass.cbClsExtra     = 0;
    wndclass.cbWndExtra     = 0;
    wndclass.hInstance      = hInstance;
    wndclass.hIcon          = NULL; /*LoadIcon (NULL, IDI_ASTERISK);*/
    wndclass.hCursor        = LoadCursor (NULL, IDC_CROSS);
    wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName   = NULL;
    wndclass.lpszClassName  = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }
  hWnd = CreateWindow (szAppName, "CopyRect",
                      WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0, NULL, NULL,
                      hInstance, NULL);

  hInstMain = hInstance;
  hWndMain  = hWnd;

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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


/****************************************************************************

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND      hWnd;
unsigned    iMessage;
WORD      wParam;
LONG      lParam;
  {
  static RECT   Rect1, Rect2;
  HDC          hDC;
  PAINTSTRUCT   ps;
  int   xOffset, yOffset;

  switch (iMessage)
    {
    case WM_CREATE:
      SetRectEmpty (&Rect1);
      SetRectEmpty (&Rect2);

      Rect1.top = 10;
      Rect1.left = 15;
      Rect1.right = 30;
      Rect1.bottom = 20;
      break;

    case WM_PAINT:
      SetRectEmpty (&Rect1);
      SetRectEmpty (&Rect2);
      Rect1.top = 10;
      Rect1.left = 15;
      Rect1.right = 30;
      Rect1.bottom = 20;

      hDC = BeginPaint (hWnd, &ps);
      CopyRect (&Rect2, &Rect1);      /*  Copy the contents of Rect1
                                       *  to Rect2  */

      for (xOffset = 0; xOffset < 15; xOffset++)
        {
        Rect1.top += 10;
        Rect1.left += 15;
        Rect1.bottom += 11;
        Rect1.right += 17;
        DrawSquare (hDC, Rect1);
        }
      DrawSquare (hDC, Rect2);
      EndPaint (hWnd, &ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return 0L;
  }


/***************************************************************************/

void DrawSquare (hDC, rect)
HDC       hDC;
RECT      rect;
  {
  MoveTo (hDC, rect.left,  rect.top);
  LineTo (hDC, rect.right, rect.top);
  LineTo (hDC, rect.right, rect.bottom);
  LineTo (hDC, rect.left,  rect.bottom);
  LineTo (hDC, rect.left,  rect.top);
  }


CPMETAFI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\CPMETAFI.C

/*
 *  CopyMetaFile
 *  This program demonstrates the use of the function CopyMetaFile.
 *  This function copied the source metafile to the file named by second
 *  parameter and returns a handle to the new metafile.
 */

#include <windows.h>

static HANDLE hWnd;

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE  hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int  cmdShow;
  {
  static char  szFuncName[] = "CopyMetaFile";
  HANDLE hMF;
  HANDLE hMF2;

  hMF = GetMetaFile ( (LPSTR) "CPMETAFI.MET");

  MessageBox (NULL, (LPSTR)"Coping metafile", (LPSTR) szFuncName, MB_OK);

  hMF2 = CopyMetaFile (hMF, (LPSTR) "METAFILE");

  if (hMF2 != NULL)
    MessageBox (NULL, (LPSTR)"Copied", (LPSTR) szFuncName, MB_OK);
  else
    MessageBox (NULL, (LPSTR)"Not copied", (LPSTR) szFuncName, MB_OK);

  return 0;
  }


CRBITMAP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRBITMAP.C

#include <windows.h>
#include "crbitmap.h"

HANDLE hInst;
HBITMAP hBitmap;                    /* bitmap structure handle */

short nBlobBitmap[] = {
        0x0000, 0x0000,
        0x0000, 0x0000,
        0x000f, 0xf000,
        0x000f, 0xf000,
        0x00ff, 0xff00,
        0x00ff, 0xff00,
        0x0fff, 0xfff0,
        0x0fff, 0xfff0,
        0x0ff0, 0x0ff0,
        0x0ff0, 0x0ff0,
        0xfff0, 0x0fff,
        0xfff0, 0x0fff,
        0xff00, 0x00ff,
        0xff00, 0x00ff,
        0xffff, 0xffff,
        0xffff, 0xffff};

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;       /* current instance */
HANDLE hPrevInstance;   /* previous instance */
LPSTR lpCmdLine;        /* command line */
int nCmdShow;           /* show window type (open/icon) */
{
    HWND hWnd;          /* window handle */
    MSG msg;            /* message */
    HMENU hMenu;        /* handle to the menu */

    if  (!hPrevInstance)        /* app already initialized? */
        if (!CreateBitMapInit(hInstance))       /* nope, init it */
            return(NULL);               /* couldn't init */

    hInst = hInstance;          /* store the current instance */

    hWnd = CreateWindow("CreateBitMap", /* window class */
        "CreateBitMap Sample Application",      /* window name */
        WS_OVERLAPPEDWINDOW,            /* window style */
        CW_USEDEFAULT,                  /* x position */
        CW_USEDEFAULT,                  /* y position */
        CW_USEDEFAULT,                  /* width */
        CW_USEDEFAULT,                  /* height */
        NULL,                           /* parent handle */
        NULL,                           /* menu or child */
        hInstance,                      /* instance */
        NULL);                          /* additional info */

    if (!hWnd)                  /* did we get a valid handle? */
        return(NULL);           /* nope, couldn't open window */

    ShowWindow(hWnd, nCmdShow);         /* show the window */
    UpdateWindow(hWnd);                 /* send the WM_PAINT msg */

    while (GetMessage(&msg, NULL, NULL, NULL))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return(msg.wParam);         /* return value from PostQuitMessage */
}

/* register the window */
BOOL CreateBitMapInit(hInstance)
HANDLE hInstance; /* current instance */
{
    HANDLE hMemory;             /* handle to allocated memory */
    PWNDCLASS pWndClass;        /* structure pointer */
    BOOL bSuccess;              /* saves RegisterClass status */

    hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
    pWndClass = (PWNDCLASS) LocalLock(hMemory);

    pWndClass->lpszClassName = (LPSTR)  "CreateBitMap";
    pWndClass->hInstance = hInstance;
    pWndClass->lpfnWndProc = CreateBitMapWndProc;
    pWndClass->style = NULL;
    pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
    pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION);
    pWndClass->lpszMenuName = (LPSTR) NULL;

    bSuccess = RegisterClass(pWndClass);

    LocalUnlock(hMemory);               /* unlock the memory */
    LocalFree(hMemory);                 /* return it to windows */

    return (bSuccess);
}

/* process messages to the window */

long FAR PASCAL CreateBitMapWndProc(hWnd, message, wParam, lParam)
HWND hWnd;                              /* window handle */
unsigned message;                       /* type of message */
WORD wParam;                            /* additional information */
LONG lParam;                            /* additional information */
{
    FARPROC lpProcAbout;                /* pointer to "About" procedure */
    HMENU hMenu;                        /* menu handle */
    HDC hMemoryDC;                      /* memory device context */
    HDC hDC;                            /* display device context */
    HANDLE hOldObject;                  /* return code from SelectObject */

    switch (message)
    {
        case WM_CREATE :                /* add command to system menu */
            hMenu = GetSystemMenu(hWnd, FALSE);
            ChangeMenu(hMenu, NULL, NULL, NULL,
                MF_APPEND | MF_SEPARATOR);
            ChangeMenu(hMenu, NULL, "A&bout CreateBitMap...",
            ID_ABOUT, MF_APPEND | MF_STRING);
            /* create bitmap */
            hBitmap = CreateBitmap(32, 16, 1, 1, (LPSTR)nBlobBitmap);
            if (hBitmap == NULL)
                MessageBox(NULL, (LPSTR)"Error creating Bitmap",
                           NULL, IDOK);
            break;

        case WM_SYSCOMMAND :
            switch (wParam)
            {
                case ID_ABOUT:
                    lpProcAbout = MakeProcInstance(About, hInst);
                    DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);
                    FreeProcInstance(lpProcAbout);
                    break;

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

        case WM_PAINT:
            hDC = GetDC(hWnd);
            hMemoryDC = CreateCompatibleDC(hDC);
            hOldObject = SelectObject(hMemoryDC, hBitmap);
            if (hOldObject == NULL)
                MessageBox(NULL, (LPSTR)"Error selecting object",
                           NULL, IDOK);
            BitBlt(hDC, 50, 30, 32, 16, hMemoryDC, 0, 0, SRCCOPY);
            /* clean up */
            SelectObject(hMemoryDC, hOldObject);
            DeleteDC(hMemoryDC);
            ReleaseDC(hWnd, hDC);
            break;

        case WM_DESTROY:                /* quit application */
      DeleteObject(hBitmap);  /* delete bitmap */
            PostQuitMessage(NULL);      /* notify windows */
            break;

        default:                        /* pass it on if unprocessed */
            return(DefWindowProc(hWnd, message, wParam, lParam));
    }
    return(NULL);
}

/* this function handles the "About" box */

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;                       /* type of message */
WORD wParam;                            /* additional information */
LONG lParam;                            /* additional information */
{
    switch (message)
    {
        case WM_INITDIALOG:             /* init dialog box */
            return(TRUE);               /* don't need to do anything */
        case WM_COMMAND:                /* received a command */
            if (wParam == IDOK)         /* OK box selected? */
            {
                EndDialog (hDlg, NULL);         /* then exit */
                return(TRUE);
            }
            break;
    }
    return(FALSE);                      /* didn't process a message */
}


CRCARET.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CARET\CRCARET.C

/*
 *  This program will demonstrate the use of the CreateCaret function.
 *  It will define a new shape for the system caret and give ownership
 *  of the system caret to the current window.
 *
 */

#include <windows.h>
#include "crcaret.h"

HANDLE hInst;

int     PASCAL WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE  hInstance;
HANDLE  hPrevInstance;
LPSTR   lpCmdLine;
int     nCmdShow;
  {
  HWND hWnd;    /* window handle */
  MSG msg;      /* message */
  HMENU hMenu;  /* handle to the menu */

  if (!hPrevInstance)   /* app already initialized? */
    if (!CrCaretInit (hInstance))        /* nope, init it */
      return (NULL);             /* couldn't init */

  hInst = hInstance;    /* store the current instance */

  hWnd = CreateWindow ("CrCaret",  /* window class */
                      "CreateCaret Sample Application", /* window name */
                      WS_OVERLAPPEDWINDOW,              /* window style */
                      CW_USEDEFAULT,                    /* x position */
                      CW_USEDEFAULT,                    /* y position */
                      CW_USEDEFAULT,                    /* width */
                      CW_USEDEFAULT,                    /* height */
                      NULL,                             /* parent handle */
                      NULL,                             /* menu or child */
                      hInstance,                        /* instance */
                      NULL);                            /* additional info */

  if (!hWnd)
    return (NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

  while (GetMessage (&msg, NULL, NULL, NULL))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return (msg.wParam);
  }

/* register the window */
BOOL CrCaretInit (hInstance)
HANDLE hInstance; /* current instance */
  {
  HANDLE hMemory;
  PWNDCLASS pWndClass;
  BOOL bSuccess;

  hMemory = LocalAlloc (LPTR, sizeof (WNDCLASS));
  pWndClass = (PWNDCLASS) LocalLock (hMemory);

  pWndClass->lpszClassName = (LPSTR)  "CrCaret";
  pWndClass->hInstance = hInstance;
  pWndClass->lpfnWndProc = CrCaretWndProc;
  pWndClass->style = NULL;
  pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  pWndClass->hCursor = LoadCursor (NULL, IDC_ARROW);
  pWndClass->hIcon = LoadIcon (NULL, IDI_APPLICATION);
  pWndClass->lpszMenuName = (LPSTR) NULL;

  bSuccess = RegisterClass (pWndClass);

  LocalUnlock (hMemory);
  LocalFree (hMemory);

  return (bSuccess);
  }


/* process messages to the window */

long    FAR PASCAL CrCaretWndProc (hWnd, message, wParam, lParam)
HWND hWnd;        /* window handle */
unsigned  message;      /* type of message */
WORD wParam;        /* additional information */
LONG lParam;        /* additional information */
  {
  FARPROC lpProcAbout;    /* pointer to "About" procedure */
  HMENU hMenu;      /* menu handle */

  switch (message)
    {
    case WM_CREATE :
          /* add command to system menu */
      hMenu = GetSystemMenu (hWnd, FALSE);
      ChangeMenu (hMenu, NULL, NULL, NULL, MF_APPEND | MF_SEPARATOR);
      ChangeMenu (hMenu, NULL, "A&bout CreateCaret...",
                  ID_ABOUT, MF_APPEND | MF_STRING);
      break;

    case WM_SYSCOMMAND :
      switch (wParam)
        {
        case ID_ABOUT:
          lpProcAbout = MakeProcInstance (About, hInst);
          DialogBox (hInst, "AboutBox", hWnd, lpProcAbout);
          FreeProcInstance (lpProcAbout);
          break;

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

    case WM_SETFOCUS:             /* create and show caret */
      CreateCaret (hWnd, NULL, 0, 5);
      SetCaretPos (20, 20);
      ShowCaret (hWnd);
      break;

    case WM_KILLFOCUS:            /* destroy the caret */
      DestroyCaret ();
      break;

    case WM_DESTROY:              /* quit application */
      PostQuitMessage (NULL);      /* notify windows */
      break;

    default:                      /* pass it on if unprocessed */
      return (DefWindowProc (hWnd, message, wParam, lParam));
    }
  return (NULL);
  }


/* this function handles the "About" box */

BOOL FAR PASCAL About (hDlg, message, wParam, lParam)
HWND hDlg;
unsigned  message;      /* type of message */
WORD wParam;        /* additional information */
LONG lParam;        /* additional information */
  {
  switch (message)
    {
    case WM_INITDIALOG:           /* init dialog box */
      return (TRUE);               /* don't need to do anything */
    case WM_COMMAND:              /* received a command */
      if (wParam == IDOK)         /* OK box selected? */
        {
        EndDialog (hDlg, NULL);           /* then exit */
        return (TRUE);
        }
      break;
    }
  return (FALSE);                        /* didn't process a message */
  }


CRDIAIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\CRDIAIN.C

/*
 *
 *  CreateDialogIndirect
 *
 *  This program demonstrates the use of the function CreateDialogIndirect.
 *  It allows a user to create a modeless dialogbox on the fly. Memory for th
 *  structure is dynamcally allocated to conform to variable string lengths.
 */

#include <windows.h>
#include "crdiain.h"

BOOL FAR PASCAL InitDiabox (HANDLE, HANDLE, int);
long  FAR PASCAL DiaboxWindowProc (HANDLE, unsigned, WORD, LONG);
BOOL FAR PASCAL DialogBoxWindowProc (HANDLE, unsigned, WORD, LONG);

HANDLE hInst;
FARPROC lpDlgTest;
HWND hDlgTest;

typedef struct dtHdrType {
  LONG  dtStyle;
  BYTE  dtItemCount;
  int  dtX;
  int  dtY;
  int  dtCX;
  int  dtCY;
  char  dtResourceName[1];
  char  dtClassName[1];
  char  dtCaptionText[1];
} DTHDR;

typedef struct dtItmType {
  int  dtilX;
  int  dtilY;
  int  dtilCX;
  int  dtilCY;
  int  dtilID;
  LONG  dtilWindowStyle;
  BYTE  dtilControlClass;
  char  dtilText[1];
} DTITM;


/**************************************************************************/

int  PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE  hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int  cmdShow;
{
  MSG  msg;

  InitDiabox (hInstance, hPrevInstance, cmdShow);
  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
  {
    if ( (hDlgTest == NULL) || !IsDialogMessage (hDlgTest, (LPMSG) & msg))
    {
      TranslateMessage ( (LPMSG) & msg);
      DispatchMessage ( (LPMSG) & msg);
    }
  }
  exit (msg.wParam);
}


/*******************************   initialization   ***********************/

BOOL FAR PASCAL InitDiabox (hInstance, hPrevInstance, cmdShow)
HANDLE  hInstance;
HANDLE  hPrevInstance;
int  cmdShow;
{
  WNDCLASS  wcDiaboxClass;
  HWND  hWnd;

  wcDiaboxClass.lpszClassName = (LPSTR) "Diabox";
  wcDiaboxClass.hInstance     = hInstance;
  wcDiaboxClass.lpfnWndProc   = DiaboxWindowProc;
  wcDiaboxClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcDiaboxClass.hIcon         = NULL;
  wcDiaboxClass.lpszMenuName  = (LPSTR) "diabox";
  wcDiaboxClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcDiaboxClass.style         = CS_HREDRAW | CS_VREDRAW;
  wcDiaboxClass.cbClsExtra    = 0;
  wcDiaboxClass.cbWndExtra    = 0;

  RegisterClass ( (LPWNDCLASS) & wcDiaboxClass);
  hWnd = CreateWindow ( (LPSTR) "Diabox",
      (LPSTR) "CreateDialogIndirect",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,
      (HMENU)NULL,
      (HANDLE)hInstance,
      (LPSTR)NULL);

  hInst = hInstance;                    /*  instance saved for dialog box  */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
}


/*********************   window procedure - process messages   *************/

long  FAR PASCAL DiaboxWindowProc (hWnd, message, wParam, lParam)
HWND        hWnd;
unsigned  message;
WORD        wParam;
LONG        lParam;
{
  switch (message)
  {
  case WM_COMMAND:
    switch (wParam)
    {
    case IDDBOX:
      DisplayDialogBox (hWnd);
      break;
    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }

  case WM_DESTROY:
    PostQuitMessage (0);
    break;

  default:
    return (DefWindowProc (hWnd, message, wParam, lParam));
    break;
  }
  return (0L);
}


/***************************************************************************/

DisplayDialogBox (hWnd)
HWND   hWnd;
{
  DTHDR    dtHdr;
  DTITM    dtItm;
  HANDLE   hDTemplate;
  LPSTR    lpDTemplate;
  WORD     wByteCount;
  BYTE     work[256];

  if (hDlgTest != NULL)
    return (FALSE);

  if (!(hDTemplate = GlobalAlloc (GMEM_MOVEABLE, (DWORD) sizeof (DTHDR))))
    return (FALSE);
  wByteCount = 0;

  dtHdr.dtStyle     = WS_POPUP | WS_VISIBLE | WS_BORDER | WS_CAPTION;
  dtHdr.dtItemCount = 2;
  dtHdr.dtX         = 10;
  dtHdr.dtY         = 10;
  dtHdr.dtCX        = 200;
  dtHdr.dtCY        = 100;
  dtHdr.dtResourceName[0] = 0;
  dtHdr.dtClassName[0]    = 0;
  if (!writeGMem (hDTemplate, wByteCount, (BYTE * ) & dtHdr, sizeof (DTHDR) -
    return (FALSE);
  wByteCount += sizeof (DTHDR) - 1;

  strcpy (work, "Howdy !!!");
  if (!writeGMem (hDTemplate, wByteCount, work, strlen (work) + 1))
    return (FALSE);
  wByteCount += strlen (work) + 1;

/* add BUTTON item */

  dtItm.dtilX     = 30;
  dtItm.dtilY     = 50;
  dtItm.dtilCX    = 32;
  dtItm.dtilCY    = 12;
  dtItm.dtilID    = 0x0200;
  dtItm.dtilWindowStyle = BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD | WS_VISIB
  dtItm.dtilControlClass = 0x80;
  if (!writeGMem (hDTemplate, wByteCount, (BYTE * ) & dtItm, sizeof (DTITM) -
    return (FALSE);
  wByteCount += sizeof (DTITM) - 1;

  strcpy (work, "OK");
  if (!writeGMem (hDTemplate, wByteCount, work, strlen (work) + 1))
    return (FALSE);
  wByteCount += strlen (work) + 1;

  work[0] = 0;
  if (!writeGMem (hDTemplate, wByteCount, work, 1))
    return (FALSE);
  wByteCount += 1;

/* add MESSAGE item */

  dtItm.dtilX     = 30;
  dtItm.dtilY     = 20;
  dtItm.dtilCX    = 100;
  dtItm.dtilCY    = 8;
  dtItm.dtilID    = 0x0100;
  dtItm.dtilWindowStyle = SS_LEFT | WS_CHILD | WS_VISIBLE;
  dtItm.dtilControlClass = 0x82;
  if (!writeGMem (hDTemplate, wByteCount, (BYTE * ) & dtItm, sizeof (DTITM) -
    return (FALSE);
  wByteCount += sizeof (DTITM) - 1;

  strcpy (work, "Modeless DialogBox");
  if (!writeGMem (hDTemplate, wByteCount, work, strlen (work) + 1))
    return (FALSE);
  wByteCount += strlen (work) + 1;

  work[0] = 0;
  if (!writeGMem (hDTemplate, wByteCount, work, 1))
    return (FALSE);

  lpDlgTest = MakeProcInstance ( (FARPROC) DialogBoxWindowProc, hInst);

  lpDTemplate = GlobalLock (hDTemplate);
/*  function demonstrated  */
  hDlgTest = CreateDialogIndirect (hInst, lpDTemplate, hWnd, lpDlgTest);

  if (hDlgTest == -1)
    MessageBox (NULL, (LPSTR)"CreateDialogIndirect failed",
        (LPSTR)"error", MB_ICONHAND);
  GlobalUnlock (hDTemplate);

  return (TRUE);
}


/**************************************************************************/

BOOL FAR PASCAL DialogBoxWindowProc (hDlg, message, wParam, lParam)
HWND      hDlg;
unsigned  message;
WORD      wParam;
LONG      lParam;
{
  switch (message)
  {
  case WM_COMMAND:
    switch (wParam)
    {
    case 0x0100:
    case 0x0200:
      break;
    default:
      return (TRUE);
    }
    break;
  default:
    return (FALSE);
  }

  DestroyWindow (hDlgTest);
  hDlgTest = NULL;
  return (TRUE);
}


/****************************************************************************

BOOL NEAR writeGMem (hData, offset, data, length)
HANDLE  hData;
WORD    offset;
BYTE    *data;
WORD    length;
{
  HANDLE  hNewData;
  LPSTR   lpDstData;
  int  n;

  if (offset + length > GlobalSize (hData))
  {
    if (!(hNewData = GlobalReAlloc (hData, (DWORD) offset + length, GMEM_MOVE
      GlobalFree (hData);

    hData = hNewData;
  }

  if (lpDstData = GlobalLock (hData))
  {
    lpDstData = lpDstData + offset;
    for (n = 0; n < length; n++)
      *lpDstData++ = *data++;
    GlobalUnlock (hData);
    return (TRUE);
  }

  return (FALSE);
}




CRDISBIT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRDISBIT.C

/*
 *  CreateDiscardableBitmap
 */

#include "windows.h"

static HWND  hWnd;
static RECT  rect;

void    ExecuteTest ();

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance;
HANDLE    hPrevInstance;
LPSTR    lpszCmdLine;
int  cmdShow;
{
  MSG  msg;

  if (!hPrevInstance)
  {
/* ensure that windows know where to find parts of this
     * task on disk by Registering a window class.  Registering
                 * a class binds an executable name to an internal name,
     * known to Windows. */
    WNDCLASS  rClass;

    rClass.lpszClassName         = (LPSTR)"CreateDiscardableBitmap";
    rClass.hInstance   = hInstance;
    rClass.lpfnWndProc   = DefWindowProc;
    rClass.hCursor               = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon                 = LoadIcon (hInstance, (LPSTR)"CreateDiscard
    rClass.lpszMenuName  = (LPSTR) NULL;
    rClass.hbrBackground         = GetStockObject (WHITE_BRUSH);
    rClass.style     = CS_HREDRAW | CS_VREDRAW;
    rClass.cbClsExtra   = 0;
    rClass.cbWndExtra   = 0;

    RegisterClass ( (LPWNDCLASS) & rClass);
  } /* end if this is the 1st task/instance of this program */

  hWnd = CreateWindow ( (LPSTR) "CreateDiscardableBitmap", /* Window class na
  (LPSTR) "CreateDiscardableBitmap", /* Window title */
  WS_OVERLAPPEDWINDOW,
    /* stlye -- WIN 2.x or later */
CW_USEDEFAULT,  /* x -  WIN 2.x or later */
CW_USEDEFAULT,  /* y -  WIN 2.x or later */
CW_USEDEFAULT,  /* cx - WIN 2.x or later */
CW_USEDEFAULT,  /* cy - WIN 2.x or later */
  (HWND)NULL,   /* No parent */
  (HMENU)NULL,  /* Use the class menu */
  (HANDLE)hInstance, /* .EXE file for Class */
  (LPSTR)NULL   /* No Params */
  );
  ShowWindow (hWnd, cmdShow);     /* Allocate room for window     */
  UpdateWindow (hWnd);            /* Paint the client area        */

  MessageBox (hWnd, (LPSTR) "Beginning Test", (LPSTR) " ", MB_OK);

/* The actual test of the CreateDiscardableBitmap function  */
  ExecuteTest (hWnd);

  MessageBox (hWnd, (LPSTR) "Demonstration Finished", (LPSTR) " ", MB_OK);
  return 0L;
} /* WINMAIN */


/****************************************************************************
/* This is the function to test CreateDiscardableBitmap Function.         */

void ExecuteTest (hWnd)
HWND hWnd;
{
  HDC    hDC;
  HDC    hMemoryDC;        /* handle to In-memory display Context */
  HBITMAP   hBitmap;          /* handle to Bitmap  */
  HBITMAP   hOldBitmap;
  BITMAP  bm;            /* copy of bitmap    */
  short  xStart;
  short  yStart;
  POINT    pt;            /* structure of x-y coordinates */

/* prepare and create bitmap  */
  hDC = GetDC (hWnd);
  hMemoryDC = CreateCompatibleDC (hDC);
  hBitmap = CreateDiscardableBitmap (hDC, 64, 32);
  hOldBitmap = SelectObject (hMemoryDC, hBitmap);

/* Color with Black  */
  PatBlt (hMemoryDC, 0, 0, 64, 32, BLACKNESS);

  GetObject (hBitmap, sizeof (BITMAP), (LPSTR) & bm);
  pt.x = bm.bmWidth;
  pt.y = bm.bmHeight;
  DPtoLP (hDC, &pt, 1);          /* convert to logical units for GDI */

  xStart = yStart = 0;

/* Copy to the Display Context  */
  BitBlt (hDC, xStart, yStart, pt.x, pt.y, hMemoryDC, 0, 0, SRCCOPY);

/* Discard objects and free up memory */
  DeleteDC (hMemoryDC);
  ReleaseDC (hWnd, hDC);
  return;
} /* END EXECUTETEST */


/* END DISCARD.C */


CREATBRI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CREATBRI.C

/*
 *   This program demonstrates the use of the CreateBrushIndirect () function
 *   CreateBrushIndirect () returns a handle to a brush with characteristics
 *   described by a LOGBRUSH structure. CreateBrushIndirect () is called in
 *   response to a WM_CREATE message in HelloWndProc (). The brush is used
 *   to fill a rectangle in response to a WM_PAINT message.
 *
 */

#include    <windows.h>
HBRUSH      hMyBrush;
LOGBRUSH    lbBrushStyle;
RECT        MyRect;

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit (hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));

  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon             = LoadIcon (hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName     = (LPSTR)"CreateBrushIndirect";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree ( (HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
  }


int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  HelloInit (hInstance);
  hWnd = CreateWindow ( (LPSTR)"CreateBrushIndirect",
                      (LPSTR)"CreateBrushIndirect ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL );       /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_CREATE:
          /*  initialize the LOGBRUSH structure "lbBrushStyle  */
      lbBrushStyle.lbStyle = BS_HATCHED;
      lbBrushStyle.lbColor = RGB (0x00, 0x00, 0x00);
      lbBrushStyle.lbHatch = HS_BDIAGONAL;
          /* initialize the rectangle structure "MyRect" */
      MyRect.left   =  17;
      MyRect.top    =  17;
      MyRect.right  = 300;
      MyRect.bottom = 100;
          /*** create a hatched brush described by lbBrushStyle ***/
      hMyBrush = CreateBrushIndirect ( (LPLOGBRUSH) & lbBrushStyle);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      TextOut (ps.hdc, 5, 5,
              (LPSTR)"This rectangle filled with hatched brush created via Cr
              (long)74);
      FillRect (ps.hdc, (LPRECT) & MyRect, hMyBrush);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


CREATDLG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\CREATDLG.C

/*
 *   This program demonstrates use of the CreateDialog () function.
 *   CreateDialog () creates a modeless dialog box. CreateDialog () is
 *   called in response to a WM_COMMAND message in HelloWndProc ();
 */

#include "windows.h"
#include "creatdlg.h"

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);
BOOL    FAR PASCAL ShakeOptions (HWND, unsigned, WORD, LONG);
HWND    hYourTurnDlg = NULL;
HANDLE  hInst;
HWND    hWnd;
FARPROC lpprocSHAKE;

BOOL FAR PASCAL ShakeOptions (hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  HWND hCtl;
  int  i;
  BOOL OKAY;
  HDC hDC;
  RECT ClearRect;

  switch (message)
    {
    case WM_INITDIALOG:
      return TRUE;
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDOK:
          DestroyWindow (hYourTurnDlg);
          hYourTurnDlg = NULL;
          break;

        default:
          return FALSE;
          break;
        } /** end CASE WM_COMMAND **/
      break;

    case WM_DESTROY:
      return TRUE;
      break;

    default:
      return FALSE;
    }
  }

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit (hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));
  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon          = NULL;
  pHelloClass->lpszMenuName   = (LPSTR)"hello";
  pHelloClass->lpszClassName  = (LPSTR)"CreateDialog";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree ( (HANDLE)pHelloClass);

  return TRUE;        /* Initialization succeeded */
  }


int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG  msg;

  int   i;

  if (!hPrevInstance)
    if (!HelloInit (hInstance))
      return FALSE;

  hWnd = CreateWindow ( (LPSTR)"CreateDialog",
                      (LPSTR)"CreateDialog ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */

  hInst = hInstance;

  lpprocSHAKE  = MakeProcInstance ( (FARPROC)ShakeOptions, hInstance);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    if (hYourTurnDlg == NULL || !IsDialogMessage (hYourTurnDlg, &msg))
      {
      TranslateMessage ( (LPMSG) & msg);
      DispatchMessage ( (LPMSG) & msg);
      }
    }

  return (int)msg.wParam;
  }


/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
  {
  switch (message)
    {
    case WM_COMMAND:
         /*** if the dialog box does not currently exist ***/
      if (!hYourTurnDlg)
        hYourTurnDlg = CreateDialog (hInst, MAKEINTRESOURCE (5), hWnd, lpproc
         /*** create the dialog box and assign "hYourTurnDlg" to its handle *
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


CREATFON.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\FONTS\CREATFON.C

/*
 *
 * Function (s) demonstrated in this program: CreateFont, CreateFontIndirect,
 *      CreateBitmapIndirect, CreateCompatibleBitmap, SetBitmapBits,
 *      GetBitmapBits, SetBitmapBits.
 *
 * Description:
 * This application demonstrates the GetBitmapBits, SetBitmapBits,
 * CreateBitmapIndirect, CreateFont, CreateCompatibleBitmap,
 * CreateFontIndirect, and SetBitmapBits Windows functions.
 *
 */

#include <windows.h>
#include <string.h>
#include <stdio.h>
#include "CreatFon.h"

long  FAR PASCAL WndProc  (HWND, unsigned, WORD, LONG);
HBITMAP StretchBitmap (HBITMAP, int);
HBITMAP GetBitmapFont (int);

long  dwCount;
HBITMAP  hBitmapScottie;
PBITMAP  pBitmap;
char  nBits[500] = "ABC";
HBITMAP  hBitmapPopFont;
HBITMAP  hBitmapAbout;
HANDLE   hInstMain;
char  szAppName [] = "CreatFon";
char  szOutputBuffer1 [70];
char  szOutputBuffer2 [500];

struct {
  char  *szMessage;
} Messages [] =   {
  "About\0",
  "  This application demonstrates the GetBitmapBits, \n\
SetBitmapBits, CreateBitmapIndirect, CreateFont, \n\
CreateCompatibleBitmap, CreateFontIndirect, and\n\
SetBitmapBits Windows functions.",

      "Help Message",
  "     This program demonstrates the use of many\n\
Windows functions.  Use the menu to test these\n\
functions.",

  "CreateFont",
  "     The menu has a new item the font for which\n\
was created using the CreateFont Windows function.",

  "CreateFontIndirect",
  "     The menu has a new item the font for which\n\
was created using the CreateFontIndirect Windows\n\
function.",

  "CreateBitmapIndirect",
  "     The menu has a new item the bitmap for which\n\
was created using the CreateBitmapIndirect Windows\n\
function.",

      "CreateCompatibleBitmap",
  "     The menu has a new item the bitmap for which\n\
was created using the CreateCompatibleBitmap Windows\n\
function.",

      "GetBitmapBits",
  "    Bitmap bits are stored in a buffer.",

  "SetBitmapBits",
  "     The menu has a new item the bitmap for which\n\
was created using the SetBitmapBits Windows\n\
function.",

  "SetBitmapBits",
  "     You must Get the Bits first!",

};


/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)  /*  For outputting messages  */
HWND     hWnd;
int  MessageNumber;
{
  sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
  sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
  MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}


/****************************************************************************

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int  nCmdShow;
{
  HMENU    hMenu, hMenuPopup;
  HWND     hWnd;
  MSG      msg;
  int  i;
  WNDCLASS wndclass;

  if (!hPrevInstance)
  {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = szAppName;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
  }

  hInstMain = hInstance;

  hWnd = CreateWindow (szAppName, "Bitmap Menu Demonstration",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

  hMenu = GetSystemMenu (hWnd, FALSE);
  hBitmapAbout = StretchBitmap (LoadBitmap (hInstance, "BitmapAbout"), 1);
  ChangeMenu (hMenu, NULL, NULL, 0, MF_APPEND | MF_SEPARATOR);
  ChangeMenu (hMenu, NULL, (PSTR) hBitmapAbout, IDM_ABOUT,
      MF_APPEND | MF_BITMAP);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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

  DeleteObject (hBitmapPopFont);  /*  Free up memory taken by bitmaps  */
  DeleteObject (hBitmapAbout);
  DeleteObject (hBitmapScottie);

  return msg.wParam;
}


/****************************************************************************

HBITMAP StretchBitmap (hBitmap1, I)
HBITMAP    hBitmap1;
int  I;
{
  BITMAP     bm1, bm2;
  HBITMAP    hBitmap2;
  HDC        hDC, hMemDC1, hMemDC2;
  TEXTMETRIC tm;

  hDC = CreateIC ("DISPLAY", NULL, NULL, NULL);
  GetTextMetrics (hDC, &tm);
  hMemDC1 = CreateCompatibleDC (hDC);
  hMemDC2 = CreateCompatibleDC (hDC);
  DeleteDC (hDC);

  GetObject (hBitmap1, sizeof (BITMAP), (LPSTR) & bm1);

  bm2 = bm1;
  bm2.bmWidth      = (tm.tmAveCharWidth * bm2.bmWidth)  / 4;
  bm2.bmHeight     = (tm.tmHeight       * bm2.bmHeight) / 8;
  bm2.bmWidthBytes = ( (bm2.bmWidth + 15) / 16) * 2;

  if (I == 1)
  {
    hBitmap2 = CreateBitmapIndirect (&bm2);
    SelectObject (hMemDC1, hBitmap1);
    SelectObject (hMemDC2, hBitmap2);
  }
  else
  {
    SelectObject (hMemDC1, hBitmap1);
    hBitmap2 = CreateCompatibleBitmap (hMemDC1, bm2.bmWidth, bm2.bmHeight);
    SelectObject (hMemDC2, hBitmap2);
  }

  StretchBlt (hMemDC2, 0, 0, bm2.bmWidth, bm2.bmHeight,
      hMemDC1, 0, 0, bm1.bmWidth, bm1.bmHeight, SRCCOPY);

  DeleteDC (hMemDC1);
  DeleteDC (hMemDC2);
  DeleteObject (hBitmap1);

  return hBitmap2;
}


/****************************************************************************

HBITMAP GetBitmapFont (i)
int  i;
{
  static struct
  {
    BYTE lfPitchAndFamily;
    BYTE lfFaceName [LF_FACESIZE];
    char  *szMenuText;
  } lfSet [2] =
  {
    VARIABLE_PITCH | FF_ROMAN,  "Tms Rmn",   "Times Roman",
    VARIABLE_PITCH | FF_SWISS,  "Helvetica", "Helvetica"
  };
  DWORD   dwSize;
  HBITMAP hBitmap;
  HDC     hDC, hMemDC;
  HFONT   hFont, hNewFont;
  LOGFONT lf;

  hFont = GetStockObject (SYSTEM_FONT);
  GetObject (hFont, sizeof (LOGFONT), (LPSTR) & lf);

  lf.lfHeight *= 2;
  lf.lfWidth  *= 2;
  lf.lfPitchAndFamily = lfSet[i].lfPitchAndFamily;
  strcpy (lf.lfFaceName, lfSet[i].lfFaceName);

  hDC = CreateIC ("DISPLAY", NULL, NULL, NULL);
  hMemDC = CreateCompatibleDC (hDC);

  if (i == 0)
  {
    hNewFont = CreateFont (lf.lfHeight, lf.lfWidth, lf.lfEscapement,
        lf.lfOrientation, lf.lfWeight, lf.lfItalic,
        lf.lfUnderline, lf.lfStrikeOut, lf.lfCharSet,
        lf.lfOutPrecision, lf.lfClipPrecision, lf.lfQuality,
        lf.lfPitchAndFamily, lf.lfFaceName);
    SelectObject (hMemDC, hNewFont);
  }
  else
    SelectObject (hMemDC, CreateFontIndirect (&lf));

  dwSize = GetTextExtent (hMemDC, lfSet[i].szMenuText,
      strlen (lfSet[i].szMenuText));

  hBitmap = CreateBitmap (LOWORD (dwSize), HIWORD (dwSize), 1, 1, NULL);
  SelectObject (hMemDC, hBitmap);
  TextOut (hMemDC, 0, 0, lfSet[i].szMenuText, strlen (lfSet[i].szMenuText));

  DeleteObject (SelectObject (hMemDC, hFont));
  DeleteDC (hMemDC);
  DeleteDC (hDC);

  return hBitmap;
}


/****************************************************************************

long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned  iMessage;
WORD     wParam;
LONG     lParam;
{
  HMENU    hMenu;
  static short  nCurrentFont = IDM_TMSRMN;

  switch (iMessage)
  {
  case WM_SYSCOMMAND:
    switch (wParam)
    {
    case IDM_ABOUT:
      ProcessMessage (hWnd, 0);
      break;
    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
    break;

  case WM_COMMAND:
    switch (wParam)
    {
    case IDM_CREATEFONT:
      hMenu = GetSubMenu (GetMenu (hWnd), 0);
      hBitmapPopFont = GetBitmapFont (0);
      ChangeMenu (hMenu, NULL, NULL, 0,
          MF_APPEND | MF_SEPARATOR);
      ChangeMenu (hMenu, NULL, (PSTR) hBitmapPopFont,
          IDM_TMSRMN, MF_APPEND | MF_BITMAP);
      ProcessMessage (hWnd, 4);
      break;

    case IDM_CREATEFONTINDIRECT:
      hMenu = GetSubMenu (GetMenu (hWnd), 0);
      hBitmapPopFont = GetBitmapFont (1);
      ChangeMenu (hMenu, NULL, NULL, 0,
          MF_APPEND | MF_SEPARATOR);
      ChangeMenu (hMenu, NULL, (PSTR) hBitmapPopFont,
          IDM_TMSRMN, MF_APPEND | MF_BITMAP);
      ProcessMessage (hWnd, 6);
      break;

    case IDM_CREATEBMPINDIRECT:
      hMenu = GetSubMenu (GetMenu (hWnd), 0);
      hBitmapAbout = StretchBitmap (LoadBitmap (hInstMain,
          "BitmapAbout"), 1);
      ChangeMenu (hMenu, NULL, NULL, 0,
          MF_APPEND | MF_SEPARATOR);
      ChangeMenu (hMenu, NULL, (PSTR) hBitmapAbout,
          IDM_ABOUT, MF_APPEND | MF_BITMAP);
      ProcessMessage (hWnd, 8);
      break;

    case IDM_CREATECOMPATIBLEBMP:
      hMenu = GetSubMenu (GetMenu (hWnd), 0);
      hBitmapAbout = StretchBitmap (LoadBitmap (hInstMain,
          "BitmapAbout"), 2);
      ChangeMenu (hMenu, NULL, NULL, 0,
          MF_APPEND | MF_SEPARATOR);
      ChangeMenu (hMenu, NULL, (PSTR) hBitmapAbout,
          IDM_ABOUT, MF_APPEND | MF_BITMAP);
      ProcessMessage (hWnd, 10);
      break;

    case IDM_GETBITMAPBITS:
      hBitmapScottie = LoadBitmap (hInstMain,
          "BitmapScottie");
      pBitmap = (PBITMAP)LocalAlloc (LMEM_MOVEABLE,
          sizeof (BITMAP));
      dwCount = GetObject (hBitmapScottie,
          (long)sizeof (BITMAP), (LPSTR) pBitmap);
      if (GetBitmapBits (hBitmapScottie, dwCount,
          (LPSTR)nBits))
  ProcessMessage (hWnd, 12);
      else
  MessageBox (hWnd, "Bitmap did not copy!",
      "GetBitmapBits", MB_OK);
      break;

    case IDM_SETBITMAPBITS:
      if (nBits [0] == 'A')
  ProcessMessage (hWnd, 16);
      else
      {
  SetBitmapBits (hBitmapScottie, dwCount, nBits);
  hMenu = GetSubMenu (GetMenu (hWnd), 0);
  hBitmapScottie = StretchBitmap (hBitmapScottie, 1);
  ChangeMenu (hMenu, NULL, NULL, 0,
      MF_APPEND | MF_SEPARATOR);
  ChangeMenu (hMenu, NULL, (PSTR) hBitmapScottie,
      IDM_SCOTTIE, MF_APPEND | MF_BITMAP);
  ProcessMessage (hWnd, 14);
      }
      break;

    case IDM_HELP:
      ProcessMessage (hWnd, 2);
      break;
    }
    break;

  case WM_DESTROY:
    PostQuitMessage (0);
    break;

  default:
    return DefWindowProc (hWnd, iMessage, wParam, lParam);
  }
  return 0L;
}




CRELIPRG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRELIPRG.C

/*
 *  Function Name:   CreateEllipticRgn
 *
 *  Description:
 *   The program below will create an elliptical region which will be
 *   inverted so that it can be seen.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_CreateEllipticRgn (hWnd, hDC)
HWND hWnd;
HDC hDC;
  {
  HRGN hNewRgn;
  RECT ClientRect;

  GetClientRect (hWnd, (LPRECT) & ClientRect);       /* get client area */

  hNewRgn = CreateEllipticRgn (10, 10, (short) (ClientRect.right / 2),
                               (short) (ClientRect.bottom / 2));
  if (hNewRgn == NULL)
    {
    MessageBeep(0);    /*  Beep if we have an error  */
    return;
    }
  InvertRgn (hDC, hNewRgn);
  DeleteObject (hNewRgn);

  return;
  }

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"CreateEllipticRgn";

    if (!RegisterClass ( (LPWNDCLASS) & wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"CreateEllipticRgn",
                      (LPSTR)"CreateEllipticRgn ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      CALL_CreateEllipticRgn (hWnd, ps.hdc);
      ValidateRect (hWnd, (LPRECT) NULL);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


CRELIRIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRELIRIN.C

/*
 *  Function Name:   CreateEllipticRgnIndirect
 *
 *  Description:
 *   The program below creates an elliptical region that will be displayed
 *   by inverting the region.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_CreateEllipticRgnIndirect (hWnd, hDC)
HWND hWnd;
HDC hDC;
  {
  RECT ClientRect;
  HRGN hNewRgn;

  GetClientRect (hWnd, (LPRECT) & ClientRect);   /* get client area  */

  ClientRect.right /= 2;
/* create new region   */
  hNewRgn = CreateEllipticRgnIndirect ( (LPRECT) & ClientRect);

  if (hNewRgn == NULL)                   /* Check for error */
    {
    MessageBeep (0);
    return;
    }
  InvertRgn (hDC, hNewRgn);
  DeleteObject (hNewRgn);
  return;
  }

/**************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  if (!hPrevInstance)
    {
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"CreateEllipticRgnIndirect";

    if (!RegisterClass ( (LPWNDCLASS) & wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"CreateEllipticRgnIndirect",
                      (LPSTR)"CreateEllipticRgnIndirect ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */


  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      CALL_CreateEllipticRgnIndirect (hWnd, ps.hdc);
      ValidateRect (hWnd, (LPRECT) NULL);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


CREWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\CREWIN.C

/*
 *  CreateWindow
 *  This function demonstrates the use of the CreateWindow function.  It will
 *  create a window using the CreateWindow function, show the window using
 *  the ShowWindow command and procede to draw a triangle in the window in
 *  the MM_ANISOTROPIC mapping mode.
 */

#include <windows.h>

BOOL FAR PASCAL InitCreateWindow (HANDLE, HANDLE, int);
long    FAR PASCAL CreateWindowWindowProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int      nCmdShow;
  {
  MSG  msg;

  InitCreateWindow (hInstance, hPrevInstance, nCmdShow);  /*  Init Routine  *
  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  exit (msg.wParam);
  }


BOOL FAR PASCAL InitCreateWindow (hInstance, hPrevInstance, nCmdShow)
HANDLE   hInstance;
HANDLE   hPrevInstance;
int      nCmdShow;
  {
  WNDCLASS  wcCreateWindowClass;
  HWND  hWnd;

  wcCreateWindowClass.lpszClassName = (LPSTR) "CreateWindow";
  wcCreateWindowClass.hInstance     = hInstance;
  wcCreateWindowClass.lpfnWndProc   = CreateWindowWindowProc;
  wcCreateWindowClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcCreateWindowClass.hIcon      = NULL;
  wcCreateWindowClass.lpszMenuName  = (LPSTR) NULL;
  wcCreateWindowClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcCreateWindowClass.style      = CS_HREDRAW | CS_VREDRAW;
  wcCreateWindowClass.cbClsExtra    = 0;
  wcCreateWindowClass.cbWndExtra    = 0;

  RegisterClass ( (LPWNDCLASS) & wcCreateWindowClass);

  hWnd = CreateWindow ( (LPSTR) "CreateWindow",  /*  Window class name
                      (LPSTR) "CreateWindow",    /*  Window title
                      WS_OVERLAPPEDWINDOW,       /*  Type of window
                      CW_USEDEFAULT,             /*  default x pos
                      CW_USEDEFAULT,             /*  default y pos
                      CW_USEDEFAULT,             /*  default change in x pos
                      CW_USEDEFAULT,             /*  default change in y pos
                      (HWND)NULL,                /*  No parent for this wind
                      (HMENU)NULL,               /*  Use the Class menu
                      (HANDLE)hInstance,         /*  Who created this window
                      (LPSTR)NULL);              /*  No params. to pass on.

  ShowWindow (hWnd, nCmdShow);   /*  Display this window on the screen
                                   *  nCmdShow is passed in by WinMain, and
           *  should only be used with ShowWindow
           *  once during a program.  Any further
           *  calls to ShowWindow will need to have
           *  certain values.  See entry in manual
           *  for ShowWindow for further details
             */

  UpdateWindow (hWnd);           /*  Cause a paint message              */
  return TRUE;
  }

/*
 *  THE WINDOW PROCEDURE - Process messages
 */

long    FAR PASCAL CreateWindowWindowProc (hWnd, message, wParam, lParam)

HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
  {
  switch (message)
    {
    case WM_PAINT:
      PaintCreateWindowWindow (hWnd);
      break;

    case WM_DESTROY:                  /*  If close requested      */
      PostQuitMessage (0);     /*    send yourself a quit  */
      break;                          /*    message               */

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
      break;
    }
  return (0L);
  }


/*
 *  THE PAINT PROCEDURE
 */

PaintCreateWindowWindow (hWnd)

HWND    hWnd;
  {
  PAINTSTRUCT  ps;
  HDC    hDC;
  POINT   lpTriangle[4];
  HANDLE        hOldBrush, hBrush;
  RECT          rRect;

  BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);    /*  Prepare the client area  */
  hDC = ps.hdc;             /*  Get the Display Context  */

  hBrush = GetStockObject (GRAY_BRUSH);     /*  Get a gray brush         */
  hOldBrush = SelectObject (hDC, hBrush);  /*  Select the new brush     */

  lpTriangle[0].x = 150;    /*  The values of the points  */
  lpTriangle[0].y = 100;
  lpTriangle[1].x = 100;
  lpTriangle[1].y = 200;
  lpTriangle[2].x = 200;
  lpTriangle[2].y = 200;

  SetMapMode (hDC, MM_ANISOTROPIC);   /*  Set the mapping mode             */

  SetWindowExt (hDC, 300, 300);      /*  Set the extent of the drawing
                                      *  area.  This is the area that
                                      *  holds graphics that you create
                                      *  with GDI functions.  Do not
                                      *  confuse this function with
                                      *  the actual window.  The
                                      *  SetViewportExt sets the
                                      *  extent of the area to be mapped
                                      *  to which is the actual window
                                      */

  GetClientRect (hWnd, (LPRECT) & rRect);
                                         /*  Get the size of the client area
            *  so that we can set the viewport
            *  extent
            */

  SetViewportExt (hDC, rRect.right, rRect.bottom);
/*  Set the Extent of the viewport   */

  Polygon (hDC, lpTriangle, 3);      /*  Draw the triangle                */

  ValidateRect (hWnd, (LPRECT) NULL);   /*  Disable any more paint messages
  EndPaint (hWnd, (LPPAINTSTRUCT) & ps);

  SelectObject (hDC, hOldBrush);       /*  Replace the old brush  */
  return TRUE;
  }


CRHABRUS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRHABRUS.C

/*
 *  Function Name:   CreateHatchBrush
 *
 *  Description:
 *   This creates a logical brush that can replace the current brush for the
 *   device.  The program below draws a rectangle and fills it in with a red,
 *   vertical line brush that was selected.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

HBRUSH    hBrush;

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    WNDCLASS   wcClass;

    hBrush = CreateHatchBrush (HS_VERTICAL, RGB (255, 0, 0));

    if (hBrush == NULL)                /* checks for successful brush creatio
      {
      MessageBox (hWnd, (LPSTR)"CreateHatchBrush failed",
                 (LPSTR)"ERROR", MB_ICONHAND | MB_OK );
      return (0L);
      }

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = hBrush;
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"CreateHatchBrush";

    if (!RegisterClass ( (LPWNDCLASS) & wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"CreateHatchBrush",
                      (LPSTR)"CreateHatchBrush ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,         /* no parent */
                      (HMENU)NULL,        /* use class menu */
                      (HANDLE)hInstance,  /* handle to window instance */
                      (LPSTR)NULL);       /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  DeleteObject (hBrush);
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


CRIC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRIC.C

/*
 *  Function Name:   CreateIC
 *  Program Name:    cric.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   An information context is retrieved from the display, and the brush is
 *   extracted.  The brush information for the IC is then displayed on
 *   the screen to show that the IC has valid information.
 */

#include "windows.h"
#include "stdio.h"

long  FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_CreateIC(hWnd, hDC)
HWND hWnd;
HDC  hDC;
{
  HDC hIC;
  PLOGBRUSH pBrush;
  HBRUSH  hICBrush;
  char  szstring[80];
  int  nLength;
/*  information context created   */
  hIC = CreateIC((LPSTR)"DISPLAY", (LPSTR)NULL, (LPSTR)NULL, (LPSTR)NULL);

  if (hIC == NULL)
  {
    MessageBox(hWnd, (LPSTR)"CreateIC failed", (LPSTR)"ERROR", MB_ICONHAND);
    return;
  }

  pBrush = (PLOGBRUSH) LocalAlloc(LMEM_MOVEABLE, sizeof(LOGBRUSH));
  hICBrush = SelectObject(hIC, CreateSolidBrush((LONG)0));
  GetObject(hICBrush, 8, (LPSTR) pBrush);   /* put brush into structure */
  nLength = sprintf(szstring, "Information Context Brush Attributes are:"
      "   style=%u, color=%lx, hatch=%d ",
      pBrush->lbStyle, pBrush->lbColor, pBrush->lbHatch);
  TextOut (hDC, 10, 10, (LPSTR) szstring, nLength);

  return;
}


/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
  WNDCLASS   wcClass;

  wcClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcClass.lpfnWndProc    = WndProc;
  wcClass.cbClsExtra     = 0;
  wcClass.cbWndExtra     = 0;
  wcClass.hInstance      = hInstance;
  wcClass.hIcon          = LoadIcon( hInstance, NULL );
  wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
  wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  wcClass.lpszMenuName   = (LPSTR)NULL;
  wcClass.lpszClassName  = (LPSTR)"CreateIC";

  if (!RegisterClass( (LPWNDCLASS) & wcClass ) )
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
  {
/* Call initialization procedure if this is the first instance */
    if (!WinInit( hInstance ))
      return FALSE;
  }

  hWnd = CreateWindow((LPSTR)"CreateIC",
      (LPSTR)"CreateIC()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
  );

/* Make window visible according to the way the app is activated */
  ShowWindow( hWnd, cmdShow );
  UpdateWindow( hWnd );

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }

  return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long  FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {

  case WM_PAINT:
    BeginPaint( hWnd, (LPPAINTSTRUCT) & ps );
    CALL_CreateIC(hWnd, ps.hdc);
    ValidateRect(hWnd, (LPRECT) NULL);
    EndPaint( hWnd, (LPPAINTSTRUCT) & ps );
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}




CRMENU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\CRMENU.C

/*
 *  Function Name:   CreateMenu
 *
 *  Description:
 *   This program creates a blank menu that the user can fill in from the
 *   program instead of the resource file.  ChangeMenu must be used to enter
 *   the heading and items of the menu.  The program below will add the menu
 *   called "Heading" to the menu bar in CurrentWindowMenu.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"CreateMenu";

    if (!RegisterClass ( (LPWNDCLASS) & wcClass))
      return FALSE;
    }

  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, "MenuItem", 100, MF_APPEND);

  hWnd = CreateWindow ( (LPSTR)"CreateMenu",
                      (LPSTR)"CreateMenu ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)hMenu,      /* use our menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }


CRMETAFI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\CRMETAFI.C

/*
 *  Function Name:   CreateMetaFile
 *  Program Name:    crmetafi.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   This function is used for saving GDI images on a disk (and in memory)
 *   that can latter be recalled and displayed or printed.  Here a metafile
 *   is created, text is placed in it, and it is written to the disk.
 *   It is then recalled and displayed on the screen.  The recall is either
 *   from memory or disk depending on whether a handle is available to a
 *   memory image.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_CreateMetaFile(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  HDC hDCMeta;
  HANDLE hDiskMetaFile;

  hDCMeta = CreateMetaFile((LPSTR) "crmetafi.met");  /* Metafile created */

  if (hDCMeta == NULL)
  {
    MessageBox(hWnd,(LPSTR)"CreateMetaFile failed",(LPSTR)"ERROR",MB_ICONHAND
    return;
  }
  else
    TextOut(hDCMeta, 20, 20, (LPSTR)"Metafile created", 16);

  hDiskMetaFile = CloseMetaFile(hDCMeta);
  PlayMetaFile(hDC, hDiskMetaFile);        /* show metafile  */
  DeleteMetaFile(hDiskMetaFile);

return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"CreateMetaFile";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"CreateMetaFile",
                        (LPSTR)"CreateMetaFile()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_CreateMetaFile(hWnd, ps.hdc);
        ValidateRect(hWnd, (LPRECT) NULL);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}



CRPABRUS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRPABRUS.C

/*
 *  Function Name:   CreatePatternBrush
 *  Program Name:    crpabrus.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   This program takes a valid bitmap pattern and assigns it to be used as a
 *   brush.  The program below draws a rectangle and fills it with a
 *   crosshatch pattern brush created from a bitmap.
 */

#include "windows.h"

long  FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_CreatePatternBrush(hWnd, hDC)
HWND hWnd;
HDC  hDC;
{
  HBRUSH    hBrush, hOldBrush;
  HBITMAP   hBitLoad;
/* set up 8x8 crosshatch pattern */
  static short  BitmapArray[] =
  {
    0xFF, 0xF7, 0xEB, 0xDD, 0xBE, 0x7F, 0xFF, 0xFF    };

  hBitLoad = CreateBitmap(8, 8, 1, 1, (LPSTR)BitmapArray); /* for monochrome

  hBrush = CreatePatternBrush(hBitLoad);      /* load pattern brush    */

  if (hBrush == NULL)                /* checks for successful brush creation
  {
    MessageBox(hWnd, (LPSTR)"CreatePatternBrush failed",
        (LPSTR)"ERROR", MB_ICONHAND);
    return;
  }

  hOldBrush = (HBRUSH) SelectObject (hDC, (HANDLE) hBrush);
  Rectangle (hDC, 10, 10, 300, 100);
  hBrush = SelectObject (hDC, hOldBrush);
  DeleteObject(hBrush);
  DeleteObject(hBitLoad);

  return;
}


/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
  WNDCLASS   wcClass;

  wcClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcClass.lpfnWndProc    = WndProc;
  wcClass.cbClsExtra     = 0;
  wcClass.cbWndExtra     = 0;
  wcClass.hInstance      = hInstance;
  wcClass.hIcon          = LoadIcon( hInstance, NULL );
  wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
  wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  wcClass.lpszMenuName   = (LPSTR)NULL;
  wcClass.lpszClassName  = (LPSTR)"CreatePatternBrush";

  if (!RegisterClass( (LPWNDCLASS) & wcClass ) )
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
  {
/* Call initialization procedure if this is the first instance */
    if (!WinInit( hInstance ))
      return FALSE;
  }

  hWnd = CreateWindow((LPSTR)"CreatePatternBrush",
      (LPSTR)"CreatePatternBrush()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
  );

/* Make window visible according to the way the app is activated */
  ShowWindow( hWnd, cmdShow );
  UpdateWindow( hWnd );

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }

  return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long  FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {

  case WM_PAINT:
    BeginPaint( hWnd, (LPPAINTSTRUCT) & ps );
    CALL_CreatePatternBrush(hWnd, ps.hdc);
    ValidateRect(hWnd, (LPRECT) NULL);
    EndPaint( hWnd, (LPPAINTSTRUCT) & ps );
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}




CRPEN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRPEN.C

/*
 *  Function Name:   CreatePen
 *
 *  Description:
 *   It creates a logical pen that can replace the current pen for the device
 *   The module below draws an arc.
 *   CreatePen selects the style (0=solid), a width of 20, and the color
 *   red. A width of 0 is one pixel width on raster devices.  The mode used
 *   is MM_TEXT (default).
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

/***********************************************************************/
void CALL_CreatePen (hWnd, hDC)
HWND hWnd;
HDC hDC;
  {
  HPEN hPen, hOldPen;

  hPen = CreatePen (0, 20, RGB (255, 0, 0));   /* hPen created.   */

  if (hPen == NULL)                /* checks for successful pen creation */
    {
    MessageBeep(0);
    return;
    }

  hOldPen = (HPEN) SelectObject (hDC, (HANDLE) hPen);
  Arc (hDC, 0, 0, 300, 200, 200, 180, 100, 30);
  DeleteObject (hPen);

  return;
  }

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  if (!hPrevInstance)
    {
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"CreatePen";

    if (!RegisterClass ( (LPWNDCLASS) & wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"CreatePen",
                      (LPSTR)"CreatePen ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {

  case WM_PAINT:
    BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
    CALL_CreatePen (hWnd, ps.hdc);
    ValidateRect (hWnd, (LPRECT) NULL);
    EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
    break;

  case WM_DESTROY:
    PostQuitMessage (0);
    break;

  default:
    return DefWindowProc (hWnd, message, wParam, lParam);
    break;
    }
  return (0L);
  }


CRPENIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRPENIN.C

/*
 *  Function Name:   CreatePenIndirect
 *
 *  Description:
 *   This program creates a logical pen that replaces the current pen for the
 *   device.  It uses the data structure LOGPEN to set up the style, width,
 *   and color fields.  With lopnWidth, the data structure is type POINT.
 *   The x value is the width, and the y value is ignored.  Unlike CreatePen,
 *   the structure for LOGOPEN must first be allocated before values can be
 *   assigned.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

HPEN hPen, hOldPen;   /*  Global Handles to Pens  */

/***********************************************************************/
void CALL_CreatePenIndirect (hWnd)
HWND hWnd;
  {
  LOGPEN PenIndirect;
  POINT Point1;

  Point1.x = 10;                      /* assign width 10 to x.          */
  Point1.y = 0;                       /* y is ignored.                  */
  PenIndirect.lopnStyle = 0;         /* style is 0                    */
  PenIndirect.lopnWidth = Point1;      /* width is Point1.         */
  PenIndirect.lopnColor = RGB (255, 0, 0);       /* color is red.   */

  hPen = CreatePenIndirect ( (LPLOGPEN) & PenIndirect);  /*  pen created  */

  if (hPen == NULL)                /* checks for successful pen creation */
    {
    MessageBox (hWnd, (LPSTR)"CreatePenIndirect failed",
                (LPSTR)"ERROR", MB_ICONHAND | MB_OK);
    DestroyWindow (hWnd);  /*  The pen wasn't created, so trash the program
    return;
    }
  return;
  }


int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"CreatePenIndirect";

    if (!RegisterClass ( (LPWNDCLASS) & wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"CreatePenIndirect",
                      (LPSTR)"CreatePenIndirect ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);        /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_CREATE:
      CALL_CreatePenIndirect (hWnd);
      break;

    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      hOldPen = SelectObject (ps.hdc, hPen);
      Arc (ps.hdc, 0, 0, 300, 200, 200, 140, 100, 30);
      SelectObject (ps.hdc, hOldPen);
      ValidateRect (hWnd, (LPRECT) NULL);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    case WM_DESTROY:
      DeleteObject (hPen);
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


CRPOLYRG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRPOLYRG.C

/*
 *  Function Name:   CreatePolygonRgn
 *
 *  Description:
 *   The program below will create a triangular region and then display it
 *   by inverting the region.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

/***********************************************************************/
void CALL_CreatePolygonRgn (hWnd, hDC)
HWND hWnd;
HDC hDC;
  {
  HRGN hNewRgn;
  POINT Points[3];

  Points[0].x = 10;
  Points[0].y = 10;
  Points[1].x = 10;
  Points[1].y = 190;                      /* clip area     */
  Points[2].x = 200;
  Points[2].y = 10;
     /*  polygon region created  */
  hNewRgn = CreatePolygonRgn ( (LPPOINT)Points, 3, WINDING);

  if (hNewRgn == NULL)                   /* Check for error */
    {
    MessageBeep (0);
    return;
    }
  InvertRgn (hDC, hNewRgn);
  DeleteObject (hNewRgn);
  return;
  }

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"CreatePolygonRgn";

    if (!RegisterClass ( (LPWNDCLASS) & wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"CreatePolygonRgn",
                      (LPSTR)"CreatePolygonRgn ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      CALL_CreatePolygonRgn (hWnd, ps.hdc);
      ValidateRect (hWnd, (LPRECT) NULL);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


CRRECRIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRRECRIN.C

/*
 *  Function Name:   CreateRectRgnIndirect
 *  Program Name:    crrectin.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   The program below will create a rectangular region and then invert
 *   it to make it visible on the screen.
 */

#include "windows.h"

long  FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_CreateRectRgnIndirect(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  HRGN hNewRgn;
  RECT ClientRect;

  GetClientRect( hWnd, (LPRECT) & ClientRect );   /* get client area */
  ClientRect.right /= 2;             /*  half client area  */
/* create new region   */
  hNewRgn = CreateRectRgnIndirect((LPRECT) & ClientRect);

  if (hNewRgn == NULL)                   /* Check for error */
  {
    MessageBox(hWnd, (LPSTR)"CreateRectRgn failed.", (LPSTR)"ERROR", MB_ICONH
    return;
  }
  InvertRgn(hDC, hNewRgn);
  DeleteObject( hNewRgn );

  return;
}


/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
  WNDCLASS   wcClass;

  wcClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcClass.lpfnWndProc    = WndProc;
  wcClass.cbClsExtra     = 0;
  wcClass.cbWndExtra     = 0;
  wcClass.hInstance      = hInstance;
  wcClass.hIcon          = LoadIcon( hInstance, NULL );
  wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
  wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  wcClass.lpszMenuName   = (LPSTR)NULL;
  wcClass.lpszClassName  = (LPSTR)"CreateRectRgnIndirect";

  if (!RegisterClass( (LPWNDCLASS) & wcClass ) )
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
  {
/* Call initialization procedure if this is the first instance */
    if (!WinInit( hInstance ))
      return FALSE;
  }

  hWnd = CreateWindow((LPSTR)"CreateRectRgnIndirect",
      (LPSTR)"CreateRectRgnIndirect()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
  );

/* Make window visible according to the way the app is activated */
  ShowWindow( hWnd, cmdShow );
  UpdateWindow( hWnd );

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }

  return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long  FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {

  case WM_PAINT:
    BeginPaint( hWnd, (LPPAINTSTRUCT) & ps );
    CALL_CreateRectRgnIndirect(hWnd, ps.hdc);
    ValidateRect(hWnd, (LPRECT) NULL);
    EndPaint( hWnd, (LPPAINTSTRUCT) & ps );
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}




CRRECTRG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRRECTRG.C

/*
 *  Function Name:   CreateRectRgn
 *  Program Name:    crrectrg.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   The program below will create a rectagular region and make it visble
 *   by inverting the region.
 */

#include "windows.h"

long  FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_CreateRectRgn(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  HRGN hNewRgn;
  RECT ClientRect;

  GetClientRect( hWnd, (LPRECT) & ClientRect );   /* get client area   */

  hNewRgn = CreateRectRgn(10, 10,
      (short) ClientRect.right / 2,  /* half client area */
  (short) ClientRect.bottom);
  if (hNewRgn == NULL)                   /* Check for error */
  {
    MessageBox(hWnd, (LPSTR)"CreateRectRgn failed.", (LPSTR)"ERROR", MB_ICONH
    return;
  }
  InvertRgn(hDC, hNewRgn);                       /* invert region  */
  DeleteObject( hNewRgn );

  return;
}


/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
  WNDCLASS   wcClass;

  wcClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcClass.lpfnWndProc    = WndProc;
  wcClass.cbClsExtra     = 0;
  wcClass.cbWndExtra     = 0;
  wcClass.hInstance      = hInstance;
  wcClass.hIcon          = LoadIcon( hInstance, NULL );
  wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
  wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  wcClass.lpszMenuName   = (LPSTR)NULL;
  wcClass.lpszClassName  = (LPSTR)"CreateRectRgn";

  if (!RegisterClass( (LPWNDCLASS) & wcClass ) )
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
  {
/* Call initialization procedure if this is the first instance */
    if (!WinInit( hInstance ))
      return FALSE;
  }

  hWnd = CreateWindow((LPSTR)"CreateRectRgn",
      (LPSTR)"CreateRectRgn()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
  );

/* Make window visible according to the way the app is activated */
  ShowWindow( hWnd, cmdShow );
  UpdateWindow( hWnd );

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }

  return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long  FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {

  case WM_PAINT:
    BeginPaint( hWnd, (LPPAINTSTRUCT) & ps );
    CALL_CreateRectRgn(hWnd, ps.hdc);
    ValidateRect(hWnd, (LPRECT) NULL);
    EndPaint( hWnd, (LPPAINTSTRUCT) & ps );
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}




CRSOBRUS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\CRSOBRUS.C

/*
 *  Function Name:   CreateSolidBrush
 *
 *  Description:
 *   This function creates a logical brush that can replace the current brush
 *   for the device.  The program below draws a rectangle and fills it in
 *   with a red brush that was selected.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG     msg;
  HWND    hWnd;
  HBRUSH  hBrush;

  hBrush = CreateSolidBrush (RGB (255, 0, 0));   /* hBrush created (red). */

  if (hBrush == NULL)                /* checks for successful brush creation
    {
    MessageBox (hWnd, (LPSTR)"CreateSolidBrush failed", (LPSTR)"ERROR", MB_IC
    return (0L);
    }

  if (!hPrevInstance)
    {
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = hBrush;
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"CreateSolidBrush";

    if (!RegisterClass ( (LPWNDCLASS) & wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"CreateSolidBrush",
                      (LPSTR)"CreateSolidBrush ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  DeleteObject (hBrush);
  return (int)msg.wParam;
  }


/* Procedures which make up the window class. */
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


CWINPROC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLASS\CWINPROC.C

/*
 *   This program demonstrates the use of the CallWindowProc () function.
 *   CallWindowProc () passes message information contained in the 3rd
 *   parameter to the window identified by the 2nd parameter. CallWindow-
 *   Proc is used in subclassing. This is how it is used in this program.
 *   No real subclass is performed in this program; it is just set up.
 *   Messages destined for the listbox in the dialog box are intercepted
 *   by SubClassProc () and then passed on to the default procedure for
 *   listboxes. CallWindowProc () is called in SubClassProc () after the
 *   subclass is performed.
 */

#include "windows.h"
#include "cwinproc.h"

BOOL FAR PASCAL DialogBoxProc (HWND, unsigned, WORD, LONG);
long  FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);
long  FAR PASCAL SubClassProc (HWND, unsigned, WORD, LONG);

HANDLE hInst;

FARPROC lpprocDlgProc;
FARPROC lpprocSubClassProc;
FARPROC lpprocListBox;

char  szLBOutput[50];

BOOL FAR PASCAL DialogBoxProc (hDlg, message, wParam, lParam)
HWND hDlg;
unsigned  message;
WORD wParam;
LONG lParam;
{
  HWND hCtl;
  LONG lListBoxSel;
  int  i;
  char  buffer[15];

  switch (message)
  {
  case WM_INITDIALOG:
    lpprocSubClassProc = MakeProcInstance ( (FARPROC) SubClassProc, hInst);

    lpprocListBox = (FARPROC) SetWindowLong (GetDlgItem (hDlg, IDLISTBOX),
        GWL_WNDPROC,
        (long)lpprocSubClassProc);

    hCtl = GetDlgItem (hDlg, IDLISTBOX);
    i =  ID_FEET;
    while (LoadString (hInst, i, (LPSTR)buffer, MAXSTRLEN) != 0)
    {
      SendMessage (hCtl, LB_ADDSTRING, 0, (LONG) (LPSTR)buffer);
      i++;
    }

    SetFocus (hCtl);
    return (TRUE);

  case WM_COMMAND:
    switch (wParam)
    {
    case IDLISTBOX:
      if ( (HIWORD (lParam)) == 2)
      {
  hCtl = GetDlgItem (hDlg, IDLISTBOX);

  lListBoxSel = SendMessage (hCtl, LB_GETCURSEL, 0,
      (LONG) (LPSTR)"");
  SendMessage (hCtl, LB_GETTEXT, (WORD) lListBoxSel,
      (LONG) (LPSTR)szLBOutput);
  MessageBox (NULL, (LPSTR)szLBOutput, (LPSTR)"Chose from listbox:",
      MB_OK);
  return (TRUE);
      }
      else
  return (FALSE);
      break;

    case IDOK:
      hCtl = GetDlgItem (hDlg, IDLISTBOX);
      lListBoxSel = SendMessage (hCtl, LB_GETCURSEL, 0, (LONG) (LPSTR)"");
      if (lListBoxSel == -1L)
  i = 1;
      else
  SendMessage (hCtl, LB_GETTEXT, (WORD)lListBoxSel,
      (LONG) (LPSTR)szLBOutput);
      EndDialog (hDlg, TRUE);
      return (TRUE);

    case IDCANCEL:
      EndDialog (hDlg, TRUE);
      return (TRUE);

    default:
      return (FALSE);
    }
    break;

  default:
    return (FALSE);
    break;
  }
}


long  FAR PASCAL SubClassProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
{
  CallWindowProc (lpprocListBox, hWnd, message, wParam, lParam);
/*  Pass Info onto the default control procedure  */
  return 0L;
}


/* Procedure called when the application is loaded for the first time */
BOOL HelloInit (hInstance)
HANDLE hInstance;
{
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));

  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon          = LoadIcon (hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)"fonttest";
  pHelloClass->lpszClassName  = (LPSTR)"CallWindowProc";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree ( (HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;

  HelloInit (hInstance);
  hWnd = CreateWindow ( (LPSTR)"CallWindowProc",
      (LPSTR)"CallWindowProc ()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL);      /* no params to pass on */

  hInst = hInstance;

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
  }
  return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long  FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  switch (message)
  {
  case WM_COMMAND:
    lpprocDlgProc = MakeProcInstance ( (FARPROC)DialogBoxProc, hInst);
    DialogBox (hInst, MAKEINTRESOURCE (5), hWnd, lpprocDlgProc);
    FreeProcInstance ( (FARPROC)lpprocDlgProc);
    break;

  case WM_DESTROY:
    PostQuitMessage (0);
    break;

  default:
    return DefWindowProc (hWnd, message, wParam, lParam);
    break;
  }
  return (0L);
}




DDEAPP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DDE\DDEAPP\DDEAPP.C

/*
 *      ddeapp.c
 *
 *      This is a dummy application used to test the DDE capabilities
 *      of Microsoft Excel.
 *
 */

#include <windows.h>
#include "ddeapp.h"

#define GMEM_DDESHARE 0x2000
#define EXCEL

#ifdef EXCEL
#define szAppDef "Excel"
#define szDocDef "Sheet1"
#define szRefDef "r1c1:c1c2"
#define szDataDef "42"
#endif

#ifdef OPUS
#define szAppDef "Opus"
#define szDocDef "opus.doc"
#define szRefDef "bkmk1"
#define szDataDef "Foo bar."
#endif

#ifdef FISH
#define szAppDef "Fish"
#define szDocDef "sub"
#define szRefDef "bkmk1"
#define szDataDef "[l]"
#endif

#ifndef FISH
#ifndef OPUS
#ifndef EXCEL
#define szAppDef ""
#define szDocDef ""
#define szRefDef ""
#define szDataDef ""
#endif
#endif
#endif


long far pascal DdeWndProc(HWND, unsigned, int, long);
BOOL far pascal InitiateDlg(HWND, unsigned, int, long);
BOOL far pascal ExecuteDlg(HWND, unsigned, int, long);
BOOL far pascal PokeDlg(HWND, unsigned, int, long);
BOOL far pascal TermDlg(HWND, unsigned, int, long);
BOOL far pascal RequestDlg(HWND, unsigned, int, long);
BOOL far pascal UnadviseDlg(HWND, unsigned, int, long);

void PostClientMsg(int, int, ATOM, int);
void ChnlBox(HWND, int);
void ClipFmtBox(HWND,int);

BOOL FInit(int);
BOOL FGetAck(HWND);
int  IclListBox(HWND,int);


HANDLE  hinstDDE;
HWND    hwndDDE;
HBRUSH  hbrBack;
HCURSOR hcrsWait;
HCURSOR hcrsArrow;

/* supported clipboard formats */
#define szClipRTF   "Rich Text Format"
#define szClipLink  "Link"
#define szClipCSV   "Csv"
#define szClipBitPrinter  "Printer_Bitmap"
#define szClipMetaPrinter "Printer_Picture"

#define icfMax 9
#define icfRTF 5
#define icfCSV 6
#define icfBitPrinter 7
#define icfMetaPrinter 8
int rgcf[icfMax] = {
        CF_TEXT,
        CF_SYLK,
        CF_DIF,
        CF_BITMAP,
        CF_METAFILEPICT
};

int  cfLink;
int  iRadioButton, iRadioButtonTemp;
int  iResult, iAck;
BOOL fInInitiate = FALSE;
HWND hwndLink;

char szApp[256]  = szAppDef;
char szDoc[256]  = szDocDef;
char szRef[256]  = szRefDef;
char szData[245] = szDataDef;

int cfCur;
int iclCur;

PLCL **hplcl;           /* channel array */
PLDL **hpldl;           /* dependent link array */


/*      WinMain
 *
 *      Main entry point for DDE dummy application.
 *
 *      Arguments:
 *              hinst
 *              hinstPrev
 *              lpszCmdLine
 *              sw
 *
 *      Returns:
 *
 */
int far pascal WinMain(hinst, hinstPrev, lpszCmdLine, sw)
HANDLE hinst;
HANDLE hinstPrev;
char far *lpszCmdLine;
int sw;
{
   MSG msg;
   PL **HplInit();

   hinstDDE = hinst;

   if (!FInit(sw))
           return(0);

   hplcl = (PLCL **)HplInit(sizeof(CL));
   hpldl = (PLDL **)HplInit(sizeof(DL));

   rgcf[icfRTF] = RegisterClipboardFormat((LPSTR)szClipRTF);
   cfLink       = RegisterClipboardFormat((LPSTR)szClipLink);
   rgcf[icfCSV] = RegisterClipboardFormat((LPSTR)szClipCSV);
   rgcf[icfBitPrinter] = RegisterClipboardFormat((LPSTR)szClipBitPrinter);
   rgcf[icfMetaPrinter] = RegisterClipboardFormat((LPSTR)szClipMetaPrinter);
   while (GetMessage((MSG far *)&msg, NULL, 0, 0)) {
           TranslateMessage((MSG far *)&msg);
           DispatchMessage((MSG far *)&msg);
   }

   return(msg.wParam);
}


/* ----------------------------------------------------- */
void Error(sz)
char *sz;
{
   MessageBeep(MB_OK|MB_ICONHAND|MB_APPLMODAL);
   MessageBox(hwndDDE, (LPSTR)sz, (LPSTR)"DDE failure", MB_OK|MB_ICONHAND|MB_
}


/* -----------------------------------------------------
 *      CchSzLen
 *
 *      Returns the length of a null-terminated string.
 *
 *      Arguments:
 *              sz
 *
 *      Returns:
 *              length of the string
 */
int CchSzLen(sz)
char far *sz;
{
   int cch;

   cch = 0;
   while (*sz++)
           cch++;
   return(cch);
}


/* ----------------------------------------------------
 *      bltbx
 *
 *      Far block transfer.
 *
 *      Arguments:
 *              lpbFrom         source buffer
 *              lpbTo           destination buffer
 *              cb              number of bytes to move
 *
 *      Returns:
 *              nothing.
 *
 *      Warning:
 *              does not handle over-lapping transfer!
 */
void bltbx(lpbFrom, lpbTo, cb)
BYTE far *lpbFrom;
BYTE far *lpbTo;
unsigned cb;
{
        while (cb--)
                *lpbTo++ = *lpbFrom++;
}


/* -----------------------------------------------------
 *      FInit
 *
 *      Initializes the window app.
 *
 *      Arguments:
 *              sw              type of ShowWindow call to make on
 *                              first window created.
 *
 *      Returns:
 *              TRUE if successful
 */
BOOL FInit(sw)
int sw;
{
   WNDCLASS cls;
   HDC hdc;
   int dxScreen, dyScreen;

/* register window class */

   hbrBack   = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
   hcrsArrow = LoadCursor(NULL, IDC_ARROW);
   hcrsWait  = LoadCursor(NULL, IDC_WAIT);

   cls.lpszClassName = (LPSTR)"DdeApp";
   cls.lpfnWndProc   = DdeWndProc;
   cls.hInstance     = hinstDDE;
   cls.hIcon         = LoadIcon(NULL, IDI_HAND);
   cls.hCursor       = NULL;
   cls.lpszMenuName  = MAKEINTRESOURCE(mbDde);
   cls.hbrBackground = hbrBack;
   cls.style         = 0;
   cls.cbClsExtra    = cls.cbWndExtra = 0;
   if (!RegisterClass((WNDCLASS far *)&cls))
           return(FALSE);

/* create initial tiled window */

   hdc = CreateDC((LPSTR)"DISPLAY", NULL, NULL, NULL);
   dxScreen = GetDeviceCaps(hdc, HORZRES);
   dyScreen = GetDeviceCaps(hdc, VERTRES);
   DeleteDC(hdc);
   hwndDDE = CreateWindow((LPSTR)"DdeApp",
                   (LPSTR)"Acme DDE Application",
                   WS_OVERLAPPEDWINDOW,
                   0, 0, dxScreen/2, dyScreen/4,
                   NULL, NULL, hinstDDE, NULL);
   ShowWindow(hwndDDE, sw);

   return(TRUE);
}


/* ----------------------------------------------------- */

BOOL far pascal InitiateDlg(hdlg, wm, wParam, lParam)
HWND hdlg;
unsigned wm;
int wParam;
long lParam;
{
    switch (wm) {
    case WM_INITDIALOG:
            SetDlgItemText(hdlg, idtxtApp, (LPSTR)szApp);
            SetDlgItemText(hdlg, idtxtDoc, (LPSTR)szDoc);
            break;
    case WM_COMMAND:
            switch (wParam) {
            case IDOK:
                    GetDlgItemText(hdlg, idtxtApp, (LPSTR)szApp, sizeof(szApp
                    GetDlgItemText(hdlg, idtxtDoc, (LPSTR)szDoc, sizeof(szDoc
                    EndDialog(hdlg, TRUE);
                    break;
            case IDCANCEL:
                    EndDialog(hdlg, FALSE);
                    break;
            }
    default:
            return(FALSE);
    }
    return(TRUE);
}

/* ----------------------------------------------------- */

BOOL far pascal RequestDlg(hdlg, wm, wParam, lParam)
HWND hdlg;
unsigned wm;
int wParam;
long lParam;
{
   HWND hctl;
   int icf;

   switch (wm) {
   case WM_INITDIALOG:
           ChnlBox(hdlg, idlboxChnl);
           ClipFmtBox(hdlg, idlboxFmt);
           SetDlgItemText(hdlg, idtxtRef, (LPSTR)szRef);
           SendDlgItemMessage(hdlg, idlboxChnl, LB_SETCURSEL, 0, 0L);
           return(TRUE);
   case WM_COMMAND:
           switch (wParam) {
           case IDOK:
                   if ((iclCur = IclListBox(hdlg, idlboxChnl)) == -1)
                           return(TRUE);
                   if ((icf = SendMessage(GetDlgItem(hdlg, idlboxFmt),
                                   LB_GETCURSEL, 0, 0L)) == -1)
                           return(TRUE);
                   GetDlgItemText(hdlg, idtxtRef, (LPSTR)szRef, sizeof(szRef)
                   cfCur = rgcf[icf];
                   EndDialog(hdlg, TRUE);
                   return(TRUE);
           case IDCANCEL:
                   EndDialog(hdlg, FALSE);
                   return(TRUE);
           default:
                   return(FALSE);
           }
   default:
           return(FALSE);
   }
   return(TRUE);
}


/* ----------------------------------------------------- */
void LinkBox(hdlg, idlbox, icl)
HWND hdlg;
int idlbox;
int icl;
{
    int idl;
    PLDL *ppldl;
    HWND hctl;
    char sz[256];

    hctl = GetDlgItem(hdlg, idlbox);
    SendMessage(hctl, LB_RESETCONTENT, 0, 0L);
    ppldl = (PLDL *)LocalLock((HANDLE)hpldl);
    for (idl = 0; idl < ppldl->idlMax; idl++) {
        if (!ppldl->rgdl[idl].fUsed || ppldl->rgdl[idl].icl != icl)
                continue;
        GlobalGetAtomName(ppldl->rgdl[idl].atomRef, (LPSTR)sz, sizeof(sz));
        SendMessage(hctl, LB_ADDSTRING, 0, (DWORD)(LPSTR)sz);
        SendMessage(hctl, LB_GETCOUNT, 0, 0L);
    }
    LocalUnlock((HANDLE)hpldl);
}


/* ----------------------------------------------------- */

BOOL far pascal UnadviseDlg(hdlg, wm, wParam, lParam)
HWND hdlg;
unsigned wm;
int wParam;
long lParam;
{
    HWND hctl;
    int il;

    switch (wm) {
    case WM_INITDIALOG:
            ChnlBox(hdlg, idlboxChnl);
            SendDlgItemMessage(hdlg, idlboxChnl, LB_SETCURSEL, 0, 0L);
            return(TRUE);
    case WM_COMMAND:
            switch (wParam) {
            case IDOK:
                    if ((iclCur = IclListBox(hdlg, idlboxChnl)) == -1)
                            return(TRUE);
                    if ((il = SendMessage(hctl = GetDlgItem(hdlg, idlboxRef),
                                    LB_GETCURSEL, 0, 0L)) == -1)
                            return(TRUE);
                    SendMessage(hctl, LB_GETTEXT, il, (DWORD)(LPSTR)szRef);
                    EndDialog(hdlg, TRUE);
                    return(TRUE);
            case IDCANCEL:
                    EndDialog(hdlg, FALSE);
                    return(TRUE);
            case idlboxChnl:
                    if (HIWORD(lParam) == LBN_SELCHANGE) {
                            if ((iclCur = IclListBox(hdlg, idlboxChnl)) == -1
                                    return(TRUE);
                            LinkBox(hdlg, idlboxRef, iclCur);
                            return(TRUE);
                    }
                    return(FALSE);
            default:
                    return(FALSE);
            }
        default:
            return(FALSE);
    }
    return(TRUE);
}


/* ----------------------------------------------------- */

BOOL far pascal ExecuteDlg(hdlg, wm, wParam, lParam)
HWND hdlg;
unsigned wm;
int wParam;
long lParam;
{
   switch (wm) {
   case WM_INITDIALOG:
           ChnlBox(hdlg, idlboxChnl);
           SetDlgItemText(hdlg, idtxtRef, (LPSTR)szRef);
           SendDlgItemMessage(hdlg, idlboxChnl, LB_SETCURSEL, 0, 0L);
           break;
   case WM_COMMAND:
           switch (wParam) {
           case IDOK:
                   GetDlgItemText(hdlg, idtxtRef, (LPSTR)szRef, sizeof(szRef)
                   if ((iclCur = IclListBox(hdlg, idlboxChnl)) == -1)
                           return(TRUE);
                   EndDialog(hdlg, TRUE);
                   return(TRUE);
           case IDCANCEL:
                   EndDialog(hdlg, FALSE);
                   return(TRUE);
           }
   default:
           return(FALSE);
   }
   return(TRUE);
}

/* ----------------------------------------------------- */

BOOL far pascal PokeDlg(hdlg, wm, wParam, lParam)
HWND hdlg;
unsigned wm;
int wParam;
long lParam;
{
   switch (wm) {
   case WM_INITDIALOG:
           ChnlBox(hdlg, idlboxChnl);
           SetDlgItemText(hdlg, idtxtRef, (LPSTR)szRef);

           CheckRadioButton(hdlg, idradioText, idradioFile, idradioText);
           iRadioButtonTemp = idradioText;

           /* file is not implemented so it is disabled */
           EnableWindow( GetDlgItem(hdlg,idradioFile), FALSE );

           SendDlgItemMessage(hdlg, idlboxChnl, LB_SETCURSEL, 0, 0L);

           break;

   case WM_COMMAND:
           switch (wParam) {
           case IDOK:

                  iResult = GetDlgItemText(hdlg, idtxtData,
                                           (LPSTR)szData, sizeof(szData));
                  iResult = GetDlgItemText(hdlg, idtxtRef,
                                           (LPSTR)szRef, sizeof(szRef));
                  if ((iclCur = IclListBox(hdlg, idlboxChnl)) == -1)
                     return(TRUE);

                  iRadioButton = iRadioButtonTemp;

                  /* verify contents of Poke message */
                  /* if the button is csv
                        and the ref is < 5 characters
                        then if the data has a comma in it
                                then display a warning message
                   */

                  if ( iRadioButtonTemp == idradioCsv && iResult<5 ) {
                     /* check for comma in data */
                     MessageBox( GetFocus(), "Ref may be too small",
                                             "Warning", MB_OK);

                     }

                   EndDialog(hdlg, TRUE);
                   return(TRUE);
           case IDCANCEL:
                   EndDialog(hdlg, FALSE);
                   return(TRUE);

           case idradioText:
           case idradioCsv:
           case idradioFile:
                   CheckRadioButton(hdlg, idradioText, idradioFile,
                      (iRadioButtonTemp = wParam));
                   return(TRUE);
                   break;

           }
   default:
           return(FALSE);
   }
   return(TRUE);
}





/* ----------------------------------------------------- */

BOOL far pascal TermDlg(hdlg, wm, wParam, lParam)
HWND hdlg;
unsigned wm;
int wParam;
long lParam;
{
   switch (wm) {
   case WM_INITDIALOG:
           ChnlBox(hdlg, idlboxChnl);
           SendDlgItemMessage(hdlg, idlboxChnl, LB_SETCURSEL, 0, 0L);
           break;
   case WM_COMMAND:
           switch (wParam) {
           case IDOK:
                   if ((iclCur = IclListBox(hdlg, idlboxChnl)) == -1)
                           return(TRUE);
                   EndDialog(hdlg, TRUE);
                   break;
           case IDCANCEL:
                   EndDialog(hdlg, FALSE);
                   break;
           default:
                   break;
           }
   default:
           return(FALSE);
   }
   return(TRUE);
}


/* -----------------------------------------------------
 *      RemoveLinks
 *
 *      Removes all a channel's links from our data structures.
 *
 *      Arguments:
 *              icl             channel to remove links from
 *
 *      Returns:
 *              nothing.
 */
void RemoveLinks(icl)
int icl;
{
    int idl;
    PLDL *ppldl;

    ppldl = (PLDL *)LocalLock((HANDLE)hpldl);
    for (idl = 0; idl < ppldl->idlMax; idl++) {
            if (ppldl->rgdl[idl].fUsed && ppldl->rgdl[idl].icl == icl)
                    ppldl->rgdl[idl].fUsed = FALSE;
    }
    LocalUnlock((HANDLE)hpldl);
}



/* -----------------------------------------------------
 *      AddPl
 *
 *      Adds an item to a PL
 *
 *      Arguments:
 *              hpl
 *              pbData
 *
 *      Returns:
 *              Nothing.
 */
void AddPl(hpl, pbData)
PL **hpl;
BYTE *pbData;
{
   PL *ppl;
   BYTE *pb;
   int cbItem;
   int i, iMax;
   int dAlloc;

   ppl = (PL *)LocalLock((HANDLE)hpl);
   cbItem = ppl->cbItem;
   iMax = ppl->iMax;
   for (i = 0, pb = ppl->rg; i < iMax; i++, pb += cbItem) {
           if (!*(int *)pb)
                   goto Return;
   }
   dAlloc = ppl->dAlloc;
   LocalUnlock((HANDLE)hpl);
   LocalReAlloc((HANDLE)hpl, sizeof(PL)-1 + (iMax + dAlloc) * cbItem,
                   LMEM_MOVEABLE|LMEM_ZEROINIT);
   ppl = (PL *)LocalLock((HANDLE)hpl);
   ppl->iMax = iMax + dAlloc;
   pb = &ppl->rg[cbItem * iMax];
Return:
   bltbx((BYTE far *)pbData, (BYTE far *)pb, cbItem);
   *(int *)pb = TRUE;
   LocalUnlock((HANDLE)hpl);
}



/* -----------------------------------------------------
 *      HplInit
 *
 *      Initializes a plex
 *
 *      Arguments:
 *              cbItem          sizeof item to put in plex
 *
 *      Returns:
 *              handle to new plex
 */
PL **HplInit(cbItem)
int cbItem;
{
   PL **hpl, *ppl;

   hpl = (PL **)LocalAlloc(LMEM_MOVEABLE|LMEM_ZEROINIT, sizeof(PL)-1);
   ppl = (PL *)LocalLock((HANDLE)hpl);
   ppl->iMax = 0;
   ppl->dAlloc = 5;
   ppl->cbItem = cbItem;
   LocalUnlock((HANDLE)hpl);
   return(hpl);
}


/* -------------------------------------------------
 *      RemovePl
 *
 *      Removes an item from a plex
 *
 *      Arguments:
 *              hpl
 *              i
 *
 *      Returns:
 *              nothing.
 */
void RemovePl(hpl, i)
PL **hpl;
int i;
{
   PL *ppl;

   ppl = (PL *)LocalLock((HANDLE)hpl);
   *(int *)&ppl->rg[i * ppl->cbItem] = FALSE;
   LocalUnlock((HANDLE)hpl);
}


/* ----------------------------------------------------
 *      GetPl
 *
 *      gets an item from a plex
 *
 *      Arguments:
 *              hpl
 *              i
 *              pb
 *
 *      Returns:
 *              nothing.
 */
void GetPl(hpl, i, pb)
PL **hpl;
int i;
BYTE *pb;
{
    PL *ppl;

    ppl = (PL *)LocalLock((HANDLE)hpl);
    bltbx((BYTE far *)&ppl->rg[i * ppl->cbItem], (BYTE far *)pb, ppl->cbItem)
    LocalUnlock((HANDLE)hpl);
}


/* -----------------------------------------------------
 *      SendInitiate
 *
 *      Broadcasts WM_DDE_INITIATE message for the given reference string
 *
 *      Arguments:
 *              szApp
 *              szDoc
 *
 *      Returns:
 *              Nothing
 */
void SendInitiate(szApp, szDoc)
char *szApp;
char *szDoc;
{
    ATOM atomApp, atomDoc;

    atomApp = *szApp == 0 ? NULL : GlobalAddAtom((LPSTR)szApp);
    atomDoc = *szDoc == 0 ? NULL : GlobalAddAtom((LPSTR)szDoc);
    iAck = FALSE;        /* no conversation is active */
    fInInitiate = TRUE;
    SendMessage((HWND)-1, WM_DDE_INITIATE, hwndDDE, MAKELONG(atomApp, atomDoc
    fInInitiate = FALSE;
    if (atomApp != NULL)
            GlobalDeleteAtom(atomApp);
    if (atomDoc != NULL)
            GlobalDeleteAtom(atomDoc);
    if (!iAck)
      MessageBox( GetFocus(), "Nobody wants to talk.", "Warning", MB_OK);

}


/* -----------------------------------------------------
 *      SendTerminate
 *
 *      Arguments:
 *              icl
 *
 *      Returns:
 *              Nothing.
 */
void SendTerminate(icl)
int icl;
{
#ifdef BOGUS
    PostClientMsg(icl, WM_DDE_UNADVISE, 0, 0);
    if (!FGetAck(icl)) {
            Error("Terminate aborted:  Unadvise failed");
            return;
    }
#endif
    PostClientMsg(icl, WM_DDE_TERMINATE, 0, 0);
    RemoveLinks(icl);
    RemovePl(hplcl, icl);
}


/* -----------------------------------------------------
 *      SendRequest
 *
 *      Sends a WM_DDE_REQUEST message
 *
 *      Arguments:
 *              icl
 *              cf
 *              szRef
 *
 *      Returns:
 *              Nothing.
 */
void SendRequest(icl, cf, szRef)
int icl;
int cf;
char *szRef;
{
   ATOM atom;

   atom = GlobalAddAtom((LPSTR)szRef);
   PostClientMsg(icl, WM_DDE_REQUEST, atom, cf);
}


/* -----------------------------------------------------
 *      SendAdvise
 *
 *      Sends WM_DDE_ADVISE message to establish hot link
 *
 *      Arguments:
 *              icl
 *              cf
 *              szRef
 *
 *      Returns:
 *              Nothing.
 */
void SendAdvise(icl, cf, szRef)
int icl;
int cf;
char *szRef;
{
   ATOM atom;
   HANDLE hDdeln;
   DDELN far *lpddeln;
   BOOL fSuccess;
   DL dl;

   atom = GlobalAddAtom((LPSTR)szRef);
   hDdeln = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (DWORD)sizeof(DDELN));
   lpddeln = (DDELN far *)GlobalLock(hDdeln);
   lpddeln->cf = cf;
   lpddeln->fAckReq = FALSE;
   lpddeln->fDeferUpd = FALSE;
   GlobalUnlock(hDdeln);
   PostClientMsg(icl, WM_DDE_ADVISE, atom, hDdeln);
   if (!FGetAck(icl)) {
      Error("Advise Failed");
      GlobalFree(hDdeln);
      /* return; */
   }
   else {
     dl.icl = icl;
     dl.atomRef = atom;
     AddPl(hpldl, &dl);
   }
}


/* -----------------------------------------------------
 *      SendUnadvise
 *
 *      Breaks a link by sending an WM_DDE_UNADVISE.
 *
 *      Arguments:
 *              icl
 *              szRef
 *
 *      Returns:
 *              Nothing.
 */
void SendUnadvise(icl, szRef)
int icl;
char *szRef;
{
   ATOM atom;
   PLDL *ppldl;
   int idl;

   if (*szRef == 0) {
      PostClientMsg(icl, WM_DDE_UNADVISE, NULL, NULL);
      if (!FGetAck(icl)) {
         Error("Unadvise Failed");
         return;
      }
      RemoveLinks(icl);
      return;
   }
   atom = GlobalAddAtom((LPSTR)szRef);
   ppldl = (PLDL *)LocalLock((HANDLE)hpldl);
   for (idl = 0; idl < ppldl->idlMax; idl++) {
      if (ppldl->rgdl[idl].fUsed &&
          ppldl->rgdl[idl].atomRef == atom &&
          ppldl->rgdl[idl].icl == icl) {
         PostClientMsg(icl, WM_DDE_UNADVISE, atom, NULL);
         if (!FGetAck(icl)) {
            Error("Unadvise Failed");
            break;
         }
         GlobalDeleteAtom(atom);
         RemovePl(hpldl, idl);
         break;
      }
   }
   LocalUnlock((HANDLE)hpldl);
}


/* -----------------------------------------------------
 *      SendExecute
 *
 *      Sends a WM_DDE_EXECUTE.
 *
 *      Arguments:
 *              icl
 *              szExec
 *
 *      Returns:
 *              Nothing.
 */
void SendExecute(icl, szExec)
int icl;
char *szExec;
{
   int cch;
   char far *lpsz;
   HANDLE hDde;

   cch  = CchSzLen((char far *)szExec);
   hDde = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (DWORD)cch+1);
   lpsz = (char far *)GlobalLock(hDde);
   bltbx((char far *)szExec, lpsz, cch+1);
   GlobalUnlock(hDde);
   PostClientMsg(icl, WM_DDE_EXECUTE, hDde, NULL);
   if (!FGetAck(icl))
           Error("Execute Failed");
   GlobalFree(hDde);
}

/* -----------------------------------------------------
 *      SendPoke
 *
 *      Sends a WM_DDE_POKE
 *
 *      Arguments:
 *              icl
 *              szRef
 *              szPoke
 *
 *      Returns:
 *              Nothing.
 */
void SendPoke(icl, szRef, szPoke)
int icl;
char *szRef;
char *szPoke;
{
   int cch;
   DDEUP far *lpddeup;
   ATOM atom;
   HANDLE hDdeup;

   switch(iRadioButton) {

     case idradioText:
          MessageBox( GetFocus(), "Text", "Sending", MB_OK);
          break;

     case idradioCsv:
          MessageBox( GetFocus(), "Csv" , "Sending", MB_OK);
          break;

     case idradioFile:
          MessageBox( GetFocus(), "File" , "Sending", MB_OK);
          break;

     default:
          MessageBox( GetFocus(), "Unknown" , NULL, MB_OK);
          break;
   }

   atom   = GlobalAddAtom((LPSTR)szRef);
   cch    = CchSzLen((char far *)szPoke);
   hDdeup = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, (DWORD)sizeof(DDEUP)+c
   lpddeup            = (DDEUP far *)GlobalLock(hDdeup);
   lpddeup->cf        = (iRadioButton == idradioText) ? CF_TEXT : rgcf[icfCSV
   lpddeup->fAckReq   = FALSE;
   lpddeup->fRelease  = TRUE;
   bltbx((char far *)szPoke, lpddeup->rgb, cch+1);
   GlobalUnlock(hDdeup);
   PostClientMsg(icl, WM_DDE_POKE, atom, hDdeup);
   if (!FGetAck(icl))
           Error("Poke Failed");
}

/* -----------------------------------------------------
 *      BenchPoke
 *
 *      Sends a whole bunch of WM_DDE_POKEs
 *
 *      Arguments:
 *              icl
 *              szRef
 *              szPoke
 *
 *      Returns:
 *              Nothing.
 */
void BenchPoke(icl, szRef, szPoke)
int icl;
char *szRef;
char *szPoke;
{
  int i;
  int cch;
  DDEUP far *lpddeup;
  ATOM atom;
  HANDLE hDdeup;

  Error("Start");
  for (i=0; i<10000; i++)
          {
          PostClientMsg(icl, WM_DDE_TEST, NULL, NULL);
          if (!FGetAck(icl))
                  Error("No Ack Received");
          }
  Error("Stop");
}


/* ----------------------------------------------------- */
int Waste(hwnd, wm, wParam, lParam)
HWND hwnd;
int wm;
int wParam;
long lParam;
{
        return(TRUE);
}


/* ----------------------------------------------------- */
void BenchCall()
{
  long l;

  Error("Start");
  for (l=0; l<1000000; l++)
          if (!Waste(1234, WM_DDE_TEST, 5678, 0L))
                  Error("No Ack Received");
  Error("Stop");
}


/* -----------------------------------------------------
 *      FGetAck
 *
 *      Waits for an ACK message to be returned
 *
 *      Arguments:
 *              icl             channel to receive ACK from
 *
 *      Returns:
 *              TRUE if affirmative ACK received within a fairly long
 *              time period
 *
 *      Note:
 *              This method is not recommended for large applications.
 */
BOOL FGetAck(icl)
HWND icl;
{
    MSG msg;
    int tid;
    HWND hwndInt, hwndExt;
    BOOL fAck;
 msAckWait 60000 /* one minute */

    hwndExt = (*hplcl)->rgcl[icl].hwndExt;
    hwndInt = (*hplcl)->rgcl[icl].hwndInt;
#ifdef TIMER
    tid = SetTimer(NULL, 0, msAckWait, NULL);
#endif
    fAck = FALSE;
    for (;;) {
       GetMessage((MSG far *)&msg, NULL, 0, 0);
       if (msg.message == WM_DDE_ACK && msg.wParam == hwndExt)
          {
          if (LOWORD(msg.lParam) & 0x8000)
                  fAck = TRUE;
          if (HIWORD(msg.lParam)>= 0xc000)
                  GlobalDeleteAtom(HIWORD(msg.lParam));
          break;
          }
       TranslateMessage((MSG far *)&msg);
       DispatchMessage((MSG far *)&msg);
#ifdef TIMER
       if (PeekMessage((MSG far *)&msg, NULL,
                           WM_TIMER, WM_TIMER, PM_REMOVE) &&
                       msg.wParam == tid)
               break;
#endif
       WaitMessage();
    }
#ifdef TIMER
    KillTimer(NULL, tid);
#endif
    return(fAck);
}




/* -----------------------------------------------------
 * P A S T E  L I N K
 *
 *  Get the paste link string from the clipboard and display it.
 *
*/

void PasteLink ()
{
   int  isp;
   char far *lpch;
   char far *lpchT;
   RECT rect;
   HDC  hdc;
   HANDLE hClipboard;

   if (!OpenClipboard(hwndDDE))
       {
       Error("Cannot open clipboard");
       return;
       }

   if ((hClipboard = GetClipboardData(cfLink)) == NULL)
       {
       Error("Cannot render clipboard in Link format");
       }
   else
       {
       hdc = GetDC(hwndDDE);
       lpch = GlobalLock(hClipboard);
       GetClientRect(hwndDDE, (LPRECT)&rect);
       hbrBack = SelectObject(hdc, hbrBack);
       PatBlt(hdc, rect.left, rect.top, rect.right - rect.left,
                rect.bottom - rect.top, PATCOPY);
       SelectObject(hdc, hbrBack);
       for (isp=0, lpchT = lpch; isp < 2; lpchT++)
               if (!*lpchT)
                       {
                       *lpchT = ' ';
                       isp++;
                       }
       DrawText(hdc, lpch, CchSzLen(lpch), (LPRECT)&rect,
               DT_LEFT|DT_EXPANDTABS);
       ReleaseDC(hwndDDE, hdc);
       GlobalUnlock(hClipboard);
       }

   CloseClipboard();
}


/* -----------------------------------------------------
 *      DoDialog
 *
 *      Brings up a dialog.
 *
 *      Arguments:
 *              idd             dialog index to bring up
 *              lpfn            dialog proc to use
 *
 *      Returns:
 *              Dialog return code
 */
int FDoDialog(idd, lpfn)
int idd;
FARPROC lpfn;
{
   int w;

   lpfn = MakeProcInstance(lpfn, hinstDDE);
   w = DialogBox(hinstDDE, MAKEINTRESOURCE(idd), hwndDDE, lpfn);
   FreeProcInstance(lpfn);
   return(w);
}


/* ----------------------------------------------------
 *      ClipFmtBox
 *
 *      Initializes clipboard format dialog list box.
 *
 *      Arguments:
 *              hdlg
 *              idlbox
 *
 *      Returns:
 *              nothing.
 */
void ClipFmtBox(hdlg, idlbox)
HWND hdlg;
int idlbox;
{
    HWND hctl;
    int icf;
    int cf;
    char sz[256];

    hctl = GetDlgItem(hdlg, idlbox);
    for (icf = 0; icf < icfMax; icf++) {
        switch (cf = rgcf[icf]) {
        case CF_TEXT:
                bltbx((LPSTR)"CF_TEXT", (LPSTR)sz, 8);
                break;
        case CF_BITMAP:
                bltbx((LPSTR)"CF_BITMAP", (LPSTR)sz, 10);
                break;
        case CF_METAFILEPICT:
                bltbx((LPSTR)"CF_METAFILEPICT", (LPSTR)sz, 12);
                break;
        case CF_SYLK:
                bltbx((LPSTR)"CF_SYLK", (LPSTR)sz, 8);
                break;
        case CF_DIF:
                bltbx((LPSTR)"CF_DIF", (LPSTR)sz, 7);
                break;
        default:
                sz[GetClipboardFormatName(cf, (LPSTR)sz, sizeof(sz))] = 0;
                break;
        }
        SendMessage(hctl, LB_ADDSTRING, 0, (DWORD)(LPSTR)sz);
    }
}


/* ----------------------------------------------------
 *      ChnlBox
 *
 *      Initializes channel dialog list box.
 *
 *      Arguments:
 *              hdlg
 *              idlbox
 *
 *      Returns:
 *              nothing.
 */
void ChnlBox(hdlg, idlbox)
HWND hdlg;
int idlbox;
{
    HWND hctl;
    PLCL *pplcl;
    int icl;
    HWND hwndExt;
    char sz[256];

    hctl = GetDlgItem(hdlg, idlbox);
    pplcl = (PLCL *)LocalLock((HANDLE)hplcl);
    for (icl = 0; icl < pplcl->iclMax; icl++) {
        if (!pplcl->rgcl[icl].fUsed)
                continue;
        hwndExt = pplcl->rgcl[icl].hwndExt;
        GetWindowText(hwndExt, (LPSTR)sz, sizeof(sz));
        SendMessage(hctl, LB_ADDSTRING, 0, (DWORD)(LPSTR)sz);
    }
    LocalUnlock((HANDLE)hplcl);
}


/* ----------------------------------------------------
 *      IclListBox
 *
 *      Given a listbox, returns the icl for the channel selected in that
 *      listobx.
 *
 *      Arguments:
 *              hdlg            dialog handle
 *              idlbox          listbox item index.
 *
 *      Returns:
 *              channel index
 */
int IclListBox(hdlg, idlbox)
HWND hdlg;
int idlbox;
{
    int il, icl;
    PLCL *pplcl;

    if ((il = SendMessage(GetDlgItem(hdlg, idlbox), LB_GETCURSEL, 0, 0L)) ==
            return(-1);
    pplcl = (PLCL *)LocalLock((HANDLE)hplcl);
    for (icl = 0; icl < pplcl->iclMax; icl++) {
            if (pplcl->rgcl[icl].fUsed && il-- == 0)
                    goto Return;
    }
    icl = -1;
Return:
    LocalUnlock((HANDLE)hplcl);
    return(icl);
}

/* ---------------------------------------------------- */

void PostClientMsg(icl, wm, atom, cf)
int icl;
int wm;
ATOM atom;
int cf;
{
    HWND hwndExt;
    PLCL *pplcl;

    pplcl = (PLCL *)LocalLock((HANDLE)hplcl);
    hwndExt = pplcl->rgcl[icl].hwndExt;
    PostMessage(hwndExt, wm,
            (WORD)pplcl->rgcl[icl].hwndInt,
            MAKELONG(cf, atom));
    LocalUnlock((HANDLE)hplcl);
}


int cxScrollLast;
int cyScrollLast;

/* ---------------------------------------------------- */
FShowMetaFilePict( hdc, prc, hmfp, cxScroll, cyScroll )
HDC      hdc;
register PRECT  prc;
HANDLE   hmfp;
int      cxScroll, cyScroll;
{       /* Display a metafile picture in the passed rectangle.
           { cxScroll, cyScroll } is the origin within the picture at which
                        to start displaying.
           Set cxScrollLast, cyScrollLast if they have not been set already *
   HDC hMemDC;
   HBITMAP hbm;
   LPMETAFILEPICT lpmfp;
   METAFILEPICT mfp;
   int mmT;
   POINT pt, ptT;
   int level;
   int cxRect = prc->right - prc->left;
   int cyRect = prc->bottom - prc->top;
   int cxBitmap;
   int cyBitmap;
   int f=FALSE;

   if ((lpmfp=(LPMETAFILEPICT)GlobalLock( hmfp )) != NULL)
      {
      int mm;
      METAFILEPICT mfp;

      mfp = *lpmfp;
      GlobalUnlock( hmfp );

      if ((level = SaveDC( hdc )) != 0)
         {
         /* Compute size of picture to be displayed */

         switch (mfp.mm)
                 {
         case MM_ISOTROPIC:
                 goto NoScroll;
         case MM_ANISOTROPIC:
                 if (mfp.xExt > 0 && mfp.yExt > 0)
                         {
                         /* suggested a size */
                         mm = MM_HIMETRIC;
                         goto GetSize;
                         }
NoScroll:
                 /* no suggested sizes, use the window size */
                 cyScrollLast = 0;   /* Not scrollable; resizes into avail. r
                 cxScrollLast = 0;
                 cxBitmap = prc->right - prc->left;
                 cyBitmap = prc->bottom - prc->top;
                 break;

         default:
                 mm = mfp.mm;
GetSize:
                 mmT = SetMapMode(hdc, mm);
                 *((long *)&ptT) = SetWindowOrg(hdc, 0, 0);
                 pt.x = mfp.xExt;
                 pt.y = mfp.yExt;
                 LPtoDP(hdc, (LPPOINT)&pt, 1);
                 cxBitmap = pt.x;
                 cyBitmap = (mm == MM_TEXT) ? pt.y : -pt.y;
                 SetMapMode(hdc, mmT);
                 SetWindowOrg(hdc, ptT.x, ptT.y);

CheckScroll:
                 if (cxScrollLast == -1)
                         {
                         cxScrollLast = cxBitmap - (prc->right - prc->left);
                         if ( cxScrollLast < 0)
                                 cxScrollLast = 0;
                         }
                 if (cyScrollLast == -1)
                         {
                         cyScrollLast = cyBitmap - (prc->bottom - prc->top);
                         if ( cyScrollLast < 0)
                                 cyScrollLast = 0;
                         }
                 break;
                 }

         /* We make the "viewport" to be an area the same size as the */
         /* clipboard object, and set the origin and clip region so as */
         /* to show the area we want. Note that the viewport may well be */
         /* bigger than the window. */
         IntersectClipRect( hdc, prc->left, prc->top,
                                 prc->right, prc->bottom );
         SetMapMode( hdc, mfp.mm );

         SetViewportOrg( hdc, prc->left - cxScroll, prc->top - cyScroll );
         switch (mfp.mm)
                 {
         case MM_ISOTROPIC:
                 if (mfp.xExt && mfp.yExt)
                         /* So we get the correct shape rectangle when
                         SetViewportExt gets called */
                         SetWindowExt( hdc, mfp.xExt, mfp.yExt );
                 break;

         case MM_ANISOTROPIC:
                 SetWindowExt(hdc, cxBitmap, cyBitmap);
                 SetViewportExt( hdc, cxBitmap, cyBitmap );
                 break;
                 }

         /* Since we may have scrolled, force brushes to align */
         SetBrushOrg( hdc, cxScroll - prc->left, cyScroll - prc->top );
         f = PlayMetaFile( hdc, mfp.hMF );

NoDisplay:
         RestoreDC( hdc, level );
         }
      }

return f;

}

/* ------------------------------------------------------
 *      DdeWndProc
 *
 *      Main window proc for the DDE application.
 *
 *      Arguments:
 *              hwnd            window receiving the message
 *              wm              the message
 *              wParam, lParam  additional info for the message
 *
 *      Returns:
 *              Depends on the message.
 */
long far pascal DdeWndProc(hwnd, wm, wParam, lParam)
HWND hwnd;
unsigned wm;
int wParam;
long lParam;
{
   int icl;
   PLCL *pplcl;
   char sz[256];
   char *pch;
   RECT rect;
   HDC hdc;
   DDEUP far *lpddeup;
   CL cl;
   HBITMAP hbmp;
   HDC hdcMem;
   BITMAP bmp;
   METAFILEPICT far *lpmfp;
   HANDLE hMF;
   BOOL fRelease;

   switch (wm) {

           case WM_DESTROY:
                   PostQuitMessage(0);
                   break;

           case WM_COMMAND:

                   switch (wParam) {

                   case idmInitiate:
                           if (FDoDialog(iddInitiate, InitiateDlg))
                                   SendInitiate(szApp, szDoc);
                           return(0L);

                   case idmTerminate:
                           if (FDoDialog(iddTerminate, TermDlg))
                                   SendTerminate(iclCur);
                           return(0L);

                   case idmRequest:
                           if (FDoDialog(iddRequest, RequestDlg))
                                   SendRequest(iclCur, cfCur, szRef);
                           return(0L);

                   case idmAdvise:
                           if (FDoDialog(iddAdvise, RequestDlg))
                                   SendAdvise(iclCur, cfCur, szRef);
                           return(0L);

                   case idmUnadvise:
                           if (FDoDialog(iddUnadvise, UnadviseDlg))
                                   SendUnadvise(iclCur, szRef);
                           return(0L);

                   case idmPoke:
                           if (FDoDialog(iddPoke, PokeDlg))
                                   SendPoke(iclCur, szRef, szData);
                           return(0L);

                   case idmExecute:
                           if (FDoDialog(iddExecute, ExecuteDlg))
                                   SendExecute(iclCur, szRef);
                           return(0L);

                   case idmBench:
                           if (FDoDialog(iddPoke, PokeDlg))
                                   BenchPoke(iclCur, szRef, szData);
                           return(0L);

                   case idmCBench:
                           BenchCall();
                           return(0L);

                   case idmPasteLink:
                           PasteLink();
                           return(0L);

                   default:
                           break;

                   }
                   break;

           case WM_DDE_TERMINATE:
                   pplcl = (PLCL *)LocalLock((HANDLE)hplcl);
                   for (icl = 0; icl < pplcl->iclMax; icl++) {
                           if (!pplcl->rgcl[icl].fUsed ||
                               pplcl->rgcl[icl].hwndExt != wParam)
                                   continue;
                           LocalUnlock((HANDLE)hplcl);
                           SendTerminate(icl);
                           return(0L);
                           }
                   LocalUnlock((HANDLE)hplcl);
                   return(0L);

           case WM_DDE_ACK:
                   if (fInInitiate) {
                           cl.hwndInt = hwnd;
                           cl.hwndExt = (HWND)wParam;
                           cl.fClient = TRUE;
                           AddPl(hplcl, &cl);
                           GlobalDeleteAtom(LOWORD(lParam));
                           iAck = TRUE;
                   } else {
                           if (LOWORD(lParam) & 0x8000)
                                   Error("Got ACK");
                           else
                                   Error("Got NACK");
                   }
                   GlobalDeleteAtom(HIWORD(lParam));
                   return(0L);

           case WM_DDE_DATA:
                   GetClientRect(hwndDDE, (LPRECT)&rect);
                   hdc = GetDC(hwndDDE);
                   hbrBack = SelectObject(hdc, hbrBack);
                   PatBlt(hdc, rect.left, rect.top,
                                   rect.right - rect.left,
                                   rect.bottom - rect.top,
                                   PATCOPY);
                   SelectObject(hdc, hbrBack);
                   lpddeup = (DDEUP far *)GlobalLock(LOWORD(lParam));
                   if (lpddeup->fAckReq)
                           PostMessage(wParam, WM_DDE_ACK,
                                   hwnd, MAKELONG(0x8000, HIWORD(lParam)));
                   else
                           GlobalDeleteAtom(HIWORD(lParam));
                   switch (lpddeup->cf)
                           {
                   default:
                           if (lpddeup->cf == rgcf[icfBitPrinter])
                                   goto GotBitmap;
                           if (lpddeup->cf == rgcf[icfMetaPrinter])
                                   goto GotMetafile;
                           if (lpddeup->cf != rgcf[icfRTF] &&
                                   lpddeup->cf != rgcf[icfCSV])
                                   break;
                           /* else fall through */
                   case CF_SYLK:
                   case CF_DIF:
                   case CF_TEXT:
                           DrawText(hdc, lpddeup->rgb,
                                           CchSzLen(lpddeup->rgb),
                                           (LPRECT)&rect,
                                           DT_LEFT|DT_EXPANDTABS);
                           break;
                   case CF_BITMAP:
GotBitmap:
                           hdcMem = CreateCompatibleDC(hdc);
                           hbmp = *(HBITMAP far *)&lpddeup->rgb[0];
                           GetObject(hbmp, sizeof(BITMAP), (BYTE far *)&bmp);
                           hbmp = SelectObject(hdcMem, hbmp);
                           BitBlt(hdc, 0, 0, bmp.bmWidth, bmp.bmHeight,
                                           hdcMem, 0, 0, SRCCOPY);
                           hbmp = SelectObject(hdcMem, hbmp);
                           DeleteDC(hdcMem);
                           if (lpddeup->fRelease)
                                   DeleteObject(hbmp);
                           break;
                   case CF_METAFILEPICT:
GotMetafile:
                           GetClientRect(hwndDDE, (LPRECT)&rect);
                           FShowMetaFilePict(hdc, &rect,
                                     *((HANDLE far *)&lpddeup->rgb[0]),
                                             0, 0);
                           if (lpddeup->fRelease)
                                   DeleteMetaFile(*((HANDLE far *)&lpddeup->r
                           break;
                   }
                   ReleaseDC(hwndDDE, hdc);
                   fRelease = lpddeup->fRelease;
                   GlobalUnlock(LOWORD(lParam));
                   if (fRelease)
                           GlobalFree(LOWORD(lParam));
                   return(0L);

           default:
                   break;

   }
   return(DefWindowProc(hwnd, wm, wParam, lParam));
}




DDESPY.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DDE\DDESPY\DDESPY.C

/*---------------------------------------------------------------------------
|   ddespy.c      - Windows message spy application
|
|   Notes:
|       "->" means "a pointer to", "->>" means "a handle to"
|
|   History:
|       01/01/87 Created
|
\*---------------------------------------------------------------------------

/*---------------------------------------------------------------------------
|
|   g e n e r a l   c o n s t a n t s
|
\*---------------------------------------------------------------------------

 DEBUGDX   100    /* Window sizes */
#define DEBUGDY   100
#define DEBUGX    50
#define DEBUGY    50
#define DEBUGXINC 10
#define DEBUGYINC 30

/*---------------------------------------------------------------------------
|
|   i n c l u d e   f i l e s
|
\*---------------------------------------------------------------------------

#include <windows.h>
#include <winexp.h>
#include "ddespy.h"
#include "dde.h"

/*---------------------------------------------------------------------------
|
|   g l o b a l   v a r i a b l e s
|
\*---------------------------------------------------------------------------

static  char    acAppName[]="DDE SPY";

static  HANDLE  hInst;
HWND    hSpyApp;
HWND    hSpyChild;
static  FARPROC fpxProcAbout;
static  FARPROC fpxProcSpySet;
static  FARPROC fpxSpyProc;
/* static  FARPROC fpxMsgHook1;
   static  FARPROC fpxMsgHook2;
   static  FARPROC fpxOldHook1;
   static  FARPROC fpxOldHook2;
 */

/* Global variables describing the state of the window being spyied on */
static  BOOL    gbSpyOn  = FALSE;
static  HWND    ghSpyWnd = NULL;
static  BOOL    gbHook   = FALSE;
static  FARPROC OldSpyProc;

BOOL gbMouse = TRUE;          /* TRUE if mouse messages are to be ignored */
BOOL gbNC    = TRUE;

static BOOL bDisableMessages; /*  TRUE if all messages are to be ignored */


struct TEXT_STRUCT {
    int  iFirst;                  /* First line in que */
    int  iCount;                  /* Number of lines in que */
    int  iTop;                    /* Line at top of window */
    int  iLeft;                   /* X offset of the window */
    char *Text[MAXLINES];         /* Que of Text in window */
    int  Len[MAXLINES];           /* String Length of text */
    int  MaxLen;                  /* Max String Length */
};

typedef struct TEXT_STRUCT *PTXT; /* pointer to a text struct */
typedef PTXT               *HTXT; /* Handle to a text struct */

static int Tdx = 0;        /* Text font size */
static int Tdy = 0;

static HWND hERROR;

/*---------------------------------------------------------------------------
|
|   f u n c t i o n   d e f i n i t i o n s
|
\*---------------------------------------------------------------------------

long FAR PASCAL MyWndProc(HWND, unsigned, WORD, LONG);
long FAR PASCAL SpyProc(HWND, unsigned, WORD, LONG);

/* HWND CreateDebugWindow (HWND,char *,BOOL); */
void Error (char *);
BOOL SSEqualToDS (void);

/*
  long FAR PASCAL MsgHook1(WORD, WORD, LPMSG);
  long FAR PASCAL MsgHook2(WORD, WORD, LPMSG);
 */

extern void FAR PASCAL KillHook();
extern BOOL FAR PASCAL InitHook( HWND );
extern long FAR PASCAL DebugWndProc(HWND, unsigned, WORD, LONG);
extern HWND FAR PASCAL CreateDebugWin (HANDLE, HWND);

extern void FAR PASCAL PassFileToDLL(int);

/*---------------------------------------------------------------------------
|   DlgAbout( hDlg, uiMessage, wParam, lParam )
|
|   Description:
|       This function handles messages belonging to the "About" dialog box.
|       The only message that it looks for is WM_COMMAND, indicating the use
|       has pressed the "OK" button.  When this happens, it takes down
|       the dialog box.
|
|   Arguments:
|       hDlg            window handle of about dialog window
|       uiMessage       message number
|       wParam          message-dependent
|       lParam          message-dependent
|
|   Returns:
|       TRUE if message has been processed, else FALSE
|
\*---------------------------------------------------------------------------

BOOL FAR PASCAL DlgAbout( hDlg, uiMessage, wParam, lParam )
HWND     hDlg;
unsigned uiMessage;
WORD     wParam;
long     lParam;
{
    switch (uiMessage) {
        case WM_COMMAND:
            EndDialog(hDlg,TRUE);
            return(TRUE);
        case WM_INITDIALOG:
            return(TRUE);
    }
    return(FALSE);
}


VOID SetDlgText (hDlg,hWnd)
  HWND hDlg;
  HWND hWnd;
{
  static char acCaption[100];
  HWND hParent;

  if (IsWindow(hWnd)) {
     acCaption[0] = '\0';
     GetWindowText (hWnd,(LPSTR)acCaption,100);
     SetDlgItemText(hDlg,ID_CAPTION,(LPSTR)acCaption);
     hParent = GetParent(hWnd);
     if (IsWindow(hParent)) {
        GetWindowText (hParent,(LPSTR)acCaption,100);
        SetDlgItemText(hDlg,ID_PARENT,(LPSTR)acCaption);
     }
     else {
        SetDlgItemText(hDlg,ID_PARENT,(LPSTR)"<NO PARENT>");
     }

     GetModuleFileName(GetWindowWord(hWnd,GWW_HINSTANCE),
                       (LPSTR)acCaption,100 );
  }
  else {
     SetDlgItemText(hDlg,ID_CAPTION,(LPSTR)"<Undefined>");
     SetDlgItemText(hDlg,ID_MODULE, (LPSTR)"<Undefined>");
     SetDlgItemText(hDlg,ID_PARENT, (LPSTR)"<Undefined>");
  }
}

/*---------------------------------------------------------------------------
|   DlgSpySet( hDlg, uiMessage, wParam, lParam )
|
|   Description:
|       This function handles messages belonging to the SpySet dialog box.
|
|   Arguments:
|       hDlg            window handle of about dialog window
|       uiMessage       message number
|       wParam          message-dependent
|       lParam          message-dependent
|
|   Returns:
|       TRUE if message has been processed, else FALSE
|
\*---------------------------------------------------------------------------

BOOL FAR PASCAL DlgSpySet( hDlg, uiMessage, wParam, lParam )
HWND     hDlg;
unsigned uiMessage;
WORD     wParam;
long     lParam;
{
    static BOOL bNC;
    static BOOL bMouse;
    static HWND hSpyWnd;
    static BOOL bHook;
    static int  iCaptureState;  /* 0 = not captured, 1 = captured */

    POINT  pCursor;

    switch (uiMessage) {
        case WM_COMMAND:
            switch (wParam) {

              case ID_OK:
                SendMessage (hSpyApp,WM_COMMAND,SPYOFF,0L);
                gbNC     = bNC;
                gbMouse  = bMouse;
                ghSpyWnd = hSpyWnd;
                gbHook   = bHook;
                if (gbHook) hSpyWnd = NULL;
                SendMessage (hSpyApp,WM_COMMAND,SPYON,0L);

                /* Fall through to cancel */
              case ID_CANCEL:
                iCaptureState++;
                EndDialog(hDlg,TRUE);
                return TRUE;

              case ID_MOUSE:
                SendDlgItemMessage(hDlg,ID_MOUSE,BM_SETCHECK,bMouse ^= 1,0L);
                return TRUE;

              case ID_NC:
                SendDlgItemMessage(hDlg,ID_NC,BM_SETCHECK,bNC ^= 1,0L);
                return TRUE;


/*              case ID_ALL:
 *               SendDlgItemMessage(hDlg,ID_ALL,BM_SETCHECK,bHook ^= 1,0L);
 *               if (bHook) hSpyWnd = NULL;
 *               SetDlgText (hDlg,hSpyWnd);
 *               return TRUE;
 */
            }
            break;

        case WM_INITDIALOG:
            SendDlgItemMessage(hDlg,ID_NC   ,BM_SETCHECK,bNC   =gbNC,0L);
            SendDlgItemMessage(hDlg,ID_MOUSE,BM_SETCHECK,bMouse=gbMouse,0L);
            SendDlgItemMessage(hDlg,ID_ALL  ,BM_SETCHECK,bHook =gbHook,0L);
            hSpyWnd = ghSpyWnd;
            if (bHook) hSpyWnd = NULL;
            SetDlgText (hDlg,hSpyWnd);
            iCaptureState=0;
            return TRUE;

        /*
         * When the dialog box is being deactivated by the user clicking
         * in a window of another application find out what window and
         * steal the focus back.  If the user tries to spy on the same
         * window two times the focus is not stolen back.
         */

        case WM_ACTIVATEAPP:
            if (wParam == 0 && !iCaptureState) {
               HWND hWnd;
               GetCursorPos((LPPOINT)&pCursor);
               hWnd = WindowFromPoint(pCursor);
               if (hWnd != hSpyWnd) {
                  SetDlgText (hDlg,hWnd);
                  PostMessage(hDlg,WM_ACTIVATE,1,0L);/* Trick used to get the
                  hSpyWnd = hWnd;                    /* focus back */
                  bHook   = FALSE;
                  SendDlgItemMessage(hDlg,ID_ALL,BM_SETCHECK,bHook,0L);
               }
               return TRUE;
            }
            return FALSE;

        default:
            return FALSE;
     }
 }


/*---------------------------------------------------------------------------
|   MyInit( hInstance )
|
|   Description:
|       This is called when the application is first loaded into
|       memory.  It performs all initialization that doesn't need to be done
|       once per instance.
|
|   Arguments:
|       hInstance       instance handle of current instance
|
|   Returns:
|       TRUE if successful, FALSE if not
|
\*---------------------------------------------------------------------------

BOOL MyInit(hInstance,hPrevInstance)
   HANDLE hInstance;
   HANDLE hPrevInstance;
{
    WNDCLASS rClass;

/* Register a class for the main application window */

    if (!hPrevInstance) {
       rClass.hCursor        = LoadCursor(NULL,IDC_ARROW);
       rClass.hIcon          = LoadIcon(hInstance,(LPSTR)"AppIcon");
       rClass.lpszMenuName   = (LPSTR)"MyMenu";
       rClass.lpszClassName  = (LPSTR)acAppName;
       rClass.hbrBackground  = (HBRUSH)COLOR_WINDOW + 1;
       rClass.hInstance      = hInstance;
       rClass.style          = CS_HREDRAW | CS_VREDRAW;
       rClass.lpfnWndProc    = MyWndProc;
       rClass.cbWndExtra     = 0;
       rClass.cbClsExtra     = 0;

       return RegisterClass((LPWNDCLASS)&rClass);
    }
    return TRUE;
}

/*---------------------------------------------------------------------------
|
|   w i n m a i n
|
\*---------------------------------------------------------------------------


/*---------------------------------------------------------------------------
|   WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
|
|   Description:
|       The main procedure for the App.  After initializing, it just goes
|       into a message-processing loop until it gets a WM_QUIT message
|       (meaning the app was closed).
|
|   Arguments:
|       hInstance       instance handle of this instance of the app
|       hPrevInstance   instance handle of previous instance, NULL if first
|       lpszCmdLine     ->null-terminated command line
|       cmdShow         specifies how the window is initially displayed
|
|   Returns:
|       The exit code as specified in the WM_QUIT message.
|
\*---------------------------------------------------------------------------

int PASCAL WinMain( hInstance, hPrevInstance, fpcCmdLine, iCmdShow )
HANDLE  hInstance, hPrevInstance;
LPSTR   fpcCmdLine;
int     iCmdShow;
{
    MSG   rMsg;
    HWND  hWnd;
    HMENU hMenu;
    HDC   hdc;
    int   dxpScreen;
    int   dypScreen;

    /* Call initialization procedure */
    if (!MyInit(hInstance,hPrevInstance))
        return FALSE;

/* create initial tiled window */

        hdc = CreateDC((LPSTR)"DISPLAY", NULL, NULL, NULL);
        dxpScreen = GetDeviceCaps(hdc, HORZRES);
        dypScreen = GetDeviceCaps(hdc, VERTRES);
        DeleteDC(hdc);

    /* Save instance handle for DialogBoxs */
    hInst = hInstance;

    hSpyApp = CreateWindow ((LPSTR)acAppName,
                            (LPSTR)acAppName,
                            WS_TILEDWINDOW,
                            0,           /*  x */
                            dypScreen/2, /*  y */
                            dxpScreen,   /* cx */
                            dypScreen/2, /* cy */
                            (HWND)NULL,        /* no parent */
                            (HMENU)NULL,       /* use class menu */
                            (HANDLE)hInstance, /* handle to window instance *
                            (LPSTR)NULL        /* no params to pass on */
                           );

    ShowWindow (hSpyApp,iCmdShow);

    /* Bind callback function with module instance */
    fpxProcAbout  = MakeProcInstance((FARPROC)DlgAbout,hInstance);
    fpxProcSpySet = MakeProcInstance((FARPROC)DlgSpySet,hInstance);
    fpxSpyProc    = MakeProcInstance((FARPROC)SpyProc,hInstance);
 /*
    fpxMsgHook1   = MakeProcInstance((FARPROC)MsgHook1,hInstance);
    fpxMsgHook2   = MakeProcInstance((FARPROC)MsgHook2,hInstance);
 */
    /* Insert "About..." into system menu */
    hMenu = GetSystemMenu(hSpyApp,FALSE);
    ChangeMenu(hMenu,0,NULL,999,MF_APPEND | MF_SEPARATOR);
    ChangeMenu(hMenu,0,(LPSTR)"About...",CMDABOUT,MF_APPEND | MF_STRING);

    /*
     * Polling messages from event queue
     */

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

    FreeProcInstance (fpxProcAbout);
    FreeProcInstance (fpxProcSpySet);
    FreeProcInstance (fpxSpyProc);
 /*
    FreeProcInstance (fpxMsgHook1);
    FreeProcInstance (fpxMsgHook2);
  */
    return((int)rMsg.wParam);
}

/*---------------------------------------------------------------------------
|
|   w i n d o w   p r o c s
|
\*---------------------------------------------------------------------------

/*---------------------------------------------------------------------------
|   MyWndProc( hWnd, uiMessage, wParam, lParam )
|
|   Description:
|       The window proc for the app's main (tiled) window.  This processes al
|       of the parent window's messages.
|
|   Arguments:
|       hWnd            window handle for the parent window
|       uiMessage       message number
|       wParam          message-dependent
|       lParam          message-dependent
|
|   Returns:
|       0 if processed, nonzero if ignored
|
\*---------------------------------------------------------------------------

long FAR PASCAL MyWndProc( hWnd, uiMessage, wParam, lParam )
HWND     hWnd;
unsigned uiMessage;
WORD     wParam;
long     lParam;
{
        HANDLE hqel;
        QEL *pqel;
        HMENU hMenu;
        RECT  rRect;
        char rgch[32];
        char rgch2[32];

    /*
     *  if the message is less than WM_USER then it is a message to
     *  be proccessed
     */

    switch (uiMessage) {

        case WM_CREATE:
            hSpyChild = CreateDebugWin(hInst, hWnd);
            return 0L;

        case WM_INITMENU:
            return 0L;

        case WM_COMMAND:
            if (lParam == 0) {
                switch (wParam) {
                    case SPYOFF:
                        if (gbSpyOn) {

                           KillHook();
                         /*
                           SetWindowsHook(WH_GETMESSAGE, fpxOldHook1);
                           SetWindowsHook(WH_CALLWNDPROC, fpxOldHook2);
                          */
                           gbSpyOn = FALSE;
                           hMenu = GetMenu (hWnd);
                           ChangeMenu (hMenu,SPYOFF,(LPSTR)"Spy On",SPYON,
                                       MF_CHANGE | MF_ENABLED);
                        }
                        return(0L);

                    case SPYON:
                        if (!gbSpyOn) {
                           InitHook(hSpyChild);
                         /*
                           fpxOldHook1 = SetWindowsHook(WH_GETMESSAGE, fpxMsg
                           fpxOldHook2 = SetWindowsHook(WH_CALLWNDPROC,fpxMsg
                          */
                           gbSpyOn = TRUE;
                           hMenu = GetMenu (hWnd);
                           ChangeMenu (hMenu,SPYON,(LPSTR)"Spy Off",SPYOFF,
                                       MF_CHANGE | MF_ENABLED);
                        }
                        return(0L);

                    case SPYSET:
                        DialogBox(hInst,MAKEINTRESOURCE(DLGSPY),hWnd,fpxProcS
                        return (0L);
                }
            }
            break;

        case WM_SYSCOMMAND:
            if (wParam == CMDABOUT) {
                DialogBox(hInst,MAKEINTRESOURCE(ABOUTBOX),hWnd,fpxProcAbout);
                return(0L);
            }
            break;

        case WM_SIZE:
            MoveWindow (hSpyChild,0,0,LOWORD (lParam),HIWORD(lParam),TRUE);
            return 0L;

        case WM_DESTROY:
            SendMessage (hSpyApp,WM_COMMAND,SPYOFF,0L);

            PostQuitMessage(0L);   /* Kill the main window */
            return 0L;
    }
    return DefWindowProc (hWnd,uiMessage,wParam,lParam);
}


/*---------------------------------------------------------------------------
|   SpyProc( hWnd, uiMessage, wParam, lParam )
|
|   Description:
|       The window proc for the app being spied on
|
|   Arguments:
|       hWnd            window handle for the parent window
|       uiMessage       message number
|       wParam          message-dependent
|       lParam          message-dependent
|
|   Returns:
|       0 if processed, nonzero if ignored
|
\*---------------------------------------------------------------------------

long FAR PASCAL SpyProc( hWnd, uiMessage, wParam, lParam )
HWND     hWnd;
unsigned uiMessage;
WORD     wParam;
long     lParam;
{
    /*
     *  This procedure is called from another task through a Data thunk and
     *  SS != DS (the SS is for the other task).  Watch out!!
     */

    PostMessage (hSpyApp,uiMessage + WM_USER,wParam,lParam);
    if (uiMessage == WM_DESTROY) {
       /*
        * The user is quitting the application being spyed on.
        * unhook the spy procedure or funny things may happen.
        */
       SendMessage (hSpyApp,WM_COMMAND,SPYOFF,0L);
       ghSpyWnd = NULL;
    }
    return CallWindowProc(OldSpyProc,hWnd,uiMessage,wParam,lParam);
}



/*---------------------------------------------------------------------------
|
|   w i n d o w   p r o c s
|
\*---------------------------------------------------------------------------


/*---------------------------------------------------------------------------
|  THIS IS NEVER CALLED.
|  CreateDebugWindow (hWnd, pcText,bTiled)
|
|   Description:
|     Creates a tiled window for the depositing of debuging messages.
|
|   Arguments:
|     hWnd   - Window handle of the parent window.
|     pcText - String to appear in the caption bar of the debuging window
|     bTiled - FALSE => window is a popup,  Tiled otherwise.
|
|   Returns:
|     A window handle of the debuging window, or NULL if a error occured.
|
\*---------------------------------------------------------------------------

HWND CreateDebugWindow (hParent,pchName,bTiled)
    HWND   hParent;
    char   *pchName;
    BOOL   bTiled;
{
    static int  iNextX = DEBUGX;
    static int  iNextY = DEBUGY;
    HWND        hWnd;

    MessageBeep(1);
    MessageBox( hParent, "We're here", NULL, MB_OK);
 /*
    hWnd = CreateDebugWin( hParent,
                           pchName,
                           (bTiled ? WS_TILED : WS_POPUP) |
                           WS_VSCROLL | WS_HSCROLL |
                           WS_CAPTION | WS_SYSMENU | WS_SIZEBOX,
                           iNextX,
                           iNextY,
                           DEBUGDX,
                           DEBUGDY
                         );
 */
    iNextX += DEBUGXINC;
    iNextY += DEBUGYINC;

    return hWnd;
}

static void Error (str)
char *str;
{
  int a = MessageBox (hERROR,(LPSTR)str,(LPSTR)NULL,MB_OKCANCEL);
  if (a == IDCANCEL) PostQuitMessage(0);
}


DDIRLI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\DDIRLI.C

/*
 *  Function Name:   DlgDirList
 *  Program Name:    ddirli.c
 *  Special Notes:
 *
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   The program below allows the display of filenames and directories from
 *   the disk.  It will display the current directory and
 *   allow the user to select the filenames.
 *
 *   Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>
#include "ddirli.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL DialogProc(HWND, unsigned, WORD, LONG);

HANDLE   hInst;

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int   cmdShow;
  {
  MSG       msg;
  HWND       hWnd;
  HMENU      hMenu;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
    {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hIcon     = LoadIcon(hInstance, NULL);
    wcClass.hCursor     = LoadCursor(NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wcClass.lpszMenuName   = (LPSTR)"MenuName";
    wcClass.lpszClassName  = (LPSTR)"DlgDirList";

    if (!RegisterClass(&wcClass))
      return FALSE;
    }

  hWnd = CreateWindow("DlgDirList",
         "DlgDirList()",
         WS_OVERLAPPEDWINDOW,
         CW_USEDEFAULT,
         CW_USEDEFAULT,
         CW_USEDEFAULT,
         CW_USEDEFAULT,
         NULL,
         NULL,
         hInstance,
         NULL);

  hInst = hInstance;
  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);
  while (GetMessage(&msg, NULL, 0, 0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
  return msg.wParam;
  }

long FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND    hWnd;
unsigned  message;
WORD    wParam;
LONG    lParam;
  {
  switch (message)
    {
    case WM_COMMAND:
      if (wParam == IDM_1)
  {
  FARPROC lpprocDialogBox;
  lpprocDialogBox = MakeProcInstance ((FARPROC) DialogProc, hInst);
  DialogBox (hInst, MAKEINTRESOURCE(DIALOGID), hWnd, lpprocDialogBox);
  FreeProcInstance ((FARPROC) lpprocDialogBox);
  }
      break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
    }
  return(0L);
  }

/* Window procedure for the dialog box */
BOOL FAR PASCAL DialogProc (hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned   message;
WORD     wParam;
LONG     lParam;
  {
  BOOL     bListed;
  char     str[128];

  switch (message)
    {
    case WM_INITDIALOG:
      {
      bListed = DlgDirList(hDlg, "*.*", ID_LISTBOX, NULL, 0x4010);
      if (!bListed)
  {
  MessageBox(NULL, (LPSTR)"DlgDirList failed", (LPSTR)"ERROR", MB_ICONHAND);
  return FALSE;
  }
      SetDlgItemText(hDlg, ID_EDIT, (LPSTR)"");
      return TRUE;
      break;
      }
    case WM_COMMAND:
      {
      switch (wParam)
  {
  case ID_LISTBOX:
    if ((HIWORD(lParam)) == LBN_SELCHANGE)
      {
      DlgDirSelect(hDlg, (LPSTR)str, ID_LISTBOX);
      SetDlgItemText(hDlg, ID_EDIT, (LPSTR)str);
      return TRUE;
      }
    break;
  case IDCANCEL:
    EndDialog(hDlg, TRUE);
    break;
  default:
    return FALSE;
  }
      }
    default:
      return FALSE;
    }
  return TRUE;
  }


DDIRSEL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\DDIRSEL.C

/*
 *  Function Name:   DlgDirSelect
 *  Program Name:    ddirsel.c
 *  Author:          bertm
 *  Date Completed:  2-Feb-88
 *  Special Notes:
 *
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   This program allows the user to select filenames or directories from
 *   the list box. The program below will display the current directory
 *   and allow the user to select the filenames.  The program will not
 *   select directories (demonstrating the return value).
 *
 *   Microsoft Product Support Services
 *   Windows Version 2.0 function demonstration application
 *   Copyright (c) Microsoft 1988
 *
 */

#include "windows.h"
#include "ddirsel.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

HANDLE   hInst;

/**************************************************************************/

/* Window procedure for the dialog box */
BOOL FAR PASCAL DialogProc (hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
  char  str[128];

  switch (message)
  {
    case WM_INITDIALOG:
      DlgDirList(hDlg, (LPSTR) "*.*", ID_LISTBOX, NULL, 0x4010);
      SetDlgItemText(hDlg, ID_EDIT, (LPSTR) "");
      return TRUE;
      break;

    case WM_COMMAND:
      switch (wParam)
      {
        case ID_LISTBOX:
          switch (HIWORD(lParam))
          {
            case LBN_SELCHANGE:
                                         /* filenames only chosen   */
             if (!DlgDirSelect(hDlg, (LPSTR)str, ID_LISTBOX))
               SetDlgItemText(hDlg, ID_EDIT, (LPSTR)str);
              return TRUE;
              break;

            default:
              return FALSE;
          }
        case IDCANCEL:
          EndDialog(hDlg, TRUE);
          break;

        default:
          return FALSE;
      }
    default:
      return FALSE;
  }
  return TRUE;              /*  return TRUE if message is processed by us  */
}

/**************************************************************************/

void CALL_DlgDirSelect(hWnd)
HWND   hWnd;
{
  FARPROC lpprocDialogBox;
                    /*  Bind callback function with module instance  */
    lpprocDialogBox = MakeProcInstance ((FARPROC) DialogProc, hInst);
                    /*  Create a modal dialog box  */
    DialogBox (hInst, MAKEINTRESOURCE(DIALOGID), hWnd, lpprocDialogBox);
    FreeProcInstance ((FARPROC) lpprocDialogBox);

return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)"MenuName";
    wcClass.lpszClassName  = (LPSTR)"DlgDirSelect";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"DlgDirSelect",
                        (LPSTR)"DlgDirSelect()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

     hInst = hInstance;

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }
    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
      case WM_COMMAND:
        switch (wParam)
        {
          case IDM_1:
            CALL_DlgDirSelect(hWnd);
            break;

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

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        ValidateRect(hWnd, (LPRECT) NULL);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}




DECARET.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CARET\DECARET.C

/*
 *  Function Name:   DestroyCaret
 *  Program Name:    decaret.c
 *  Special Notes:
 *
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   The program below will display a caret and then destroy it.
 *
 *   Microsoft Product Support Services
 *   Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

long  FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

int  PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int  cmdShow;
{
  MSG       msg;
  HWND       hWnd;
  HMENU      hMenu;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
  {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hIcon     = LoadIcon(hInstance, NULL);
    wcClass.hCursor     = LoadCursor(NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wcClass.lpszMenuName   = NULL;
    wcClass.lpszClassName  = "DestroyCaret";

    if (!RegisterClass(&wcClass))
      return FALSE;
  }

  hWnd = CreateWindow("DestroyCaret",
      "DestroyCaret()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      NULL,
      NULL,
      hInstance,
      NULL);

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

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


long  FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned  message;
WORD     wParam;
LONG     lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {
  case WM_PAINT:
    {
      BeginPaint(hWnd, &ps);
      if (!IsIconic (hWnd))
      {
  CreateCaret (hWnd, NULL, 10, 20);
  SetCaretPos (40, 40);
  ShowCaret (hWnd);
  MessageBox(hWnd,
      "Caret shown, press return to destroy",
      "DestroyCaret", MB_OK);
  DestroyCaret();
      }
      ValidateRect(hWnd, NULL);
      EndPaint(hWnd, &ps);
      break;
    }
  case WM_DESTROY:
    {
      PostQuitMessage(0);
      break;
    }
  default:
    return DefWindowProc(hWnd, message, wParam, lParam);
  }
  return(0L);
}




DEMENU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\DEMENU.C

/*  Function Name:   DestroyMenu
 *
 *  Description:
 *   The program below will create a menu.  When the menuitem is selected,
 *   that menu will be destroyed and a new menu will be created.
 *
 *   Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

HMENU hMenu;

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  if (!hPrevInstance)
    {
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"DestroyMenu";

    if (!RegisterClass ( (LPWNDCLASS) & wcClass))
      return FALSE;
    }

  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, "Add MenuItem", 100, MF_APPEND);

  hWnd = CreateWindow ( (LPSTR)"DestroyMenu",
                      (LPSTR)"DestroyMenu ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,        /* no parent */
                      (HMENU)hMenu,      /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case 100:
          SetMenu (hWnd, NULL);  /*  No Menu for the Window while we play  */
          DestroyMenu (hMenu);   /*  Trash the Menu  */
          hMenu = CreateMenu (); /*  Create a new one  */
          ChangeMenu (hMenu, NULL, "Delete Extra MenuItem  ", 105, MF_APPEND)
          ChangeMenu (hMenu, NULL, "  Extra MenuItem", 110, MF_APPEND);
          SetMenu (hWnd, hMenu);  /*  Change the menu for the window  */
          break;

        case 105:
          SetMenu (hWnd, NULL);
          DestroyMenu (hMenu);
          hMenu = CreateMenu ();
          ChangeMenu (hMenu, NULL, "Add MenuItem", 100, MF_APPEND);
          SetMenu (hWnd, hMenu);
          break;

        case 110:
          MessageBox (GetFocus(), "Extra MenuItem Was Selected",
                      "Extra MenuItem", MB_OK | MB_ICONEXCLAMATION);
          break;

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

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


DEMETAFI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\DEMETAFI.C

/*
 *  Function Name:   DeleteMetaFile
 *  Program Name:    demetafi.c
 *  Special Notes:   Needs CRMETAFI.MET file to run.
 *
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   The program below used to free up memory the metafile has been using.
 *   The metafile may be recalled from the disk into memory by using the
 *   GetMetaFile function.  The program below draws a rectangle, then
 *   releases the metafile handle.
 */

#include "windows.h"

long  FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

int  PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int  cmdShow;
{
  MSG       msg;
  HWND       hWnd;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
  {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hIcon     = LoadIcon(hInstance, NULL);
    wcClass.hCursor     = LoadCursor(NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"DeleteMetaFile";

    if (!RegisterClass((LPWNDCLASS) & wcClass))
      return FALSE;
  }

  hWnd = CreateWindow("DeleteMetaFile",
      "DeleteMetaFile()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      NULL,
      NULL,
      hInstance,
      NULL);

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);
  while (GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}


long  FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned  message;
WORD     wParam;
LONG     lParam;
{
  PAINTSTRUCT ps;
  HDC        hDC;
  HANDLE      hMetaFile;

  switch (message)
  {
  case WM_PAINT:
    {
      BeginPaint(hWnd, &ps);
      hDC = ps.hdc;
      hMetaFile = GetMetaFile("demetafi.met");
      PlayMetaFile(hDC, hMetaFile);
      if (!DeleteMetaFile(hMetaFile))
  MessageBox(hWnd, "DeleteMetaFile failed", "ERROR", MB_ICONHAND);
      else
  TextOut(hDC, 20, 20, "Metafile handle released", 24);
      ValidateRect(hWnd, NULL);
      EndPaint(hWnd, &ps);
      break;
    }
  case WM_DESTROY:
    {
      PostQuitMessage(0);
      break;
    }
  default:
    return DefWindowProc(hWnd, message, wParam, lParam);
  }
  return(0L);
}




DEWINDOW.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\DEWINDOW.C

/*
 *  Function Name:   DestroyWindow
 *  Program Name:    dewindow.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   This program will destroy the window, leaving just a message box.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int   cmdShow;
  {
  MSG       msg;
  HWND       hWnd;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
    {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hIcon     = LoadIcon(hInstance, NULL);
    wcClass.hCursor     = LoadCursor(NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wcClass.lpszMenuName   = NULL;
    wcClass.lpszClassName  = "DestroyWindow";

    if (!RegisterClass(&wcClass))
      return FALSE;
    }

  hWnd = CreateWindow("DestroyWindow",
          "DestroyWindow()",
          WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          NULL,
          NULL,
          hInstance,
          NULL);

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);
  while (GetMessage(&msg, NULL, 0, 0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
  return msg.wParam;
  }

long FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned   message;
WORD     wParam;
LONG     lParam;
  {
  PAINTSTRUCT ps;
  BOOL        bDestroyed;
  HDC        hDC;

  switch (message)
    {
    case WM_PAINT:
      BeginPaint(hWnd, &ps);
      hDC=ps.hdc;
      TextOut(hDC, 10, 10, "End program to demonstrate", 26);
      ValidateRect(hWnd, NULL);
      EndPaint(hWnd, &ps);
      break;
    case WM_CLOSE:
      bDestroyed = DestroyWindow(hWnd);
      MessageBox(hWnd, "Window was just destroyed", "DestroyWindow", MB_OK);
      return DefWindowProc(hWnd, message, wParam, lParam);
      break;
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
    }
  return(0L);
  }


DIABOX.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\DIABOX.C


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

BOOL FAR PASCAL InitDiabox (HANDLE, HANDLE, int);
LONG FAR PASCAL DiaboxWindowProc   (HANDLE, unsigned, WORD, LONG);
BOOL FAR PASCAL DialogBoxWindowProc (HANDLE, unsigned, WORD, LONG); /* added
int     NEAR writeGMem (HANDLE, WORD, BYTE *, WORD);

HANDLE  hDTemplate;
HANDLE  hInst;
FARPROC lpDlgTest;
HWND    hDlgTest;
BOOL    nModeless;
BOOL    bResult;

struct dtHdrType   {
  LONG  dtStyle;
  BYTE  dtItemCount;
  int  dtX;
  int  dtY;
  int  dtCX;
  int  dtCY;
  char  dtResourceName[1];
  char  dtClassName[1];
  char  dtCaptionText[1];
  };

#define DTHDR    struct dtHdrType

struct dtItmType   {
  int  dtilX;
  int  dtilY;
  int  dtilCX;
  int  dtilCY;
  int  dtilID;
  LONG  dtilWindowStyle;
  BYTE  dtilControlClass;
  char  dtilText[1];
  };

#define DTITM    struct dtItmType

DTHDR    dtHdr;
DTITM    dtItm;
WORD     wByteCount;
BYTE     work[256];

/*  Forward references and type checking */

BOOL DisplayDialogBox (HWND);

/**************************************************************************/

int     PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  MSG  msg;

  if (hPrevInstance)   /* do not allow more than one instance */
    return FALSE;

  InitDiabox (hInstance, hPrevInstance, cmdShow);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    if (nModeless == TRUE)
      {
      TranslateMessage ( (LPMSG) & msg);
      DispatchMessage ( (LPMSG) & msg);
      }
    else
      {
      if ( (hDlgTest == NULL) || !IsDialogMessage (hDlgTest, (LPMSG) & msg))
        {
        TranslateMessage ( (LPMSG) & msg);
        DispatchMessage ( (LPMSG) & msg);
        }
      }
    }
  return (msg.wParam);
  }

/*******************************   initialization   ***********************/
BOOL FAR PASCAL InitDiabox (hInstance, hPrevInstance, cmdShow)
HANDLE   hInstance;
HANDLE   hPrevInstance;
int      cmdShow;
  {
  WNDCLASS  wcDiaboxClass;
  HWND      hWnd;

  wcDiaboxClass.lpszClassName = (LPSTR) "Diabox";
  wcDiaboxClass.hInstance     = hInstance;
  wcDiaboxClass.lpfnWndProc   = DiaboxWindowProc;
  wcDiaboxClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcDiaboxClass.hIcon         = NULL;
  wcDiaboxClass.lpszMenuName  = (LPSTR) "diabox";             /* menu added
  wcDiaboxClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcDiaboxClass.style         = CS_HREDRAW | CS_VREDRAW;
  wcDiaboxClass.cbClsExtra    = 0;
  wcDiaboxClass.cbWndExtra    = 0;

  RegisterClass ( (LPWNDCLASS) & wcDiaboxClass);
  hWnd = CreateWindow ( (LPSTR) "Diabox",
      (LPSTR) "DialogBox",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,
      (HMENU)NULL,
      (HANDLE)hInstance,
      (LPSTR)NULL
     );

  hInst = hInstance;       /*  instance saved for dialog box  */

  ShowWindow   (hWnd, cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
  }


/*********************   window procedure - process messages   *************/

LONG FAR PASCAL DiaboxWindowProc (hWnd, message, wParam, lParam)
HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
  {
  switch (message)
    {
    case WM_COMMAND:
      switch (wParam)
        {
        case IDDBOX:
          nModeless = FALSE;
          bResult = DisplayDialogBox (hWnd);
          break;

        case IDDBOX2:
          nModeless = TRUE;
          bResult = DisplayDialogBox (hWnd);
          break;

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

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
      break;
    }
  return (0L);
  }


/***************************************************************************/
BOOL DisplayDialogBox (hWnd)
HWND   hWnd;
  {
  LPSTR    lpDTemplate;

  if (hDlgTest != NULL)
    return (FALSE);

  if (! (hDTemplate = GlobalAlloc (GMEM_MOVEABLE, (DWORD) sizeof (DTHDR))))
    return (FALSE);

  wByteCount = 0;
  dtHdr.dtStyle           = WS_POPUP | WS_VISIBLE | WS_BORDER | WS_CAPTION;
  dtHdr.dtItemCount       = 4;
  dtHdr.dtX               = 10;
  dtHdr.dtY               = 10;
  dtHdr.dtCX              = 200;
  dtHdr.dtCY              = 100;
  dtHdr.dtResourceName[0] = 0;
  dtHdr.dtClassName[0]    = 0;

  if (!writeGMem (hDTemplate, wByteCount, (BYTE *) & dtHdr, sizeof (DTHDR) -
    return (FALSE);
  wByteCount += sizeof (DTHDR) - 1;

  strcpy (work, "Template Test");
  if (!writeGMem (hDTemplate, wByteCount, work, strlen (work) + 1))
    return (FALSE);
  wByteCount += strlen (work) + 1;

/* add OK BUTTON item */

  dtItm.dtilX            = 30;
  dtItm.dtilY            = 60;
  dtItm.dtilCX           = 32;
  dtItm.dtilCY           = 12;
  dtItm.dtilID           = 0x0300;
  dtItm.dtilWindowStyle  = BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD | WS_VISI
  dtItm.dtilControlClass = 0x80; /* BUTTON */
  if (!writeGMem (hDTemplate, wByteCount, (BYTE *) & dtItm, sizeof (DTITM) -
    return (FALSE);
  wByteCount += sizeof (DTITM) - 1;

  strcpy (work, "OK");
  if (!writeGMem (hDTemplate, wByteCount, work, strlen (work) + 1))
    return (FALSE);
  wByteCount += strlen (work) + 1;

  work[0] = 0;
  if (!writeGMem (hDTemplate, wByteCount, work, 1))
    return (FALSE);
  wByteCount += 1;

/* add CANCEL BUTTON item */

  dtItm.dtilX            = 70;
  dtItm.dtilY            = 60;
  dtItm.dtilCX           = 32;
  dtItm.dtilCY           = 12;
  dtItm.dtilID           = 0x0400;
  dtItm.dtilWindowStyle  = BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD | WS_VISIBLE
  dtItm.dtilControlClass = 0x80; /* BUTTON */
  if (!writeGMem (hDTemplate, wByteCount, (BYTE *) & dtItm, sizeof (DTITM) -
    return (FALSE);
  wByteCount += sizeof (DTITM) - 1;

  strcpy (work, "Cancel");
  if (!writeGMem (hDTemplate, wByteCount, work, strlen (work) + 1))
    return (FALSE);
  wByteCount += strlen (work) + 1;

  work[0] = 0;
  if (!writeGMem (hDTemplate, wByteCount, work, 1))
    return (FALSE);
  wByteCount += 1;

/* add EDIT item */

  dtItm.dtilX            = 30;
  dtItm.dtilY            = 40;
  dtItm.dtilCX           = 32;
  dtItm.dtilCY           = 12;
  dtItm.dtilID           = 0x0200;
  dtItm.dtilWindowStyle  = ES_LEFT | WS_TABSTOP | WS_CHILD | WS_BORDER | WS_V
  dtItm.dtilControlClass = 0x81; /* EDITCODE */
  if (!writeGMem (hDTemplate, wByteCount, (BYTE *) & dtItm, sizeof (DTITM) -
    return (FALSE);
  wByteCount += sizeof (DTITM) - 1;

  strcpy (work, "Edit");
  if (!writeGMem (hDTemplate, wByteCount, work, strlen (work) + 1))
    return (FALSE);
  wByteCount += strlen (work) + 1;

  work[0] = 0;
  if (!writeGMem (hDTemplate, wByteCount, work, 1))
    return (FALSE);
  wByteCount += 1;

/* add MESSAGE item */

  dtItm.dtilX     = 30;
  dtItm.dtilY     = 20;
  dtItm.dtilCX    = 100;
  dtItm.dtilCY    = 8;
  dtItm.dtilID    = 0x0100;
  dtItm.dtilWindowStyle = SS_LEFT | WS_CHILD | WS_VISIBLE;
  dtItm.dtilControlClass = 0x82; /* STATICCODE */
  if (!writeGMem (hDTemplate, wByteCount, (BYTE *) & dtItm, sizeof (DTITM) -
    return (FALSE);
  wByteCount += sizeof (DTITM) - 1;

  if (nModeless == FALSE)
    strcpy (work, "Modal DialogBox");
  else
    strcpy (work, "Modeless DialogBox");

  if (!writeGMem (hDTemplate, wByteCount, work, strlen (work) + 1))
    return (FALSE);
  wByteCount += strlen (work) + 1;

  work[0] = 0;
  if (!writeGMem (hDTemplate, wByteCount, work, 1))
    return (FALSE);

  lpDlgTest = MakeProcInstance ( (FARPROC) DialogBoxWindowProc, hInst);

  if (nModeless == FALSE)
    {
    hDlgTest = DialogBoxIndirect (hInst, hDTemplate, hWnd, lpDlgTest);
    FreeProcInstance ( (FARPROC) lpDlgTest);
    hDlgTest = NULL;
    }
  else
    {
    lpDTemplate = GlobalLock (hDTemplate);
    hDlgTest = CreateDialogIndirect (hInst, lpDTemplate, hWnd, lpDlgTest);
    GlobalUnlock (hDTemplate);
    }
  return (TRUE);
  }

/**************************************************************************/
BOOL FAR PASCAL DialogBoxWindowProc (hDlg, message, wParam, lParam)
HWND      hDlg;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  char  TempEdit[24];

  switch (message)
    {
    case WM_INITDIALOG:
  /* SetFocus to first control that is not a static or group box */
      SetFocus (GetDlgItem (hDlg, 0x0200));
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case 0x0100: /* static */
        case 0x0200: /* edit   */
          break;
        case 0x0300: /* ok     */
          GetDlgItemText (hDlg, 0x0200, TempEdit, 24);
          MessageBox (GetFocus (), (LPSTR)TempEdit,
                     (LPSTR)"Edit Control Contains", MB_OK);

          /*  No Break Here... We want to end the Dialog Box  */
        case 0x0400: /* cancel */
          if (nModeless == FALSE)
            EndDialog (hDlg, TRUE);
          else
            {
            DestroyWindow (hDlg);
            hDlgTest = NULL;
            }
          return (TRUE);
        default:
          return (TRUE);
        }           /* end wParam switch */
      break;      /* end command */

    default:
      return (FALSE);
    }                 /* end message switch */
  return (FALSE);
  }

/****************************************************************************
int     NEAR writeGMem (hData, offset, data, length)
HANDLE  hData;
WORD    offset;
BYTE    *data;
WORD    length;
  {
  HANDLE  hNewData;
  LPSTR   lpDstData;
  int     n;

  if (offset + length > (WORD)GlobalSize (hData))
    {
    if (! (hNewData = GlobalReAlloc (hData, (DWORD) offset + length, GMEM_MOV
      GlobalFree (hData);
    hDTemplate = hNewData;
    }

  if (lpDstData = GlobalLock (hData))
    {
    lpDstData = lpDstData + offset;
    for (n = 0; n < length; n++)
      *lpDstData++ = *data++;
    GlobalUnlock (hData);
    return (TRUE);
/* return (lpDstData); */  /* return new offset position */
    }
  return (FALSE);
  }


DIABOXIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\DIABOXIN.C

/*
 *
 *  DialogBoxIndirect
 *
 *  This program demonstrates the use of the function DialogBoxIndirect.
 *  It allows the user to create a modal dialogbox on the fly. Memory is
 *  dynamically allocated so that the structure will accomadate variable
 *  string sizes.
 */



#include <windows.h>
#include "diaboxin.h"

BOOL FAR PASCAL InitDiabox ( HANDLE , HANDLE , int );
long FAR PASCAL DiaboxWindowProc ( HANDLE , unsigned , WORD , LONG );
BOOL FAR PASCAL DialogBoxWindowProc (HANDLE, unsigned, WORD, LONG); /* added

HANDLE hInst;
FARPROC lpDlgTest;
HWND hDlgTest;

#define DTHDR        struct dtHdrType

struct dtHdrType
{
   LONG  dtStyle;
   BYTE  dtItemCount;
   int   dtX;
   int   dtY;
   int   dtCX;
   int   dtCY;
   char  dtResourceName[7];
   char  dtClassName[1];
   char  dtCaptionText[1];
};

#define DTITM        struct dtItmType

struct dtItmType
{
   int   dtilX;
   int   dtilY;
   int   dtilCX;
   int   dtilCY;
   int   dtilID;
   LONG  dtilWindowStyle;
   BYTE  dtilControlClass;
   char  dtilText[1];
};


/**************************************************************************/

int PASCAL WinMain  (hInstance , hPrevInstance , lpszCmdLine , cmdShow )
HANDLE hInstance , hPrevInstance;
LPSTR  lpszCmdLine;
int cmdShow;
  {
  MSG  msg;

  InitDiabox (hInstance, hPrevInstance, cmdShow );
  while ( GetMessage((LPMSG)&msg, NULL, 0 , 0 ))
    {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
    }
  exit(msg.wParam);
  }

/*******************************   initialization   ***********************/

BOOL FAR PASCAL InitDiabox (hInstance , hPrevInstance , cmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
int cmdShow;
  {
  WNDCLASS  wcDiaboxClass;
  HWND  hWnd;

  wcDiaboxClass.lpszClassName = (LPSTR) "Diabox";
  wcDiaboxClass.hInstance     = hInstance;
  wcDiaboxClass.lpfnWndProc   = DiaboxWindowProc;
  wcDiaboxClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
  wcDiaboxClass.hIcon         = NULL;
  wcDiaboxClass.lpszMenuName  = (LPSTR) "diabox";             /* menu added
  wcDiaboxClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcDiaboxClass.style         = CS_HREDRAW | CS_VREDRAW;
  wcDiaboxClass.cbClsExtra    = 0;
  wcDiaboxClass.cbWndExtra    = 0;

  RegisterClass ((LPWNDCLASS) &wcDiaboxClass);
  hWnd = CreateWindow((LPSTR) "Diabox",
                      (LPSTR) "DialogBoxIndirect",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,
                      (HMENU)NULL,
                      (HANDLE)hInstance,
                      (LPSTR)NULL
                     );

  hInst = hInstance;                    /*  instance saved for dialog box  */

  ShowWindow (hWnd , cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
  }

/*********************   window procedure - process messages   *************/

long FAR PASCAL DiaboxWindowProc (hWnd , message , wParam , lParam)
HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
  {
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_COMMAND:
        switch (wParam)
        {
        case IDDBOX:
            DisplayDialogBox(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
            break;
        }

    case WM_PAINT:
        BeginPaint (hWnd, (LPPAINTSTRUCT)&ps);
        EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return( DefWindowProc( hWnd , message , wParam , lParam ) );
        break;
    }
  return( 0L );
  }

/***************************************************************************/

DisplayDialogBox(hWnd)
HWND   hWnd;
{

   DTHDR    dtHdr;
   DTITM    dtItm;
   HANDLE   hDTemplate;
   LPSTR    lpDTemplate;
   WORD     wByteCount;
   BYTE     work[256];
   static   char     name[7] = "diabox";

   if(hDlgTest != NULL)
      return(FALSE);

   if(!(hDTemplate = GlobalAlloc(GMEM_MOVEABLE, (DWORD) sizeof(DTHDR))))
      return(FALSE);
   wByteCount = 0;

   dtHdr.dtStyle     = WS_POPUP | WS_VISIBLE | WS_BORDER | WS_CAPTION |
                       WS_SIZEBOX | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
   dtHdr.dtItemCount = 2;
   dtHdr.dtX         = 10;
   dtHdr.dtY         = 10;
   dtHdr.dtCX        = 200;
   dtHdr.dtCY        = 100;
   strcpy(dtHdr.dtResourceName, name);
   dtHdr.dtClassName[0]    = 0;
   if(!writeGMem(hDTemplate, wByteCount, (BYTE *) &dtHdr, sizeof(DTHDR)-1))
      return(FALSE);
   wByteCount += sizeof(DTHDR)-1;

   strcpy(work, "Howdy !!!");
   if(!writeGMem(hDTemplate, wByteCount, work, strlen(work)+1))
      return(FALSE);
   wByteCount += strlen(work)+1;

/* add BUTTON item */

   dtItm.dtilX     = 30;
   dtItm.dtilY     = 50;
   dtItm.dtilCX    = 32;
   dtItm.dtilCY    = 12;
   dtItm.dtilID    = 0x0200;
   dtItm.dtilWindowStyle = BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD | WS_VISI
   dtItm.dtilControlClass = 0x80;
   if(!writeGMem(hDTemplate, wByteCount, (BYTE *) &dtItm, sizeof(DTITM)-1))
      return(FALSE);
   wByteCount += sizeof(DTITM)-1;

   strcpy(work, "OK");
   if(!writeGMem(hDTemplate, wByteCount, work, strlen(work)+1))
      return(FALSE);
   wByteCount += strlen(work)+1;

   work[0] = 0;
   if(!writeGMem(hDTemplate, wByteCount, work, 1))
      return(FALSE);
   wByteCount += 1;

/* add MESSAGE item */

   dtItm.dtilX     = 30;
   dtItm.dtilY     = 20;
   dtItm.dtilCX    = 100;
   dtItm.dtilCY    = 8;
   dtItm.dtilID    = 0x0100;
   dtItm.dtilWindowStyle = SS_LEFT | WS_CHILD | WS_VISIBLE;
   dtItm.dtilControlClass = 0x82;
   if(!writeGMem(hDTemplate, wByteCount, (BYTE *) &dtItm, sizeof(DTITM)-1))
      return(FALSE);
   wByteCount += sizeof(DTITM)-1;

   strcpy(work, "Modal DialogBox");
   if(!writeGMem(hDTemplate, wByteCount, work, strlen(work)+1))
      return(FALSE);
   wByteCount += strlen(work)+1;

   work[0] = 0;
   if(!writeGMem(hDTemplate, wByteCount, work, 1))
      return(FALSE);

   lpDlgTest = MakeProcInstance((FARPROC) DialogBoxWindowProc, hInst);

   hDlgTest = DialogBoxIndirect (hInst, hDTemplate, hWnd, lpDlgTest);
                                             /*  function demonstrated  */
   if (hDlgTest == -1)
     MessageBox (NULL,(LPSTR)"DialogBoxIndirect failed",
                (LPSTR) "error",MB_ICONHAND);
   FreeProcInstance ((FARPROC) lpDlgTest);
   hDlgTest = NULL;
  return(TRUE);

}
/**************************************************************************/

BOOL FAR PASCAL DialogBoxWindowProc (hDlg, message, wParam, lParam)
HWND      hDlg;
unsigned  message;
WORD      wParam;
LONG      lParam;
{
  switch(message)
  {
   case WM_COMMAND:
      switch(wParam)
      {
      case 0x0100:
      case 0x0200:
         break;
      default:
         return(TRUE);
      }
      break;
   default:
      return(FALSE);
   }

   EndDialog (hDlg, TRUE);
   return(TRUE);
}


/****************************************************************************

BOOL NEAR writeGMem(hData, offset, data, length)
HANDLE  hData;
WORD    offset;
BYTE    *data;
WORD    length;
{
   HANDLE  hNewData;
   LPSTR   lpDstData;
   int     n;

   if(offset+length > GlobalSize(hData))
   {
      if(!(hNewData = GlobalReAlloc(hData, (DWORD) offset+length, GMEM_MOVEAB
         GlobalFree(hData);

      hData = hNewData;
   }

   if(lpDstData = GlobalLock(hData))
   {
      lpDstData = lpDstData + offset;
      for (n = 0 ; n < length ; n++)
         *lpDstData++ = *data++;
      GlobalUnlock(hData);
      return(TRUE);
   }

   return(FALSE);
}






DIMESS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\DIMESS.C

/*
 *  Function Name:   DispatchMessage
 *
 *  Description:
 *   This function passes all messages from the main procedure (WinMain) to
 *   the window procedure.  It passes the message in the MSG structure to the
 *   window function of the specified window.
 */

#include "windows.h"

long  FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);



int  PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int  cmdShow;
{
  MSG       msg;
  HWND       hWnd;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
  {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hIcon     = LoadIcon(hInstance, NULL);
    wcClass.hCursor     = LoadCursor(NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wcClass.lpszMenuName   = NULL;
    wcClass.lpszClassName  = "DispatchMessage";

    if (!RegisterClass(&wcClass))
      return FALSE;
  }

  hWnd = CreateWindow("DispatchMessage",
      "DispatchMessage()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      NULL,
      NULL,
      hInstance,
      NULL);

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);
  MessageBox(hWnd, "DispatchMessage working in loop",
      "DispatchMessage", MB_ICONASTERISK);
  while (GetMessage(&msg, NULL, 0, 0))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return msg.wParam;
}


long  FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned  message;
WORD     wParam;
LONG     lParam;
{
  switch (message)
  {
  case WM_DESTROY:
    {
      PostQuitMessage(0);
      break;
    }
  default:
    return DefWindowProc(hWnd, message, wParam, lParam);
  }
  return(0L);
}




DLGINT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\DLGINT.C

/*
 *
 *  SetDlgItemInt
 *  This program demonstrates the use of the function SetDlgItemInt.
 *  It sets the text of a dialog item (control) to the string representation
 *  of an integer value.
 */

#include "windows.h"
#include "dlgint.h"

HANDLE   hInst;
FARPROC  lpprocEdit;

long    FAR PASCAL SampleWndProc (HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL EditProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG       msg;
  HWND       hWnd;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
    {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = SampleWndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.hIcon          = LoadIcon (hInstance, "WindowIcon");
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.lpszMenuName   = MAKEINTRESOURCE (DIALOGMENU);
    wcClass.lpszClassName  = "dlgint";

    if (!RegisterClass (&wcClass))
      return FALSE;
    }
  hWnd = CreateWindow ("dlgint",
                      "Sending Integers",
                      WS_OVERLAPPEDWINDOW,
                      50,
                      50,
                      600,
                      250,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);
  hInst = hInstance;
  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);
  while (GetMessage (&msg, NULL, 0, 0))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return msg.wParam;
  }

long    FAR PASCAL SampleWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned   message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_COMMAND:
      if (wParam == ID_DIALOG)
        {
        lpprocEdit = MakeProcInstance ( (FARPROC) EditProc, hInst);
        DialogBox (hInst, MAKEINTRESOURCE (EDITBOX), hWnd, lpprocEdit);
        FreeProcInstance ( (FARPROC) lpprocEdit);
        }
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }


BOOL FAR PASCAL EditProc (hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned   message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_INITDIALOG:
      SetDlgItemInt (hDlg, ID_EDITBOX, 12345, (BOOL)FALSE);
      return TRUE;
      break;

    case WM_COMMAND:
      if (wParam == IDOK)
        {
        EndDialog (hDlg, TRUE);
  return TRUE;
        }
      break;

    default:
      return FALSE;
    }
  return TRUE;
  }


DLGTEXT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\DLGTEXT.C

/*
 *  SetDlgItemText
 *  This program demonstrates the use of the function SetDlgItemText.
 *  It sets the caption or text of a dialog item (control) in the dialog
 *  box.
 */

#include "windows.h"
#include "dlgtext.h"

HANDLE hInst;
FARPROC lpprocEdit;

long    FAR PASCAL SampleWndProc (HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL EditProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        cmdShow;
  {
  MSG       msg;
  HWND       hWnd;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
    {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = SampleWndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hIcon          = LoadIcon (hInstance, "WindowIcon");
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = MAKEINTRESOURCE (DIALOGMENU);
    wcClass.lpszClassName  = "dlgtext";

    if (!RegisterClass (&wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ("dlgtext",
                      (LPSTR)"Sending Text",
                      WS_OVERLAPPEDWINDOW,
                      50,
                      50,
                      600,
                      250,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);

  hInst = hInstance;
  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);
  while (GetMessage (&msg, NULL, 0, 0))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return msg.wParam;
  }

long    FAR PASCAL SampleWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned   message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_COMMAND:
      if (wParam == ID_DIALOG)
        {
        lpprocEdit = MakeProcInstance ( (FARPROC) EditProc, hInst);
        DialogBox (hInst, MAKEINTRESOURCE (EDITBOX), hWnd, lpprocEdit);
        FreeProcInstance ( (FARPROC) lpprocEdit);
        }
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }

BOOL FAR PASCAL EditProc (hDlg, message, wParam, lParam)
HWND    hDlg;
unsigned  message;
WORD    wParam;
LONG    lParam;
  {
  switch (message)
    {
    case WM_INITDIALOG:
      SetDlgItemText (hDlg, ID_EDITBOX, (LPSTR)"Text Received!!");
      return TRUE;
      break;

    case WM_COMMAND:
      if (wParam == IDOK)
        {
        EndDialog (hDlg, TRUE);
  return TRUE;
  break;
        }
      break;

    default:
      return FALSE;
    }
  return TRUE;
  }


DPTOLP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIENT\DPTOLP.C

/*
 *  Function Name:   DPtoLP
 *
 *  Description:
 *   This program will take the client area in MM_TEXT mode (device
 *   coordinates), store the client area size in a POINT data structure,
 *   change the map mode to MM_LOENGLISH, then convert the points to
 *   MM_LOENGLISH (logical coordinates).  The size of the client area
 *   is then displayed for both map modes.
 */

#include "windows.h"
#include "stdio.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int         cmdShow;
  {
  MSG       msg;
  HWND       hWnd;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
    {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = NULL;
    wcClass.lpszClassName  = "DPtoLP";

    if (!RegisterClass ( (LPWNDCLASS) & wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ("DPtoLP",
                      "DPtoLP ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);
  while (GetMessage (&msg, NULL, 0, 0))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return msg.wParam;
  }


long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND    hWnd;
unsigned  message;
WORD    wParam;
LONG    lParam;
  {
  PAINTSTRUCT ps;
  RECT        ClientRect;
  POINT       Points[1];
  char        szString1[80], szString2[80];
  int         nLength[2];

  switch (message)
    {
    case WM_PAINT:
      BeginPaint (hWnd, &ps);
      GetClientRect (hWnd, &ClientRect);
      Points[0].x = ClientRect.right;
      Points[0].y = ClientRect.bottom;
      SetMapMode (ps.hdc, MM_LOENGLISH);
      if (!DPtoLP (ps.hdc, Points, 1))
        {
        MessageBeep (0);
  break;
        }
      SetMapMode (ps.hdc, MM_TEXT);
      nLength[0] = sprintf (szString1,
          "Client area in MM_LOENGLISH mode: x=%d   y=%d",
          Points[0].x,
          Points[0].y);
      nLength[1] = sprintf (szString2,
          "Client area in MM_TEXT mode (pixels): x=%d   y=%d",
          ClientRect.right,
          ClientRect.bottom);
      TextOut (ps.hdc, 10, 10, szString1, nLength[0]);
      TextOut (ps.hdc, 30, 30, szString2, nLength[1]);
      ValidateRect (hWnd, NULL);
      EndPaint (hWnd, &ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }


DRICON.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\ICON\DRICON.C

/*
 *  Function Name:   DrawIcon
 *
 *  Description:
 *   The program below will display a stock icon.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE  hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  MSG       msg;
  HWND       hWnd;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
    {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = NULL;
    wcClass.lpszClassName  = "DrawIcon";

    if (!RegisterClass (&wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ("DrawIcon",
                      "DrawIcon ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);
  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);
  while (GetMessage (&msg, NULL, 0, 0))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return msg.wParam;
  }

long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND    hWnd;
unsigned  message;
WORD    wParam;
LONG    lParam;
  {
  PAINTSTRUCT ps;
  HANDLE      hIcon;
  BOOL        bDrawn;

  switch (message)
    {
    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      hIcon = LoadIcon ( (HANDLE) NULL, IDI_EXCLAMATION);
      if (!DrawIcon (ps.hdc, 50, 50, hIcon))
        {
        MessageBeep (0);
  return FALSE;
        }
      ValidateRect (hWnd, (LPRECT) NULL);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }


DRMENUBR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\DRMENUBR.C

/*
 *  Function Name:   DrawMenuBar
 *
 *  Description:
 *   The program below will redraw a window's menu, usually with
 *   modifications by ChangeMenu.  DrawMenuBar gives the same result as
 *   SetMenu, but DrawMenuBar cannot initially create the menu bar like
 *   SetMenu can.  The program below uses SetMenu to set and display
 *   'Heading1'and uses DrawMenuBar to display the addition 'Heading2'
 *   by ChangeMenu.
 *
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG       msg;
  HWND       hWnd;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
    {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = NULL;
    wcClass.lpszClassName  = "DrawMenuBar";

    if (!RegisterClass (&wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ("DrawMenuBar",
      "DrawMenuBar ()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      NULL,
      NULL,
      hInstance,
      NULL);
  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);
  while (GetMessage (&msg, NULL, 0, 0))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return msg.wParam;
  }


long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND    hWnd;
unsigned  message;
WORD    wParam;
LONG    lParam;
  {
  HMENU      hCurrentWindowMenu;
  unsigned   wIDItem;

  switch (message)
    {
    case WM_CREATE:
      hCurrentWindowMenu = CreateMenu ();
      ChangeMenu (hCurrentWindowMenu, NULL, "Heading1", wIDItem,
                  MF_APPEND | MF_BYCOMMAND | MF_STRING);
      SetMenu (hWnd, hCurrentWindowMenu);
      ChangeMenu (hCurrentWindowMenu, NULL, "Heading2", wIDItem,
                  MF_APPEND | MF_BYCOMMAND | MF_STRING);
      DrawMenuBar (hWnd);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;
    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }


DRTEXT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\DRTEXT.C

/*
 *  Function Name:   DrawText
 *
 *  Description:
 *   This program will put text into the user rectangle with some control
 *   over the method of formatting the text.
 */

#include "windows.h"
#include "stdio.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG       msg;
  HWND       hWnd;
  WNDCLASS   wcClass;

  if (!hPrevInstance)
    {
    wcClass.style     = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance     = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = NULL;
    wcClass.lpszClassName  = "DrawText";

    if (!RegisterClass (&wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ("DrawText",
      "DrawText ()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      NULL,
      NULL,
      hInstance,
      NULL);
  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);
  while (GetMessage (&msg, NULL, 0, 0))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return msg.wParam;
  }

long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned   message;
WORD     wParam;
LONG     lParam;
  {
  PAINTSTRUCT ps;
  HDC        hDC;
  RECT        RectDraw;
  char  szString[80];
  int  nLength;

  switch (message)
    {
    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      hDC = ps.hdc;
      RectDraw.left   = 10;
      RectDraw.top   = 10;
      RectDraw.right   = 150;
      RectDraw.bottom   = 70;
      nLength = sprintf (szString, "Wow!  Some Text!");
      DrawText (hDC, szString, nLength, &RectDraw, DT_LEFT | DT_WORDBREAK);
      ValidateRect (hWnd, NULL);
      EndPaint (hWnd, &ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }


DSPYDLL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DDE\DDESPY\DSPYDLL.C

#include "windows.h"
#include "winexp.h"
#include "ddespy.h"
#include "dde.h"

#define MENU

/*---------------------------------------------------------------------------
|
|   g l o b a l   v a r i a b l e s
|
\*---------------------------------------------------------------------------
/* NOTICE: The message structure for WH_CALLWNDPROC is "upside down"
           compared to the normal MSG structure. */
typedef struct mymsg {
    LONG lParam;
    WORD wParam;
    WORD message;
    HWND hwnd;
} MYMSG;
typedef MYMSG FAR *LPMYMSG;

/* Static definitions */
static  FARPROC fpxMsgHook1;
static  FARPROC fpxMsgHook2;
static  FARPROC fpxOldHook1;
static  FARPROC fpxOldHook2;

FARPROC lplpfnNextHook1;
FARPROC lplpfnNextHook2;
HWND    hSpyChild;
char    szTemp[30];
char    szTemphWnd[30];
static  int Tdx = 0;        /* Text font size */
static  int Tdy = 0;

struct TEXT_STRUCT {
    int  iFirst;                  /* First line in que */
    int  iCount;                  /* Number of lines in que */
    int  iTop;                    /* Line at top of window */
    int  iLeft;                   /* X offset of the window */
    char *Text[MAXLINES];         /* Que of Text in window */
    int  Len[MAXLINES];           /* String Length of text */
    int  MaxLen;                  /* Max String Length */
};

typedef struct TEXT_STRUCT *PTXT; /* pointer to a text struct */
typedef PTXT               *HTXT; /* Handle to a text struct */

#define ihqelMax 256
#define RADIX    16

HWND    hGParent;
HWND    hGMenu;
HANDLE  rghqel[ihqelMax];
int     ihqelHead;
int     ihqelTail;

int  iLen;
char pchFoo[MAXFOOLEN];    /* Buffer */

char szMessages[10][12];   /* messages */

HWND hWndMenu[10];
HWND hSpyWndMenu;  /* this is so we can attach the
                      windows text to the menu bar */

int  dllgfhFile;   /* handle to the file, if open */

/******************************************/

/* Handle to the DLL instance from Libinit.asm */
extern HANDLE LIBINST;

/*---------------------------------------------------------------------------
|
|   f u n c t i o n   d e f i n i t i o n s
|
\*---------------------------------------------------------------------------
void  FAR PASCAL InitHook( HWND );
BOOL  FAR PASCAL KillHook();
DWORD FAR PASCAL MsgHook1( WORD, WORD, LPMSG );
DWORD FAR PASCAL MsgHook2( WORD, WORD, LPMSG );
void  FAR PASCAL DebugPaint(HWND, HDC);
HWND  FAR PASCAL CreateDebugWin(HANDLE, HWND);

void  FAR PASCAL PassFileToDLL(int);
void  WriteitToFile( LPSTR , int);
void  FormatString(void);

void DebugHScroll (HWND, PTXT, int);
void DebugVScroll (HWND, PTXT, int);
void Error (char *);

char   *WM_MessageText(WORD);
HANDLE HqelGet();
void   HqelPut(HANDLE);


void FAR PASCAL PassFileToDLL(int gfhFile)
{
   dllgfhFile = gfhFile;
}


/* ------------------- Set the HOOKs ---------------- */
void FAR PASCAL InitHook( hWnd )
HWND hWnd;
{

   hSpyChild = hWnd;  /* handle to child window */

   fpxMsgHook1 = MakeProcInstance((FARPROC)MsgHook1,LIBINST);
   fpxMsgHook2 = MakeProcInstance((FARPROC)MsgHook2,LIBINST);

   fpxOldHook1 = SetWindowsHook(WH_GETMESSAGE, fpxMsgHook1);
   fpxOldHook2 = SetWindowsHook(WH_CALLWNDPROC,fpxMsgHook2);

   strcpy(szMessages[0], "INITIATE  ");
   strcpy(szMessages[1], "TERMINATE ");
   strcpy(szMessages[2], "ADVISE    ");
   strcpy(szMessages[3], "UNADVISE  ");
   strcpy(szMessages[4], "ACK       ");
   strcpy(szMessages[5], "DATA      ");
   strcpy(szMessages[6], "REQUEST   ");
   strcpy(szMessages[7], "POKE      ");
   strcpy(szMessages[8], "EXECUTE   ");

return;
}

/* ------------------- Remove the HOOKs ---------------- */
BOOL FAR PASCAL KillHook()
{
   BOOL fSuccess;

   fSuccess = UnhookWindowsHook( WH_GETMESSAGE,  fpxMsgHook1 );
   fSuccess = UnhookWindowsHook( WH_CALLWNDPROC, fpxMsgHook2 );

   FreeProcInstance( fpxMsgHook1 );
   FreeProcInstance( fpxMsgHook2 );

   return fSuccess;
}



/*---------------------------------------------------------------------------
|  CreateDebugWin (hParent, lpchName, dwStyle, x, y, dx, dy)
|
|   Description:
|     Creates a window for the depositing of debuging messages.
|
|   Arguments:
|     hWnd   - Window handle of the parent window.
|     pcName - String to appear in the caption bar of the debuging window
|     dwStyle- Window style
|     x,y    - Location of window
|     dx,dy  - Size of the window
|
|   Returns:
|     A window handle of the debuging window, or NULL if a error occured.
|
\*---------------------------------------------------------------------------

HWND FAR PASCAL CreateDebugWin (hInstance, hParent)
HANDLE  hInstance;
HWND    hParent;
{
    static BOOL bFirst = TRUE;   /* Is this the first call */

    HWND   hWnd;
    PTXT   pTxt;      /* pointer to a debuging window struct */

    TEXTMETRIC tm;    /* Used to find out the size of a char */
    RECT       rRect;
    HDC        hDC;
    int        i;

    if (bFirst) {
        /* Find out the size of a Char in the system font */
        hDC = GetDC(hParent);
        GetTextMetrics (hDC,(LPTEXTMETRIC)&tm);
        Tdy = tm.tmHeight;
        Tdx = tm.tmAveCharWidth;
        ReleaseDC (hParent,hDC);
        SetDebugClass(hInstance);
        hGParent = hParent;
        hGMenu = GetMenu(hParent);
        hSpyWndMenu = GetSubMenu( hGMenu ,4 );

        for (i=0 ; i<10 ; i++)         /* clear menu handles */
           hWndMenu[i] = NULL;

        bFirst = FALSE;
    }

    hInstance = GetWindowWord(hParent, GWW_HINSTANCE);
    GetClientRect (hParent,(LPRECT)&rRect);

    hWnd = CreateWindow((LPSTR)"DEBUG"
                        ,(LPSTR)"DDE SPY"
                        ,WS_CHILD | WS_VSCROLL | WS_HSCROLL
                        ,0,0
                        ,rRect.right
                        ,rRect.bottom
                        ,(HWND)hParent      /* parent window */
                        ,(HMENU)NULL        /* use class menu */
                        ,(HANDLE)hInstance  /* handle to window instance */
                        ,(LPSTR)NULL        /* no params to pass on */
                       );

    pTxt = (PTXT)LocalAlloc(LPTR,sizeof(struct TEXT_STRUCT));
    if (!pTxt || !hWnd) {
        Error ("CreateDebugWindow Failed.....");
        return NULL;
    }
    SetWindowWord (hWnd,0,(WORD)pTxt); /* Store the structure pointer with th
                                          window handle */

    pTxt->iFirst = 0;               /* Set the que up to have 1 NULL line */
    pTxt->iCount = 1;
    pTxt->iTop   = 0;
    pTxt->iLeft  = 0;
    pTxt->Text[0]= NULL;
    pTxt->Len[0] = 0;
    pTxt->MaxLen = 0;

    SetScrollRange (hWnd,SB_VERT,0,0,FALSE);
    SetScrollRange (hWnd,SB_HORZ,0,0,FALSE);
    /* Make window visible */
    ShowWindow(hWnd,SHOW_OPENWINDOW);

    return hWnd;
}


/*---------------------------------------------------------------------------
|   SetDebugClass(hInstance)
|
|   Description:
|     Registers a class for a DEBUG window.
|
|   Arguments:
|       hInstance       instance handle of current instance
|
|   Returns:
|       TRUE if successful, FALSE if not
|
\*---------------------------------------------------------------------------

static BOOL SetDebugClass(hInstance)
  HANDLE hInstance;
{
    WNDCLASS rClass;

    rClass.hCursor        = LoadCursor(NULL,IDC_ARROW);
    rClass.hIcon          = (HICON)NULL;
    rClass.lpszMenuName   = (LPSTR)NULL;
    rClass.lpszClassName  = (LPSTR)"DEBUG";
    rClass.hbrBackground  = (HBRUSH)COLOR_WINDOW + 1;
    rClass.hInstance      = hInstance;
    rClass.style          = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc    = DebugWndProc;
    rClass.cbWndExtra     = sizeof (HANDLE);
    rClass.cbClsExtra     = 0;

    return RegisterClass((LPWNDCLASS)&rClass);
}



/*---------------------------------------------------------------------------
|   MsgHook1 (wToast,pMsg,nCode)
|
|   Description:
|       The Message Hook1 to process all messages...
|
|   Arguments:
|       wToast          integer (0-100) for darkness of toast in morning
|       pMsg            Pointer to message
|       nCode           Message context
|
|   Returns:
|       FALSE to let windows process, TRUE to ignore
|
\*---------------------------------------------------------------------------
DWORD FAR PASCAL MsgHook1(code, wToast, lpmsg)
WORD     code;
WORD     wToast;
LPMSG    lpmsg;
{
   HANDLE hData;
   HANDLE hqel;
   QEL *pqel;
   char rgch[65];

   if (code == HC_ACTION &&
       lpmsg->message >= WM_DDE_FIRST &&
       lpmsg->message <= WM_DDE_LAST)
   {
      hqel=LocalAlloc(LMEM_MOVEABLE|LMEM_ZEROINIT, sizeof(QEL));
      pqel=(QEL *)LocalLock(hqel);
      pqel->msg=*lpmsg;
      switch(lpmsg->message)
      {
      case WM_DDE_TERMINATE:
              break;

      case WM_DDE_ACK:
              if ((unsigned)HIWORD(lpmsg->lParam)>=(unsigned)0xc000)
                      {
                      pqel->un.type=1;
                      goto OneAtom;
                      }
              pqel->un.type=2;
              /* fall thru... */
      case WM_DDE_EXECUTE:
              break;
      case WM_DDE_ADVISE:
              hData=(HANDLE)LOWORD(lpmsg->lParam);
              pqel->un.cf=((DDELN far *)GlobalLock(hData))->cf;
              GlobalUnlock(hData);
              goto OneAtom;
      case WM_DDE_REQUEST:
              pqel->un.cf=LOWORD(lpmsg->lParam);
              goto OneAtom;
      case WM_DDE_DATA:
      case WM_DDE_POKE:
              hData=(HANDLE)LOWORD(lpmsg->lParam);
              pqel->un.cf=((DDEUP far *)GlobalLock(hData))->cf;
              GlobalUnlock(hData);
              /* fall thru... */
      case WM_DDE_UNADVISE:
OneAtom:
              rgch[GlobalGetAtomName(HIWORD(lpmsg->lParam), rgch, 64)]='\0';
              pqel->atom1=AddAtom(rgch);
              break;
      }
      LocalUnlock(hqel);
      HqelPut(hqel);
      /* alert window that new queue data is available */
      FormatString();
      /* PostMessage(hSpyApp, WM_USER, 0, 0L); */
   }
   /* do default message handling */
   return(DefHookProc(code, wToast, (DWORD)lpmsg, (FARPROC FAR *)&fpxOldHook1
}

/* ----------------------------------------------------- */
DWORD FAR PASCAL MsgHook2(code, wToast, lpmsgr)
WORD   code;
WORD   wToast;
LPMSGR lpmsgr;
{
   HANDLE hqel;
   QEL *pqel;
   char rgch[65];

   if (code == HC_ACTION &&
       lpmsgr->message >= WM_DDE_FIRST &&
       lpmsgr->message <= WM_DDE_LAST)
   {
       hqel=LocalAlloc(LMEM_MOVEABLE|LMEM_ZEROINIT, sizeof(QEL));
       pqel=(QEL *)LocalLock(hqel);
       pqel->msg.message =lpmsgr->message;
       pqel->msg.wParam  =lpmsgr->wParam;
       pqel->msg.lParam  =lpmsgr->lParam;
       pqel->msg.hwnd    =lpmsgr->hwnd;
       pqel->un.type     =0;
       rgch[GlobalGetAtomName(LOWORD(lpmsgr->lParam), rgch, 64)]='\0';
       pqel->atom1=AddAtom(rgch);
       rgch[GlobalGetAtomName(HIWORD(lpmsgr->lParam), rgch, 64)]='\0';
       pqel->atom2=AddAtom(rgch);
       LocalUnlock(hqel);
       HqelPut(hqel);
       /* alert window that new queue data is available */
       FormatString();
       /* PostMessage(hSpyApp, WM_USER, 0, 0L); */
   }
   /* do default message handling */
   return(DefHookProc(code, wToast, (DWORD)lpmsgr, (FARPROC FAR *)&fpxOldHook
}

/* -------------------- FormatString ------------- */
void  FormatString()
{

  HANDLE hqel;
  QEL *pqel;
  HMENU hMenu;
  RECT  rRect;
  char rgch[32];
  char rgch2[32];
  int i;

  /*
   *  if the message is greater than WM_USER then it is a message to
   *  be printed in the window
   */

   while ((hqel=HqelGet())!=NULL)
   {
        pqel=(QEL *)LocalLock(hqel);

#ifdef OLD
        DebugPrintf(hSpyChild,"%-10s %4.4X %4.4X %4.4X,%4.4X ",
                WM_messageText(pqel->msg.message),
                pqel->msg.wParam,
                pqel->msg.hwnd,
                LOWORD(pqel->msg.lParam),
                HIWORD(pqel->msg.lParam));
#else
        lstrcpy( pchFoo, szMessages[(pqel->msg.message)-WM_DDE_FIRST] );
        lstrcat( pchFoo, "  " );
        ultoa ((DWORD)pqel->msg.wParam, szTemp, 16);
        lstrcat( pchFoo, szTemp );
        lstrcat( pchFoo, "  " );
        ultoa ((DWORD)pqel->msg.hwnd, szTemphWnd, 16);
        lstrcat( pchFoo, szTemphWnd );
        if ( strlen(szTemphWnd) < 4)
          lstrcat( pchFoo, " " );
        lstrcat( pchFoo, "  " );
        ultoa ((DWORD)LOWORD(pqel->msg.lParam), szTemp, 16);
        lstrcat( pchFoo, szTemp );
        if ( strlen(szTemp) < 3)
          lstrcat( pchFoo, "  " );
        if ( strlen(szTemp) < 4)
          lstrcat( pchFoo, " " );
        lstrcat( pchFoo, "  " );
        ultoa ((DWORD)HIWORD(pqel->msg.lParam), szTemp, 16);
        lstrcat( pchFoo, szTemp );

        iLen = 0;
        DebugPrintf(hSpyChild, pchFoo, iLen);


#endif

#ifdef MENU
        if ( pqel->msg.message == WM_DDE_INITIATE &&
             pqel->msg.hwnd    != NULL )
        {
          for (i=0 ; i<10 ; i++) {
             if (hWndMenu[i] == NULL ) {
                 hWndMenu[i] = pqel->msg.hwnd;
                 GetWindowText ( pqel->msg.hwnd, szTemp,25 );
                 lstrcat ( szTemphWnd, ":" );
                 lstrcat ( szTemphWnd, szTemp );
                 ChangeMenu(hSpyWndMenu, 153, (LPSTR)szTemphWnd,153,
                            i ? MF_APPEND : MF_CHANGE );
                 if (i == 0) {
                   EnableMenuItem(hGMenu, 152, MF_ENABLED );
                   DrawMenuBar(hGParent);
                 }
                 break;
             }
             else {
               if ( hWndMenu[i] == pqel->msg.hwnd )
                 break;
             }
          }
        }
#endif
        switch(pqel->msg.message)
        {
          case WM_DDE_ACK:
                switch (pqel->un.type)
                        {
                case 1:
                        goto OneAtom;
                case 2:
                        goto Execute;
                        }
                /* fall thru... */
          case WM_DDE_INITIATE:
                rgch[GetAtomName(pqel->atom1, (LPSTR)rgch, 32)]='\0';
                rgch2[GetAtomName(pqel->atom2, (LPSTR)rgch2, 32)]='\0';
#ifdef OLD
                DebugPrintf(hSpyChild,"(App:%s, Topic:%s)",rgch, rgch2);
#else
                lstrcpy( pchFoo, " (App:"                     );
                lstrcat( pchFoo,       rgch                  );
                lstrcat( pchFoo,           ", Topic:"        );
                lstrcat( pchFoo,                    rgch2    );
                lstrcat( pchFoo,                         ")" );
                DebugPrintf(hSpyChild, pchFoo, iLen);
#endif
                DeleteAtom(pqel->atom1);
                DeleteAtom(pqel->atom2);
                break;
          case WM_DDE_TERMINATE:
                break;
          case WM_DDE_UNADVISE:
OneAtom:
                rgch[GetAtomName(pqel->atom1, (LPSTR)rgch, 32)]='\0';
#ifdef OLD
                DebugPrintf(hSpyChild,"(Item:%s)",rgch);
#else
                lstrcpy( pchFoo, " (Items:"      );
                lstrcat( pchFoo,         rgch   );
                lstrcat( pchFoo,            ")" );
                DebugPrintf(hSpyChild, pchFoo, iLen);
#endif
                DeleteAtom(pqel->atom1);

                break;
          case WM_DDE_ADVISE:
          case WM_DDE_DATA:
          case WM_DDE_POKE:
          case WM_DDE_REQUEST:
                rgch[MyGetClipboardFormatName(pqel->un.cf, (LPSTR)rgch, 32)]=
                rgch2[GetAtomName(pqel->atom1, (LPSTR)rgch2, 32)]='\0';
#ifdef OLD
                DebugPrintf(hSpyChild,"(Format:%s, Item:%s)",rgch, rgch2);
#else
                lstrcpy( pchFoo, " (Format:"                    );
                lstrcat( pchFoo,         rgch                  );
                lstrcat( pchFoo,             ", Items:"        );
                lstrcat( pchFoo,                      rgch2    );
                lstrcat( pchFoo,                           ")" );
                DebugPrintf(hSpyChild, pchFoo, iLen);
#endif
                DeleteAtom(pqel->atom1);
                break;
          case WM_DDE_EXECUTE:
Execute:
                break;
        }
#ifdef OLD
        DebugPrintf(hSpyChild,"\n");
#else
        lstrcpy( pchFoo, "\n" );
        DebugPrintf(hSpyChild, pchFoo, iLen);
#endif

        LocalUnlock(hqel);
        LocalFree(hqel);
   }
   /* return(0L); */
}

/*---------------------------------------------------------------------------
|   DebugPrintf (hWnd,str,...)
|
|   Description:
|       Writes data into the window hWnd (hWnd must be created with
|       CreateDebugWindow ())
|       follows the normal C printf definition.
|
|   Arguments:
|       hWnd            window handle for the Degubing window
|       str             printf control string
|       ...             extra parameters as required by the contol string
|
|   NOTE: if hWnd == NULL text will be printed in the window used in the last
|         call to DebugPrintf.
\*---------------------------------------------------------------------------

int  DebugPrintf (hWnd,format,i)
HWND hWnd;
char *format;
int  i;
{
#ifdef OLD
  return vDebugPrintf (hWnd,format,&i);
#else
  return vDebugPrintf (hWnd,format,i);
#endif
}

#ifdef OLD
int  vDebugPrintf (hWnd,format,pi)
HWND hWnd;
char *format;
int  *pi;
#else
int  vDebugPrintf (hWnd,format,pi)
HWND hWnd;
char *format;
int  pi;
#endif

{
  static HWND hWndLast = NULL;
  RECT  rect;
  int   iFree;
  int   iRet;
  int   iLine;
  int   cLine;
  int   cScroll;
  PTXT  pTxt;
  MSG   rMsg;
  POINT rPoint;
/*
  if (!SSEqualToDS()) {
    Error ("WARNING: SS != DS,  Can't printf to window");
    return 0;
  }
 */
  if (hWnd == NULL) hWnd = hWndLast;

  if (hWnd == NULL || !IsWindow (hWnd)) {
     Error ("WARNING: bad window handle,  Can't printf to window");
     return 0;  /* exit if bad window handle */
  }
  pTxt = (PTXT)GetWindowWord (hWnd,0);
  hWndLast = hWnd;
#ifdef OLD
  iRet = vsprintf(pchFoo,format,pi);
#endif

  iLine   = pTxt->iCount - pTxt->iTop;
  cLine   = LinesInDebugWindow(hWnd);
  iFree   = pTxt->iTop;
  cScroll = InsertString (pTxt,pchFoo);  /* Insert text in the que */

  /* Scroll the window if Que overflowed */
  if (pTxt->iCount == MAXLINES && pTxt->iTop == 0) {
    iFree = cScroll - iFree;
    pTxt->iTop = -iFree;
    DebugVScroll (hWnd,pTxt,iFree);
  }

  if (iLine == cLine) {                  /* Scroll the window if last line */
     DebugVScroll (hWnd,pTxt,cScroll);   /* is allso last line in window */
     iLine -= cScroll;
  }

  /* Update the scroll bars */
  SetScrollRange (hWnd,SB_VERT,0,pTxt->iCount-2,FALSE);
  SetScrollRange (hWnd,SB_HORZ,0,pTxt->MaxLen,FALSE);
  SetScrollPos   (hWnd,SB_VERT,pTxt->iTop,FALSE);
  SetScrollPos   (hWnd,SB_HORZ,pTxt->iLeft,FALSE);

  /* Now make sure the new text is painted only if visable */
  GetClientRect(hWnd,(LPRECT)&rect);
  rect.top += (iLine-1) * Tdy;
  InvalidateRect (hWnd,(LPRECT)&rect,FALSE);
  UpdateWindow (hWnd);

  return(iRet);       /* return the count of arguments printed */
}

/*---------------------------------------------------------------------------
|
\*---------------------------------------------------------------------------

static void NewLine (pTxt)
PTXT pTxt;
{
  int iLast = LAST(pTxt);
  int iLine,cLine;

  if (pTxt->iCount == MAXLINES) {
    LocalFree ((HANDLE)pTxt->Text[pTxt->iFirst]);
    INC (pTxt->iFirst);
    if (pTxt->iTop > 0) pTxt->iTop--;
  }
  else {
    pTxt->iCount++;
  }
  iLast = LAST(pTxt);
  pTxt->Text[iLast] = NULL;
  pTxt->Len[iLast]  = 0;
}

/*---------------------------------------------------------------------------
|
\*---------------------------------------------------------------------------

static int InsertString (pTxt,str)
  PTXT pTxt;
  char *str;
{
  static char   buffer[MAXFOOLEN];               /* intermediate buffer */
  int    iBuf;
  int    iLast = LAST(pTxt);
  int    cLine = 0;

  for (iBuf=0; iBuf < pTxt->Len[iLast]; iBuf++)
    buffer[iBuf] = pTxt->Text[iLast][iBuf];

  if (pTxt->Text[iLast] != NULL)
    LocalFree ((HANDLE)pTxt->Text[iLast]);

  while (*str != '\0') {
    while ((*str != '\n') && (*str != '\0'))
      buffer[iBuf++] = *str++;

    /* Test for the case of a zero length line, Only brian would do this */

    if (iBuf == 0)
       pTxt->Text[iLast] == NULL;
    else {
      if ((pTxt->Text[iLast] = (char *)LocalAlloc (LPTR,iBuf)) == NULL)
         Error ("Local alloc failed in Insert string.....");
    }

    pTxt->Len[iLast] = iBuf;
    if (iBuf > pTxt->MaxLen) pTxt->MaxLen = iBuf;
    while (--iBuf >= 0 )
      pTxt->Text[iLast][iBuf] = buffer[iBuf];

    if (*str == '\n') {   /* Now do the next string after the \n */
       str++;
       iBuf = 0;
       cLine++;
       NewLine (pTxt);
       INC(iLast);
    }
  }
  return cLine;
}


/*---------------------------------------------------------------------------
|   DebugWndProc( hWnd, uiMessage, wParam, lParam )
|
|   Description:
|       The window proc for the debuging window.  This processes all
|       of the window's messages.
|
|   Arguments:
|       hWnd            window handle for the parent window
|       uiMessage       message number
|       wParam          message-dependent
|       lParam          message-dependent
|
|   Returns:
|       0 if processed, nonzero if ignored
|
\*---------------------------------------------------------------------------

long FAR PASCAL DebugWndProc( hWnd, uiMessage, wParam, lParam )
HWND     hWnd;
unsigned uiMessage;
WORD     wParam;
long     lParam;
{
    PAINTSTRUCT rPS;
    PTXT        pTxt  = (PTXT)GetWindowWord(hWnd,0);
    RECT        CRect;
    static WORD wScroll;

    switch (uiMessage) {
       /*
        * This tries to go around a BUG in 1.03 about scroll bars being confu
        */
        case WM_SYSCOMMAND:
            switch (wParam & 0xFFF0) {
                case SC_VSCROLL:
                case SC_HSCROLL:
                     wScroll = wParam & 0xFFF0;
                default:
                   return DefWindowProc(hWnd,uiMessage,wParam,lParam);
            }
            break;

        case WM_DESTROY: {
            int i,iQue;

            iQue = TOP(pTxt);
            for (i=0; i < pTxt->iCount; i++,INC(iQue))
              if (pTxt->Text[iQue] != NULL)
                 LocalFree ((HANDLE)pTxt->Text[iQue]);

            LocalFree ((HANDLE)pTxt);
            break;
        }

        case WM_VSCROLL:
            if (wScroll == SC_VSCROLL) {
               switch (wParam) {
                  case SB_LINEDOWN:
                     DebugVScroll (hWnd,pTxt,1);
                     break;
                  case SB_LINEUP:
                     DebugVScroll (hWnd,pTxt,-1);
                     break;
                  case SB_PAGEUP:
                     DebugVScroll (hWnd,pTxt,-PAGE);
                     break;
                  case SB_PAGEDOWN:
                     DebugVScroll (hWnd,pTxt,PAGE);
                     break;
                  case SB_THUMBPOSITION:
                     DebugVScroll (hWnd,pTxt,LOWORD(lParam)-pTxt->iTop);
                     break;
               }
             }
             break;

        case WM_HSCROLL:
            if (wScroll == SC_HSCROLL) {
               switch (wParam) {
                  case SB_LINEDOWN:
                     DebugHScroll (hWnd,pTxt,1);
                     break;
                  case SB_LINEUP:
                     DebugHScroll (hWnd,pTxt,-1);
                     break;
                  case SB_PAGEUP:
                     DebugHScroll (hWnd,pTxt,-PAGE);
                     break;
                  case SB_PAGEDOWN:
                     DebugHScroll (hWnd,pTxt,PAGE);
                     break;
                  case SB_THUMBPOSITION:
                     DebugHScroll (hWnd,pTxt,LOWORD(lParam)-pTxt->iLeft);
                     break;
               }
            }
            break;

        case WM_PAINT:
            BeginPaint(hWnd,(LPPAINTSTRUCT)&rPS);
            DebugPaint (hWnd,rPS.hdc);
            EndPaint(hWnd,(LPPAINTSTRUCT)&rPS);
            break;

        default:
           return DefWindowProc(hWnd,uiMessage,wParam,lParam);
    }
    return 0L;
}


/*---------------------------------------------------------------------------
|   DebugPaint(hWnd, hDC )
|
|   Description:
|       The paint function.
|
|   Arguments:
|       hWnd            Window to paint to.
|       hDC             handle to update region's display context
|
|   Returns:
|       nothing
|
\*---------------------------------------------------------------------------

void FAR PASCAL DebugPaint(hWnd, hDC)
HWND hWnd;
HDC  hDC;
{
  PTXT pTxt;
  int  i;
  int  iQue;
  int  xco;
  int  yco;
  char iFoo = 0;
  int  iLast;
  int  Wdy;
  RECT CRect;

  pTxt = (PTXT)GetWindowWord(hWnd,0);

  GetClientRect(hWnd,(LPRECT)&CRect);
  Wdy = CRect.bottom-CRect.top;

  iLast = LAST(pTxt);
  iQue  = TOP(pTxt);
  xco   = OFFSETX;
  yco   = OFFSETY;
  for (;;) {
    if (pTxt->Len[iQue] > pTxt->iLeft)
       TextOut (hDC,xco,yco,(LPSTR)pTxt->Text[iQue] + pTxt->iLeft,
                                   pTxt->Len[iQue]  - pTxt->iLeft
               );
    if (iQue == iLast) break;
    INC(iQue);
    yco += Tdy;
    if (yco > Wdy) break;
  }
}


/*---------------------------------------------------------------------------
|
\*---------------------------------------------------------------------------

void DebugVScroll (hWnd,pTxt,n)
HWND hWnd;
PTXT pTxt;
int  n;
{
  int  delta;
  RECT rect;

  GetClientRect (hWnd,(LPRECT)&rect);
  rect.left += OFFSETX;
  rect.top  += OFFSETY;

  if (n > 0) {
     delta = pTxt->iCount - pTxt->iTop - 2;
     if (n > delta) n = delta;
     pTxt->iTop += n;
     ScrollWindow (hWnd,0,-n*Tdy,(LPRECT)&rect,(LPRECT)&rect);
  }
  else {
     n *= -1;
     delta = pTxt->iTop;
     if (n > delta) n = delta;
     pTxt->iTop -= n;
     ScrollWindow (hWnd,0,n*Tdy,(LPRECT)&rect,(LPRECT)&rect);
  }
  SetScrollPos (hWnd,SB_VERT,pTxt->iTop,TRUE);
}

/*---------------------------------------------------------------------------
|
\*---------------------------------------------------------------------------

void DebugHScroll (hWnd,pTxt,n)
HWND hWnd;
PTXT pTxt;
int  n;
{
  int delta;
  RECT rect;

  GetClientRect (hWnd,(LPRECT)&rect);
  rect.left += OFFSETX;
  rect.top  += OFFSETY;

  if (n > 0) {
     delta = pTxt->MaxLen - pTxt->iLeft;
     if (n > delta) n = delta;
     pTxt->iLeft += n;
     ScrollWindow (hWnd,-n*Tdx,0,(LPRECT)&rect,(LPRECT)&rect);
  }
  else {
     n *= -1;
     delta = pTxt->iLeft;
     if (n > delta) n = delta;
     pTxt->iLeft -= n;
     ScrollWindow (hWnd,n*Tdx,0,(LPRECT)&rect,(LPRECT)&rect);
  }
  SetScrollPos (hWnd,SB_HORZ,pTxt->iLeft,TRUE);
}

/*---------------------------------------------------------------------------
|
\*---------------------------------------------------------------------------

static
int LinesInDebugWindow (hWnd)
    HWND hWnd;
{
    RECT CRect;

    GetClientRect(hWnd,(LPRECT)&CRect);
    return (CRect.bottom-CRect.top) / Tdy + 1;
}


/*---------------------------------------------------------------------------
| Error routine, brings up a message box with a error message
\*---------------------------------------------------------------------------

static void Error (str)
char *str;
{
  int a = MessageBox (GetFocus(),(LPSTR)str,(LPSTR)NULL,MB_OKCANCEL);
  if (a == IDCANCEL) PostQuitMessage(0);
}

/*---------------------------------------------------------------------------
| routine to verify that SS == DS
\*---------------------------------------------------------------------------

static BOOL SSEqualToDS () {
  int a = (int)&a;
  return (int far *)&a == (int far *)(int near *)a;
}


int MyGetClipboardFormatName(cf, lpch, cchMac)
int cf;
LPSTR lpch;
int cchMac;
{
        switch(cf)
                {
        case CF_TEXT:
                lstrcpy(lpch,"TEXT");
                return(4);
        case CF_BITMAP:
                lstrcpy(lpch,"BITMAP");
                return(6);
        case CF_METAFILEPICT:
                lstrcpy(lpch,"METAFILEPICT");
                return(12);
        case CF_SYLK:
                lstrcpy(lpch,"SYLK");
                return(4);
        case CF_DIF:
                lstrcpy(lpch,"DIF");
                return(3);
        default:
                return(GetClipboardFormatName(cf, lpch, cchMac));
                }
}


/* add an element to the queue */
void HqelPut(hqel)
HANDLE hqel;
{

  rghqel[ihqelHead++]=hqel;
  if (ihqelHead==ihqelMax)
    ihqelHead=0;
  if (ihqelHead==ihqelTail)
    MessageBox(GetFocus(), "Queue overflow", NULL, MB_OK|MB_SYSTEMMODAL);
}

/* delete an element from the queue */
HANDLE HqelGet()
{
  HANDLE hqel;

  if (ihqelTail==ihqelHead)
    return(NULL);
  hqel=rghqel[ihqelTail++];

  if (ihqelTail==ihqelMax)
    ihqelTail=0;

  return(hqel);
}

#ifdef OLD
 char *WM_MessageText (uiMsg)
 WORD uiMsg;
 {
   switch (uiMsg)
   {
     case WM_DDE_INITIATE:  return("INITIATE");
     case WM_DDE_TERMINATE: return("TERMINATE");
     case WM_DDE_ADVISE:    return("ADVISE");
     case WM_DDE_UNADVISE:  return("UNADVISE");
     case WM_DDE_ACK:       return("ACK");
     case WM_DDE_DATA:      return("DATA");
     case WM_DDE_REQUEST:   return("REQUEST");
     case WM_DDE_POKE:      return("POKE");
     case WM_DDE_EXECUTE:   return("EXECUTE");
   }
   return(NULL);
 }
#endif

#ifdef OLD
 void WriteitToFile( LPSTR lpString, int iLen )
 {
   if (dllgfhFile > 0) {
     _lwrite (dllgfhFile," ",1);
     _lwrite (dllgfhFile,lpString,iLen);
   }
   return;

 }
#endif



DUMPER.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\BIFFLIB\DUMPER.C


#include "stdio.h"


/*  DUMPER dumps all the records of a specified type  */
main()
{
  char filename[12];
  int type;
  int handler(int, char *, int);

  printf("Enter filename\n");
  scanf("%s", filename);
  printf("Enter data type of interest\n");
  scanf("%d", &type);
  open_BIFF(filename);
  read_BIFF(type, handler);
}

int handler(int type, char *data, int length)
{
  int row, column, i;
  unsigned int value;
  double val;
  char *label;

  int get_blank(char *, int *, int *);
  int get_integer(char *, int *, int *, unsigned int *);
  int get_number(char *, int *, int *, double *);
  int get_label(char *, int *, int *,  char **);
  int get_bool(char *, int *, int *, int *);


  switch (type) {
      case 1:
    get_blank(data, &row, &column);
    printf("In row %d column %d is a blank\n", row, column);
    break;
      case 2:
    get_integer(data, &row, &column, &value);
    printf("In row %d column %d is %d\n", row, column, value);
    break;
      case 4:
    get_number(data, &row, &column, &val);
    printf("In row %d column %d is %f\n", row, column, val);
    break;
      case 8:
    get_label(data, &row, &column, &label);
    printf("In row %d column %d is %s\n", row, column, label);
    break;
      case 16:
    get_bool(data, &row, &column, &value);
    printf("In row %d column %d is %d\n", row, column, value);
    break;

  }

}



ELLIPSE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\ELLIPSE.C

/*
 *  Function Name:   Ellipse
 *  Program Name:    ellipse.c
 *  Special Notes:
 *
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   The program below will draw an ellipse on the display.
 *
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_Ellipse(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  BOOL      bDrawn;

  bDrawn = Ellipse (hDC, 10, 10, 300, 150);

  if (bDrawn == FALSE)
    MessageBox(hWnd,(LPSTR)"Ellipse failed",(LPSTR)"ERROR",MB_ICONHAND);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Ellipse";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"Ellipse",
                        (LPSTR)"Ellipse()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_Ellipse(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ENAWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\ENAWIN.C

/*
 *  Function Name:   EnableWindow
 *  Program Name:    enawin.c
 *
 *  Description:
 *   This function can enable or disable keyboard and mouse input to a
 *   particular window.  The program below will disable input to the
 *   window when it loses the focus. The problem is that then you
 *   can't get the focus back. Oh Well....
 *
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);


/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
    HANDLE hInstance;
    {
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnableWindow";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        return FALSE;

    return TRUE;        /* Initialization succeeded */
    }


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
    HANDLE hInstance, hPrevInstance;
    LPSTR lpszCmdLine;
    int cmdShow;
    {
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnableWindow",
                        (LPSTR)"EnableWindow()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    MessageBox(hWnd, "This window is disabled when it loses \
the input focus.", "EnableWindow", MB_OK);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
    }

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
    HWND hWnd;
    unsigned message;
    WORD wParam;
    LONG lParam;
    {
    switch (message)
  {
  /* Disable window if focus is moved to another window */
  case WM_KILLFOCUS:
      EnableWindow(hWnd, FALSE);
      break;

  case WM_DESTROY:
      PostQuitMessage(0);
      break;

  default:
      return DefWindowProc( hWnd, message, wParam, lParam );
      break;
  }
    return(0L);
    }


ENAWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\ENAWIN.C

/*
 *  Function Name:   EnableWindow
 *  Program Name:    enawin.c
 *
 *  Description:
 *   This function can enable or disable keyboard and mouse input to a
 *   particular window.  The program below will disable input to the
 *   window when it loses the focus. The problem is that then you
 *   can't get the focus back. Oh Well....
 *
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);


/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
    HANDLE hInstance;
    {
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnableWindow";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        return FALSE;

    return TRUE;        /* Initialization succeeded */
    }


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
    HANDLE hInstance, hPrevInstance;
    LPSTR lpszCmdLine;
    int cmdShow;
    {
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnableWindow",
                        (LPSTR)"EnableWindow()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    MessageBox(hWnd, "This window is disabled when it loses \
the input focus.", "EnableWindow", MB_OK);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
    }

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
    HWND hWnd;
    unsigned message;
    WORD wParam;
    LONG lParam;
    {
    switch (message)
  {
  /* Disable window if focus is moved to another window */
  case WM_KILLFOCUS:
      EnableWindow(hWnd, FALSE);
      break;

  case WM_DESTROY:
      PostQuitMessage(0);
      break;

  default:
      return DefWindowProc( hWnd, message, wParam, lParam );
      break;
  }
    return(0L);
    }


ENCHWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SPAWN\ENCHWIN.C

/*
 *  Function Name:   EnumChildWindows
 *  Program Name:    enchwin.c
 *
 *  Description:
 *   This program will enumerate the child window(s) for the parent
 *   window.  The Class name of the child window will be displayed
 *   in a message box.  This program has only one child window.
 *
 */

#include "windows.h"
#include "string.h"
#include "enchwin.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
long FAR PASCAL ChildProc(HWND, unsigned, WORD, LONG);

char   szAppName [] = "EnChWin" ;
HWND   hWndChild1, hWndChild2;       /*  child window handle   */
HANDLE hInst;

/************************************************************************/

BOOL FAR PASCAL EnumProc(hChildWindow, lParam)
HWND   hChildWindow;
LONG   lParam;
{
   char szstr[31];

   GetWindowText (hChildWindow, szstr, 30);
   MessageBox(hChildWindow, (LPSTR)szstr,
       (LPSTR)"Name of child window", MB_OK);
   return TRUE;
}

/***********************************************************************/

void CALL_EnumChildWindows(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  FARPROC lpprocEnumChWin;
  char    szstring[80];
  LONG    lParam=0;

    lpprocEnumChWin = MakeProcInstance ((FARPROC) EnumProc, hInst);
    EnumChildWindows (hWnd, lpprocEnumChWin, lParam);
    FreeProcInstance ((FARPROC) lpprocEnumChWin);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)szAppName;
    wcClass.lpszClassName  = (LPSTR)"EnumChildWindows";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = ChildProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Child";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnumChildWindows",
                        (LPSTR)"EnumChildWindows()",
                        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    hWndChild1 = CreateWindow((LPSTR)"Child",
      (LPSTR)"Child Window 1",
                        WS_CHILD | WS_VISIBLE | WS_CAPTION,
                        50,
      20,
                        120,
      50,
                        (HWND)hWnd,        /* specify hWnd as parent */
                        (HMENU)NULL,       /* use class menu */
      (HANDLE)hInst, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

     hInst = hInstance;    /*  save Instance       */

     hWndChild2 = CreateWindow((LPSTR)"Child",
      (LPSTR)"Child Window 2",
                        WS_CHILD | WS_VISIBLE | WS_CAPTION,
                        50,
      70,
      120,
      50,
                        (HWND)hWnd,        /* specify hWnd as parent */
                        (HMENU)NULL,       /* use class menu */
      (HANDLE)hInst, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

     hInst = hInstance;    /*  save Instance       */


    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_COMMAND:
  switch (wParam)
  {
  case IDM_ENUM:
       ps.hdc = GetDC (hWnd);
       CALL_EnumChildWindows(hWnd, ps.hdc);
       ReleaseDC (hWnd, ps.hdc);
       break ;
  default:
       break ;
  }
    break ;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


long FAR PASCAL ChildProc( hChildWnd, message, wParam, lParam )
HWND hChildWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;
    switch (message)
    {

    default:
        return DefWindowProc( hChildWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ENDDIA.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\ENDDIA.C

/*
 *  Function Name:   EndDialog
 *  Program Name:    enddia.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   This function frees resources and reactivates the parent window
 *   while destroying the dialog box.
 */

#include "windows.h"
#include "enddia.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

HANDLE   hInst;

/**************************************************************************/

/* Window procedure for the dialog box */
BOOL FAR PASCAL DialogProc (hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
  if (message == WM_COMMAND)           /* check for WM_COMMAND            */
    EndDialog(hDlg, TRUE);            /* free resources                   */
  else
    return FALSE;
}

/**************************************************************************/

void CALL_EndDialog(hWnd)
HWND   hWnd;
{
  FARPROC lpprocDialogBox;
                    /*  Bind calback function with module instance  */
    lpprocDialogBox = MakeProcInstance ((FARPROC) DialogProc, hInst);
                    /*  Create a modal dialog box  */
    DialogBox (hInst, MAKEINTRESOURCE(IDD_10), hWnd, lpprocDialogBox);
    FreeProcInstance ((FARPROC) lpprocDialogBox);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)"MenuName";
    wcClass.lpszClassName  = (LPSTR)"EndDialog";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EndDialog",
                        (LPSTR)"EndDialog()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

     hInst = hInstance;

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }
    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
      case WM_COMMAND:
        switch (wParam)
        {
          case IDM_1:
            CALL_EndDialog(hWnd);
            break;

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

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}























c


ENDPAINT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\ENDPAINT.C

/*
 *  Function Name:   BeginPaint EndPaint
 *  Program Name:    endpaint.c
 *  Special Notes:
 *
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   This function tells Windows that the program has finished processing
 *   the paint message and it is okay for Windows to go ahead and remove
 *   the display context.
 *
 *   Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_EndPaint(hDC)
HDC hDC;
{
    TextOut(hDC, 10, 10, (LPSTR)"See code for details. /n", 22);

    return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EndPaint";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EndPaint",
                        (LPSTR)"EndPaint()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EndPaint(ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}



ENFONTS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\FONTS\ENFONTS.C

/*
 *  Function Name:   EnumFonts
 *  Program Name:    enfonts.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   This program will enumerate one font for each available typeface.
 *   The alphabet of each font will be displayed.
 */

#include "windows.h"
#include "stdio.h"
#include "string.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

HWND   hWndMain;            /*  need global handle to window   */
HANDLE hInst;

/************************************************************************/

short FAR PASCAL EnumProc(lpLogFont, lpTextMetric, FontType, lpData)
LPLOGFONT lpLogFont;
LPTEXTMETRIC lpTextMetric;
short FontType;
LPSTR lpData;
{
     HFONT hnewFont, holdFont;
     HDC   theDC;
     char  messageStr[256];
     static int row=10;

  theDC = GetDC(hWndMain);
  hnewFont = CreateFontIndirect(lpLogFont);
  holdFont = SelectObject(theDC,hnewFont);       /* load new font  */
  GetTextFace(theDC, 100, (LPSTR)messageStr);
  sprintf (messageStr + strlen(messageStr), " Height: %d Width %d",
           lpLogFont->lfHeight, lpLogFont->lfWidth);
  TextOut(theDC,10,row,(LPSTR) messageStr, strlen(messageStr));
  row += lpLogFont->lfHeight;             /*  advance line   */
  DeleteObject(holdFont);
  ReleaseDC(hWndMain, theDC);

  return (1);                    /* return value is user defined  */
}

/***********************************************************************/

void CALL_EnumFonts(hDC)
HDC hDC;
{
  FARPROC lpprocEnumFonts;

    lpprocEnumFonts = MakeProcInstance ((FARPROC) EnumProc, hInst);
    EnumFonts (hDC, (LPSTR)NULL, lpprocEnumFonts, 0L);
    FreeProcInstance ((FARPROC) lpprocEnumFonts);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnumFonts";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnumFonts",
                        (LPSTR)"EnumFonts()",
                        WS_OVERLAPPEDWINDOW | WS_VSCROLL,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    hWndMain = hWnd;
    hInst = hInstance;

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EnumFonts(ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ENHARDIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MOUSE\ENHARDIN.C

/*
 *  Function Name:   EnableHardwareInput
 *  Program Name:    enhardin.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   This function can disable the mouse and keyboard input.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_EnableHardwareInput(hWnd)
HWND hWnd;
{
  BOOL      bEnableInput;

  bEnableInput = EnableHardwareInput (TRUE);
                                      /* save input specified, else   */
  if (bEnableInput == TRUE)           /* mouse and keyboard diasbled  */
    MessageBox(hWnd,(LPSTR)"mouse & keyboard enabled",
              (LPSTR)"EnableHardwareInput", MB_OK);
  else
    MessageBox(hWnd,(LPSTR)"mouse & keyboard disabled",
              (LPSTR)"EnableHardwareInput", MB_OK);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnableHardwareInput";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnableHardwareInput",
                        (LPSTR)"EnableHardwareInput()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EnableHardwareInput(hWnd);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ENHARDIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\ENHARDIN.C

/*
 *  Function Name:   EnableHardwareInput
 *  Program Name:    enhardin.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   This function can disable the mouse and keyboard input.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_EnableHardwareInput(hWnd)
HWND hWnd;
{
  BOOL      bEnableInput;

  bEnableInput = EnableHardwareInput (TRUE);
                                      /* save input specified, else   */
  if (bEnableInput == TRUE)           /* mouse and keyboard diasbled  */
    MessageBox(hWnd,(LPSTR)"mouse & keyboard enabled",
              (LPSTR)"EnableHardwareInput", MB_OK);
  else
    MessageBox(hWnd,(LPSTR)"mouse & keyboard disabled",
              (LPSTR)"EnableHardwareInput", MB_OK);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnableHardwareInput";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnableHardwareInput",
                        (LPSTR)"EnableHardwareInput()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EnableHardwareInput(hWnd);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ENMENUIT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\ENMENUIT.C

/*
 *  Function Name:   EnableMenuItem
 *  Program Name:    enmenuit.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.0
 *
 *  Description:
 *   The program below allows a menu item to be grayed, enabled, or disabled.
 *   The following program will gray a menu item.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_EnableMenuItem(hWnd)
HWND hWnd;
{
  HMENU hCurrentWindowMenu, hSubItem;
  unsigned wIDNewItem1, wIDNewItem2;
  BOOL  bPrevState;

  hCurrentWindowMenu = CreateMenu();
  hSubItem           = CreateMenu();
                                              /* menu heading created. */
  ChangeMenu (hCurrentWindowMenu, NULL, (LPSTR) "Heading",
              hSubItem, MF_APPEND | MF_BYPOSITION | MF_POPUP);

                                             /* 2 items added under Heading *
  ChangeMenu (hSubItem, NULL, (LPSTR ) "Item1", wIDNewItem1,
               MF_APPEND | MF_BYCOMMAND | MF_STRING);
  ChangeMenu (hSubItem, NULL, (LPSTR) "Item2", wIDNewItem2,
               MF_APPEND | MF_BYCOMMAND | MF_STRING);

  SetMenu(hWnd, hCurrentWindowMenu);

  bPrevState = EnableMenuItem(hCurrentWindowMenu, wIDNewItem1, MF_GRAYED);

/*  if (bPrevState == 0 or 1 or 2)         0 = ENABLED or error (as in
                                              BYPOSITION invalid number)
                                          1 = GRAYED
                                          2 = DISABLED
  {
    MessageBox(NULL,(LPSTR)"EnableMenuItem failed",(LPSTR)"ERROR",MB_ICONHAND
    return FALSE;
  }
*/

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnableMenuItem";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnableMenuItem",
                        (LPSTR)"EnableMenuItem()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EnableMenuItem(hWnd);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ENMETAFI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\ENMETAFI.C

/*
 *  Function Name:   EnumMetaFile
 *  Program Name:    enmetafi.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   The program below will create a metafile, close it, then
 *   enumerate it.  The enumeration will play each record in
 *   the metafile.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

HANDLE hInst;

/*************************************************************************/

BOOL FAR PASCAL EnumProc(hDC, lpHTable, lpMFR, nObj, lpClientData)
HDC      hDC;
LPHANDLETABLE lpHTable;
LPMETARECORD  lpMFR;
int           nObj;
BYTE FAR *    lpClientData;
{
  PlayMetaFileRecord(hDC, lpHTable, lpMFR, nObj);
  return(1);
}

/***********************************************************************/

void CALL_EnumMetaFile(hDC)
HDC hDC;
{
  FARPROC lpprocEnumMF;
  char szstring[81];
  LOCALHANDLE hMF;
  HDC     hDCMeta;


  hDCMeta = CreateMetaFile((LPSTR) "enmetafi.met");
  Rectangle (hDCMeta, 10, 10, 400, 200);       /*  metafile records    */
  Rectangle (hDCMeta, 20, 20, 300, 180);       /*  for enumeration count  */
  TextOut (hDCMeta, 40, 40, (LPSTR)"Metafile Enumerated", 19);

  hMF = CloseMetaFile (hDCMeta);

    lpprocEnumMF = MakeProcInstance ((FARPROC) EnumProc, hInst);
    EnumMetaFile(hDC, hMF, lpprocEnumMF, (BYTE FAR *) NULL);
    FreeProcInstance ((FARPROC) lpprocEnumMF);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnumMetaFile";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnumMetaFile",
                        (LPSTR)"EnumMetaFile()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );
    hInst = hInstance;

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EnumMetaFile(ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ENOBJ.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\OBJECT\ENOBJ.C

/*
 *  Function Name:   EnumObjects
 *  Program Name:    enobj.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   This function enumerates the pens and brushes available on a
 *   device.  The program below will count the number of pen
 *   enumerations.
 */

#include "windows.h"
#include "stdio.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

HANDLE hInst;
int    nResult;

/*************************************************************************/

short FAR PASCAL EnumProc(lpObj, lpData)
LPLOGPEN lpObj;
LPSTR lpData;
{
/*  nPenStyle = lpObj->lopnStyle;   */
  nResult++;                            /* enumerations counted   */
  return (1);                    /* return value is user defined.   */
}

/***********************************************************************/

void CALL_EnumObjects(hDC)
HDC hDC;
{
  FARPROC lpprocEnumObj;
  char    szstring[80];
  int     nLength;

    lpprocEnumObj = MakeProcInstance ((FARPROC) EnumProc, hInst);
    EnumObjects (hDC, OBJ_PEN, lpprocEnumObj, 0L);
    FreeProcInstance ((FARPROC) lpprocEnumObj);

    nLength = sprintf(szstring, "Pen Enumerations = %d ", nResult);
    TextOut (hDC, 10, 10, szstring, nLength);
    nResult = 0;
    return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnumObjects";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnumObjects",
                        (LPSTR)"EnumObjects()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );
    hInst = hInstance;

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EnumObjects(ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ENPROPS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\ENPROPS.C

/*
 *  Function Name:   EnumProps
 *  Program Name:    enprops.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   This function will enumerate properties assigned to a window.
 *   The program below will assign two properties to the window
 *   and display them during the enumeration.
 */

#include "windows.h"
#include "string.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

HANDLE hInst;
int    nResult;

/*************************************************************************/

int FAR PASCAL EnumProc(hWnd, lpString, hData)
HWND   hWnd;
LPSTR  lpString;
HANDLE hData;
{
  HDC  hDC;
  static int nInc = 10;

  hDC = GetDC(hWnd);
  TextOut(hDC, 10, nInc+=20, lpString, strlen((PSTR) LOWORD(lpString)));
  ReleaseDC (hWnd, hDC);
  return (1);                    /* return value is user defined.   */
}

/***********************************************************************/

void CALL_EnumProps(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  FARPROC lpprocEnumProp;
  char szstring[80];

  SetProp (hWnd, (LPSTR)"prop1", (HANDLE) NULL);
  SetProp (hWnd, (LPSTR)"prop2", (HANDLE) NULL);

    lpprocEnumProp = MakeProcInstance ((FARPROC) EnumProc, hInst);
    EnumProps (hWnd, lpprocEnumProp);       /*  function demonstrated   */
    FreeProcInstance ((FARPROC) lpprocEnumProp);

  RemoveProp(hWnd, (LPSTR)"prop1");
  RemoveProp(hWnd, (LPSTR)"prop2");

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnumProps";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnumProps",
                        (LPSTR)"EnumProps()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );
    hInst = hInstance;

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EnumProps(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ENTAWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\ENTAWIN.C

/*
 *  Function Name:   EnumTaskWindows
 *  Program Name:    entawin.c
 *
 *  Special Notes:   The enumeration does not work.  The callback function
 *                   EnumProc is never reached.
 *
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

HANDLE hInst;

/*************************************************************************/

BOOL FAR PASCAL EnumProc(hWnd, lParam)
HWND      hWnd;
LONG      lParam;
{
    MessageBox(hWnd,(LPSTR)"Made it to enumeration",(LPSTR)"",MB_ICONHAND);
    return (1);
}

/***********************************************************************/

void CALL_EnumTaskWindows(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  FARPROC lpprocEnumTaskWin;
  HANDLE  hTask;

  hTask = GetCurrentTask();
  if (hTask == NULL)
    MessageBox(hWnd,(LPSTR)"task = null",(LPSTR)"",MB_ICONHAND);

  lpprocEnumTaskWin = MakeProcInstance ((FARPROC)EnumProc, hInst);
  if (lpprocEnumTaskWin == NULL)
    MessageBox(hWnd,(LPSTR)"lpEnumFunc = null",(LPSTR)"",MB_ICONHAND);

  EnumTaskWindows (hTask, lpprocEnumTaskWin, (LONG) NULL);

  FreeProcInstance (lpprocEnumTaskWin);
  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnumTaskWindows";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnumTaskWindows",
                        (LPSTR)"EnumTaskWindows()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );
    hInst = hInstance;

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    MessageBox(hWnd, "The enumeration does not work.  \
The callback function is never reached.", "EnumTaskWindows", MB_OK);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EnumTaskWindows(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ENWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\ENWIN.C

/*
 *  Function Name:   EnumWindows
 *  Program Name:    enwin.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   This function will enumerate all the windows on the screen.  The
 *   name of each window enumerated will be displayed.
 */

#include "windows.h"
#include "string.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

HANDLE hInst;
HWND   hWndGlobal;      /*  for TextOut during enumeration  */

/*************************************************************************/

BOOL FAR PASCAL EnumProc(hWnd, lParam)
HWND   hWnd;
LONG   lParam;
{
  HDC  hDC;
  char szstr[80];
  static int inc = 10;

  GetClassName(hWnd, (LPSTR)szstr, 80);
  hDC = GetDC(hWndGlobal);
  TextOut(hDC, 10, inc+=15, (LPSTR)szstr, strlen(szstr));
  ReleaseDC(hWndGlobal, hDC);
  return (1);                    /* returning 0 will stop the enumeration */
}

/***********************************************************************/

void CALL_EnumWindows(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  FARPROC lpprocEnumWindow;
  LONG lParam;

    lpprocEnumWindow = MakeProcInstance ((FARPROC) EnumProc, hInst);
    EnumWindows (lpprocEnumWindow, lParam);   /*  function demonstrated   */
    FreeProcInstance ((FARPROC) lpprocEnumWindow);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EnumWindows";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EnumWindows",
                        (LPSTR)"EnumWindows()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );
    hInst = hInstance;
    hWndGlobal = hWnd;

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EnumWindows(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


EQRECT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\EQRECT.C

/*
 *  Function Name:   EqualRect
 *  Program Name:    eqrect.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   This function compares the upper-left and lower-right hand corners
 *   of two rectangles for eqality.  If they are equal, a non-zero
 *   value returns, else a zero returns.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_EqualRect(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  BOOL   bEqual;
  static RECT      rRect1 = { 30, 30, 60, 60 };
  static RECT      rRect2 = { 30, 30, 60, 60 };

  Rectangle( hDC, 30, 30, 60, 60 );
                                         /*  function demonstrated   */
  bEqual = EqualRect ((LPRECT) &rRect1, (LPRECT) &rRect2);

  if (bEqual == NULL)
      TextOut(hDC, 10, 10, (LPSTR)"Rectangle coordinates are not equal", 35);
  else
      TextOut(hDC, 10, 10, (LPSTR)"Rectangle coordinates are equal", 31);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EqualRect";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EqualRect",
                        (LPSTR)"EqualRect()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EqualRect(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


EQRGN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\EQRGN.C

/*
 *  Function Name:   EqualRgn
 *  Program Name:    eqrgn.c
 *
 *  Description:
 *   This function will compare the coordinates of two regions.  If
 *   both regions are the same size and in the same place, a nonzero
 *   value will return.  Otherwise a zero is returned.
 *
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_EqualRgn(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  HRGN hRgn1, hRgn2;
  BOOL bEqual;

  MessageBox(hWnd, "Creating two rectangular regions at \
(30,30)-(90,90)...", "EqualRgn", MB_OK);

  hRgn1 = CreateRectRgn(30, 30, 90, 90);
  hRgn2 = CreateRectRgn(30, 30, 90, 90);
  InvertRgn(hDC, hRgn1);                        /* make region visible  */

  bEqual = EqualRgn(hRgn1, hRgn2);        /* compare regions       */

  if (bEqual)
    TextOut (hDC, 10, 10, (LPSTR)"Regions are equal", 17);
  else
    TextOut (hDC, 10, 10, (LPSTR)"Regions are not equal", 21);

  DeleteObject( hRgn1 );
  DeleteObject( hRgn2 );

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EqualRgn";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EqualRgn",
                        (LPSTR)"EqualRgn()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
  CALL_EqualRgn(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ESC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\ESC.C

/*
 *  Function Name:   Escape
 *  Program Name:    esc.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   The program below will retrieve and display the physical page size
 *   for the installed printer.
 */

#include "windows.h"
#include "stdio.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_Escape(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  HDC    hDCDevice;
  char   szDevice[81], szstring[80];
  PSTR   spDeviceName, spFileName, spPort, strtok();
  int    PageCnt, Pages, nResult, nLength;
  POINT  ptPageSize;

  GetProfileString ("windows", "device", "", szDevice, 81);
  spDeviceName = strtok (szDevice, ",");
  spFileName   = strtok (NULL, ", ");
  spPort       = strtok (NULL, ", ");
  hDCDevice = CreateDC(spFileName, szDevice, spPort, 0);
                                               /* function demonstrated  */
  nResult = Escape (hDCDevice, GETPHYSPAGESIZE, 0, 0, (LPSTR)&ptPageSize);

  if (nResult < 0)
  {
    MessageBox(hWnd,(LPSTR)"Escape failed",(LPSTR)"ERROR",MB_ICONHAND);
    return;
  }
  nLength = sprintf(szstring, "Physical page size for %s is  x=%d,  y=%d",
                               spDeviceName, ptPageSize.x, ptPageSize.y);
  TextOut (hDC, 10, 10, szstring, nLength);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Escape";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"Escape",
                        (LPSTR)"Escape()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_Escape(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


ESCCOMF.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\ESCCOMF.C

/*
 *  Function Name:   EscapeCommFunction
 *  Program Name:    esccomf.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   The program below will carry out the extended function given
 *   with LPT2.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_EscapeCommFunction(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  int     nCid, nResult;

  nCid = OpenComm ((LPSTR)"LPT2", 20, 20);
                                          /*  function demonstrated  */
  nResult = EscapeCommFunction (nCid, SETXOFF);

  if (nResult != 0)
       MessageBox (hWnd, (LPSTR)"EscapeCommFunction failed",
                  (LPSTR)"ERROR",MB_ICONHAND);
  else
      TextOut(hDC, 10, 10, (LPSTR)"EscapeCommFunction successful", 29);

  CloseComm (nCid);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"EscapeCommFunction";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"EscapeCommFunction",
                        (LPSTR)"EscapeCommFunction()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_EscapeCommFunction(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


EXAMPLE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DLL\EXAMPLE.C

typedef double far *LPDOUBLE;
typedef char   far *LPSTR;


/* ------------------------------ AA */
int far pascal TestBool(a)
int a;
{
   return (!a);
}

/* ------------------------------ */
LPDOUBLE far pascal TestDouble(a)
double a;
{
   static double temp;

   temp = a*2.0;
   return (LPDOUBLE)&temp;
}

/* ------------------------------ */
LPSTR far pascal TestChar(s)
LPSTR s;
{
     static char buffer[128];
     char *t;

     t = buffer;
     while (*s++) {
          *t++ = '$';
     }
     *t = '\0';
     return (LPSTR) buffer;
}

/* ------------------------------ */
LPSTR far pascal TestByte()
{
     static char buff[24];

     buff[0] = 9;    /* a contains the # of characters to return */
     buff[1] = 'H';
     buff[2] = 'i';
     buff[3] = ' ';
     buff[4] = 'T';
     buff[5] = 'h';
     buff[6] = 'e';
     buff[7] = 'r';
     buff[8] = 'e';
     buff[9] = '.';

   return (LPSTR) buff;
}

/* ------------------------------ */
double far pascal TestFloatBuff(a)
double *a;
{

   *a = 2.0;
   return (double) *a;
}

/* ------------------------------ */
LPSTR far pascal TestZBuff(a)
LPSTR a;
{

   a[0] = 'G';
   a[1] = 'r';
   a[2] = 'e';
   a[3] = 'e';
   a[4] = 't';
   a[5] = 'i';
   a[6] = 'n';
   a[7] = 'g';
   a[8] = 's';
   a[9] = '\0';

   return (LPSTR) a;
}

/* ------------------------------ */
LPSTR far pascal TestByteBuff(a)
LPSTR a;
{

   a[0] = 8;
   a[1] = 'G';
   a[2] = 'o';
   a[3] = 'o';
   a[4] = 'd';
   a[5] = ' ';
   a[6] = 'd';
   a[7] = 'a';
   a[8] = 'y';

   return (LPSTR) a;
}

/* ------------------------------ */
unsigned int far pascal TestUInt(a)
unsigned int a;
{
   return (2*a);
}

/* ------------------------------ */
int far pascal TestInt(a)
int a;
{
   return (2*a);
}

/* ------------------------------ */
long far pascal TestLong(a)
long a;
{
   return (2*a);
}



/* ============================== */

typedef unsigned short  WORD;
typedef struct fp {
     WORD rows;
     WORD columns;
     double Array[1];
} FP;
typedef struct gp {
     WORD rows;
     WORD columns;
     double Array[6];
} GP;
typedef FP far *LPFP;
typedef GP far *LPGP;


/* ------------------------------ */
LPDOUBLE far pascal TestAddK(a)
LPFP a;
{
     int i,items;
     static double value;

     value = 0.0;
     items = a->rows * a->columns;
     for (i=0 ; i<items ; i++)
        value += a->Array[i];
     return (LPDOUBLE)&value;
}

LPGP far pascal ChangeK(a)
LPFP a;
{
     int i,items;
     static GP b;

     items = a->rows * a->columns;
     b.rows = 2; b.columns = 3;
     for (i=0 ; i<items ; i++)
       b.Array[i] = a->Array[i] + 1;
     return (LPGP)&b;
}



EXAMPLE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\BIFFLIB\EXAMPLE.C



main()
{
  static char *names[6] = { "Yankees\0",
      "Tigers\0",
      "Blue Jays\0",
      "Brewers\0",
      "Red Sox\0",
      "Orioles\0" };

  static int wins[6] = {57, 55, 52, 48, 44, 29};
  static int losses[6] = {18, 20, 23, 27, 31, 46};
  int i;

  create_BIFF("ALEast.xls");
  dimension_BIFF(0, 5, 1, 3);
  for (i = 0; i < 6; i++){
    save_BIFF(8, i, 1, names[i]);
    save_BIFF(2, i, 2, (char *) &wins[i]);
    save_BIFF(2, i, 3, (char *) &losses[i]);
  }
  close_BIFF();
}



EXCLIPRE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\EXCLIPRE.C

/*
 *  Function Name:   ExcludeClipRect
 *  Program Name:    exclipre.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   This function will exclude an area from a region that would otherwise be
 *   accessible.  The program below creates a rectangular region, excludes
 *   part of the rectangle, then inverts the region, showing the excluded
 *   rectangle is unaffected by the inversion.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_ExcludeClipRect(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  HRGN hNewRgn;
  short nRgnType;

  hNewRgn = CreateRectRgn(0, 0, 200, 100);

  nRgnType = ExcludeClipRect(hDC, 50, 20, 100, 50);  /* rectangle clipped   *
                                                      /* from region
  if (nRgnType == 1)                     /* Check for error */
    {
    MessageBox(hWnd,(LPSTR)"SelectClipRgn failed.",(LPSTR)"ERROR",MB_ICONHAND
      return;
    }
  InvertRgn(hDC, hNewRgn);
  DeleteObject( hNewRgn );

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"ExcludeClipRect";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"ExcludeClipRect",
                        (LPSTR)"ExcludeClipRect()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_ExcludeClipRect(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


EXTEXTO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\EXTEXTO.C

/*
 *  Function Name:   ExtTextOut
 *  Program Name:    extexto.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   The program below will display text in the given rectangular region.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_ExtTextOut(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  RECT    rTextRect;
  BOOL    bDrawn;

  rTextRect.left    = 0;
  rTextRect.top     = 0;
  rTextRect.right   = 350;
  rTextRect.bottom  = 25;
                                     /* function demonstrated */
  bDrawn = ExtTextOut (hDC, 10, 10, ETO_CLIPPED, (LPRECT) &rTextRect,
             (LPSTR) "Sample showing ExtTextOut", 25, (LPINT) NULL);

  if (bDrawn == FALSE)
    MessageBox(hWnd, (LPSTR)"ExtTextOut failed", (LPSTR)"ERROR", MB_ICONHAND)
  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );  /* black brush *
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( BLACK_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"ExtTextOut";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"ExtTextOut",
                        (LPSTR)"ExtTextOut()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_ExtTextOut(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


EXUPRG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\EXUPRG.C

/*
 *  Function Name:   ExcludeUpdateRgn
 *  Program Name:    exuprg.c
 *  Special Notes:
 *
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   This program invalidates a rectangular region, then calls the
 *   ExcludeUpdateRgn function to protect the invalidated rectangle from
 *   being overlayed by succeeding regions, in this case an
 *   elliptical region. The display will show that the elliptical region
 *   did not overlay the invalidated rectangular region.

 *   Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_ExcludeUpdateRgn(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  HRGN hRgn;
  RECT rect;

  rect.left=70;               /* region to invalidate  */
  rect.top =70;
  rect.right =200;
  rect.bottom=100;

  InvalidateRect(hWnd,(LPRECT)&rect,TRUE);

  ExcludeUpdateRgn(hDC, hWnd);          /*  function demonstrated  */

  hRgn = CreateEllipticRgn( 50, 50, 400, 150);    /*  new region created  */
  InvertRgn(hDC, hRgn);                           /* invert region to show */
  DeleteObject(hRgn);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"ExcludeUpdateRgn";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"ExcludeUpdateRgn",
                        (LPSTR)"ExcludeUpdateRgn()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_ExcludeUpdateRgn(hWnd, ps.hdc);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}



FAEXIT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\ENDINGS\FAEXIT.C

/*
 *  Function demonstrated in this program: FatalExit
 *  Compiler version: C 5.1
 *
 *  Description:
 *   This function is typically used for debugging and cannot be
 *   demonstrated in this program.  Only a message box will display
 *   in this program.
 */

#include "windows.h"


/* PROTOTYPES */

long  FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
void CALL_FatalExit(HWND hWnd, HDC hDC);
BOOL WinInit(HANDLE hInstance);

/***********************************************************************/

int  PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;
  HDC   hDC;

  if (!hPrevInstance)
  {
/* Call initialization procedure if this is the first instance */
    if (!WinInit( hInstance ))
      return FALSE;
  }

  hWnd = CreateWindow((LPSTR)"FatalExit",
      (LPSTR)"FatalExit()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
  );

/* Make window visible according to the way the app is activated */
  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

  GetDC(hWnd);
  CALL_FatalExit(hWnd, hDC);
  ReleaseDC(hWnd, hDC);

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }

  return (int)msg.wParam;
}


/***********************************************************************/

/* Procedures which make up the window class. */
long  FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  switch (message)
  {
  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}


/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit(hInstance)
HANDLE hInstance;
{
  WNDCLASS   wcClass;

  wcClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcClass.lpfnWndProc    = WndProc;
  wcClass.cbClsExtra     = 0;
  wcClass.cbWndExtra     = 0;
  wcClass.hInstance      = hInstance;
  wcClass.hIcon          = LoadIcon(hInstance, NULL);
  wcClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
  wcClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  wcClass.lpszMenuName   = (LPSTR)NULL;
  wcClass.lpszClassName  = (LPSTR)"FatalExit";

  if (!RegisterClass((LPWNDCLASS) & wcClass))
    return FALSE;

  return TRUE;        /* Initialization succeeded */
}


/***********************************************************************/

void CALL_FatalExit(hWnd, hDC)
HWND hWnd;
HDC hDC;
{

/*  FatalExit(0);  */        /*      FatalExit function  */

  MessageBox(hWnd, (LPSTR)"FatalExit cannot be demonstrated \
- debugging Windows not installed.",
      (LPSTR)"FatalExit", MB_OK);
  return;
}




FILLRECT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\FILLRECT.C

/*
 *  Function (s) demonstrated in this program: FillRect
 *
 *  Description:
 *   This function will fill in a specified area of type RECT with the
 *   designated brush.  The program below fills a red rectangle.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HWND     hWnd;
  WNDCLASS wcClass;
  MSG      msg;

  if (!hPrevInstance)
    {
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon (hInstance, NULL);
    wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    wcClass.lpszMenuName   = NULL;
    wcClass.lpszClassName  = "FILLRECT";

    if (!RegisterClass (&wcClass))
      return FALSE;
    }

  hWnd = CreateWindow ("FILLRECT",
                      "FillRect",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (msg.wParam);
  }

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HDC    hDC;
  HMENU  hMenu;
  HBRUSH hBrush;
  RECT   ShowRect;

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"Fill", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_INITMENU:
      InvalidateRect (hWnd, NULL, TRUE);
      break;

    case WM_COMMAND:
      if (wParam == 100)
        {
        hDC = GetDC (hWnd);
        hBrush = CreateSolidBrush (RGB (255, 0, 0));
        ShowRect.left   = 50;
        ShowRect.top    = 20;
        ShowRect.right  = 400;
        ShowRect.bottom = 100;
        FillRect (hDC, (LPRECT) & ShowRect, hBrush);
        DeleteObject (hBrush);
        ReleaseDC (hWnd, hDC);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
      break;
    }
  return (0L);
  }


FILLRGN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\FILLRGN.C

/*
 *  Function Name:   FillRgn
 *  Program Name:    fillrgn.c
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   The program below will create a region and fill it with a
 *   red background.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_FillRgn (hWnd, hDC)
HWND hWnd;
HDC hDC;
  {
  HBRUSH    hBrush;
  HRGN      hNewRgn;
  RECT      ClientRect;

  hBrush = CreateSolidBrush (RGB (255, 0, 0));   /* hBrush created (red). */
  GetClientRect (hWnd, (LPRECT) &ClientRect);
  hNewRgn = CreateRectRgn (10, 10, (ClientRect.right / 2),
                          (ClientRect.bottom / 2));
  FillRgn (hDC, hNewRgn, hBrush);                /* region filled */
  DeleteObject (hBrush);
  DeleteObject (hNewRgn);
  return;
  }

/**************************************************************************/
BOOL WinInit (hInstance)
HANDLE hInstance;
  {
  WNDCLASS   wcClass;

  wcClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcClass.lpfnWndProc    = WndProc;
  wcClass.cbClsExtra     = 0;
  wcClass.cbWndExtra     = 0;
  wcClass.hInstance      = hInstance;
  wcClass.hIcon          = LoadIcon (hInstance, NULL);
  wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
  wcClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  wcClass.lpszMenuName   = (LPSTR)NULL;
  wcClass.lpszClassName  = (LPSTR)"FillRgn";

  if (!RegisterClass ( (LPWNDCLASS) & wcClass))
    return FALSE;

  return TRUE;        /* Initialization succeeded */
  }


/**************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  if (!hPrevInstance)
    if (!WinInit (hInstance))
      return FALSE;

  hWnd = CreateWindow ( (LPSTR)"FillRgn",
                      (LPSTR)"FillRgn ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,          /* no parent */
                      (HMENU)NULL,         /* use class menu */
                      (HANDLE)hInstance,   /* handle to window instance */
                      (LPSTR)NULL);        /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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

  return (int)msg.wParam;
  }

/**************************************************************************/
long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      CALL_FillRgn (hWnd, ps.hdc);
      ValidateRect (hWnd, (LPRECT) NULL);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


FINDER.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\BIFFLIB\FINDER.C

#include "stdio.h"

/* This function displays the contents of a specific spreadsheet cell */
main()
{

  char filename[12];

  int open_BIFF(), find_BIFF(), close_BIFF();
  int type, row, col;
  int handler(int, char *, int);


  printf("Enter filename\n");
  scanf("%s", filename);
  printf("Enter type\n");
  scanf("%d", &type);
  printf("Enter row\n");
  scanf("%d", &row);
  printf("Enter col\n");
  scanf("%d", &col);

  open_BIFF(filename);
  find_BIFF(type, row, col, handler);
}

int handler(int type, char *data, int length)
{
  int row, column, i;
  unsigned int value;
  double val;
  char *label;

  int get_blank(char *, int *, int *);
  int get_integer(char *, int *, int *, unsigned int *);
  int get_number(char *, int *, int *, double *);
  int get_label(char *, int *, int *,  char **);
  int get_bool(char *, int *, int *, int *);


  switch (type) {
      case 1:
    get_blank(data, &row, &column);
    printf("In row %d column %d is a blank\n", row, column);
    break;
      case 2:
    get_integer(data, &row, &column, &value);
    printf("In row %d column %d is %d\n", row, column, value);
    break;
      case 4:
    get_number(data, &row, &column, &val);
    printf("In row %d column %d is %f\n", row, column, val);
    break;
      case 8:
    get_label(data, &row, &column, &label);
    printf("In row %d column %d is %s\n", row, column, label);
    break;
      case 16:
    get_bool(data, &row, &column, &value);
    printf("In row %d column %d is %d\n", row, column, value);
    break;
  }

}



FINDRES.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\RESOURCE\FINDRES.C

/*
 *
 *  Function (s) demonstrated in this program: FindResource
 *  Compiler version: C 5.1
 *
 *  Description:
 *     This program demonstrates the use of the function FindResource.
 *     This function determines the location of a resource in the specified
 *     resource file.
 *
 *  Other references: Clock.c
 *
 */

#include <windows.h>
#include "findres.h"

static HANDLE hInst;
static char  szFileName[] = "FindRes";
static char  szFuncName[] = "FindResource";

long FAR PASCAL WindowProc (HANDLE, unsigned, WORD, LONG);
BOOL FAR PASCAL FunctionDemonstrated (HWND);

/***************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  MSG  msg;

  WindowInit (hInstance, hPrevInstance, cmdShow);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  exit (msg.wParam);
  }

/***************************************************************************/

BOOL WindowInit (hInstance, hPrevInstance, cmdShow)
HANDLE hInstance, hPrevInstance;
int  cmdShow;
  {
  HWND  hWnd;

  if (!hPrevInstance)
    {
    WNDCLASS rClass;

    rClass.style      = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WindowProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor          = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon            = LoadIcon (hInstance, szFileName);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = szFileName;
    rClass.lpszClassName = szFileName;

    RegisterClass ( (LPWNDCLASS) & rClass);
    }

  hInst = hInstance;

  hWnd = CreateWindow (szFileName, szFuncName,
                      WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
  }

/***************************************************************************/

long    FAR PASCAL WindowProc (hWnd, iMessage, wParam, lParam)
HWND      hWnd;
unsigned    iMessage;
WORD      wParam;
LONG      lParam;
  {
  HMENU  hMenu;

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();     /*  Add a menu item */
      ChangeMenu (hMenu, NULL, (LPSTR)"FindResource", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_COMMAND:
      if (wParam == 100)  /*  Our Menu item  */
        FunctionDemonstrated (hWnd);
      else
        return (DefWindowProc (hWnd, iMessage, wParam, lParam));
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
      break;
    }
  return (0L);
  }

/***************************************************************************/

BOOL FAR PASCAL FunctionDemonstrated (hWnd)
HWND hWnd;
  {
  MessageBox (NULL, "Looking for resource FindRes", szFuncName, MB_OK);
  if (FindResource (hInst, "FindRes", RT_ICON))
    MessageBox (NULL, "Resource found", szFuncName, MB_OK);
  else
    MessageBox (NULL, "Resource not found", szFuncName, MB_OK);
  return (TRUE);
  }


FINDWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\FINDWIN.C

/*
 *
 *  FindWindow
 *
 *  findwin.c, charlesl, v2.00, 30-Dec-1987
 *
 *  This program demonstrates the use of FindWindow function.
 *  This function the handle of the window whose class is given
 *  by it's frist parameter and whose window name (caption) is
 *  given by is second parameter.
 *
 *  Microsoft Product Support Services
 *  Windows Version 2.0 function demonstration application
 *  Copyright (c) Microsoft 1987
 *
 */

/*************************************************************************/
/*                           INCLUDE FILES                               */
/*************************************************************************/

#include <windows.h>

/*************************************************************************/
/*                        STRUCTURE DEFINTIONS                           */
/*************************************************************************/

typedef struct
{
   int nDummy;
}
SETUPDATA;

/*************************************************************************/
/*                         GLOBAL VARIABLES                              */
/*************************************************************************/

static SETUPDATA strSetUpData;
static HANDLE hInst;
static char szFileName[] = "findwin";
static char szFuncName[] = "FindWindow";

/*************************************************************************/
/*                       FORWARD REFERENCES                              */
/*************************************************************************/

long FAR PASCAL WindowProc ( HANDLE , unsigned , WORD , LONG );

/*************************************************************************/
/*                         MAIN PROCEDURE                                */
/*************************************************************************/

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  MSG  msg;

  WindowInit (hInstance, hPrevInstance, cmdShow );

  while ( GetMessage((LPMSG)&msg, NULL, 0 , 0 ))
    {
    TranslateMessage((LPMSG)&msg);
    DispatchMessage((LPMSG)&msg);
    }
  exit(msg.wParam);
}

/*************************************************************************/
/*                      INITIALIZATION                                   */
/*************************************************************************/

BOOL WindowInit (hInstance , hPrevInstance , cmdShow)
HANDLE hInstance, hPrevInstance;
int cmdShow;
{
  HWND  hWnd;

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.lpfnWndProc   = WindowProc;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;
     rClass.hInstance     = hInstance;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.lpszMenuName  = (LPSTR) NULL;
     rClass.lpszClassName = (LPSTR) szFileName;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }
  else
     GetInstanceData ( hPrevInstance, (PSTR) &strSetUpData,
        sizeof ( SETUPDATA ) );

  hInst = hInstance;

  hWnd = CreateWindow ( (LPSTR) szFileName, (LPSTR) szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      (HWND) NULL, (HMENU) NULL,
                      (HANDLE) hInstance, (LPSTR) NULL );

  ShowWindow ( hWnd , cmdShow );
  UpdateWindow (hWnd);

  return TRUE;
}

/*************************************************************************/
/*                 WINDOW PROCEDURE - PROCESS MESSAGES                   */
/*************************************************************************/

long FAR PASCAL WindowProc (hWnd , message , wParam , lParam)
HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint ( hWnd, (LPPAINTSTRUCT)&ps );
        FunctionDemonstrated ( hWnd, (PAINTSTRUCT *)&ps );
        EndPaint ( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage ( 0 );
        break;

    default:
        return ( DefWindowProc ( hWnd , message , wParam , lParam ) );
        break;
    }
  return ( 0L );
}

/*************************************************************************/
/*              FUNCTION DEMONSTRATED HERE - LOOK HERE                   */
/*************************************************************************/

FunctionDemonstrated ( hWnd )
HWND hWnd;
{
    HWND hFindWnd;

    MessageBox (NULL, (LPSTR)"Searching for Window", (LPSTR)szFuncName,
       MB_OK);

    hFindWnd = FindWindow ( ( LPSTR ) "findwin", ( LPSTR ) "FindWindow" );

    if ( hFindWnd != NULL )
       MessageBox (NULL, (LPSTR)"Window Found", (LPSTR)szFuncName, MB_OK);
    else
       MessageBox (NULL, (LPSTR)"Window not Found", (LPSTR)szFuncName, MB_OK)

    return TRUE;
}


FINDWIND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\FINDWIND.C

/*
 *
 * Function (s) demonstrated in this program: FindWindow
 * Compiler version:  C 5.10
 *
 * Description:  This function returns a handle to the Window whose caption
 *    matches the caption parameter.  If no match is found a NULL handle is
 *         returned.  The program will tell the MS-DOS executive to minimize
 *         itself.
 */

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "FindWind.h"

void ProcessMessage (HWND, int);

HWND     hWndParent1;
HANDLE   hInstMain;

char  szOutputBuffer1 [70];
char  szOutputBuffer2 [500];

struct   {
  char  *szMessage;
  } Messages [] =   {
  "About\0",
  "     This is a sample application to demonstrate the\n\
use of the FindWindow Windows function.",

  "Help Message",
  "     This program uses the FindWindow Windows function\n\
to get a handle to the MS-DOS Executive.  This handle\n\
is then displayed in a message box.  The MS-DOS\n\
Executive is then Iconized.  Use the menu to invoke\n\
this function.",

  };


/****************************************************************************

void ProcessMessage (hWnd, MessageNumber)
HWND     hWnd;
int  MessageNumber;
  {
  sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
  sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
  MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
  }


/****************************************************************************

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int      nCmdShow;
  {
  static char   szAppName [] = "FindWind";
  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG msg;
  short xScreen, yScreen;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = szAppName;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  xScreen = GetSystemMetrics (SM_CXSCREEN);
  yScreen = GetSystemMetrics (SM_CYSCREEN);

  hWndParent1 = CreateWindow (szAppName,          /* window class name
                             "FindWindow",        /* window caption
                             WS_OVERLAPPEDWINDOW, /* window style
                             CW_USEDEFAULT,       /* initial x position
                             0,                   /* initial y position
                             CW_USEDEFAULT,       /* initial x size
                             0,                   /* initial y size
                             NULL,                /* parent window handle
                             NULL,                /* window menu handle
                             hInstance,           /* program instance handle
                             NULL);               /* create parameters

  ShowWindow (hWndParent1, nCmdShow);
  UpdateWindow (hWndParent1);

  hInstMain = hInstance;

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

/****************************************************************************
long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND      hWnd;
unsigned  iMessage;
WORD      wParam;
LONG      lParam;
  {
  HMENU       hMenu;
  HWND        hExecutive;
  PAINTSTRUCT ps;
  static int    xClient, yClient;

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = GetSystemMenu (hWnd, FALSE);

      ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT, MF_APPEND | MF_STRING);
      break;

    case WM_SYSCOMMAND:
      switch (wParam)
        {
        case IDM_ABOUT:
          ProcessMessage (hWnd, 0);
          break;
        default:
          return DefWindowProc (hWnd, iMessage, wParam, lParam);
        }
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_FINDWINDOW:
          hExecutive = FindWindow (NULL, "MS-DOS Executive");
          if (!IsIconic (hExecutive))
            ShowWindow (hExecutive, SW_SHOWMINIMIZED);
          break;

        case IDM_HELP:
          ProcessMessage (hWnd, 2);
          break;
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


FLASHWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\FLASHWIN.C

/*
 *
 *  Function demonstrated in this program: FlashWindow
 *  Compiler version: C 5.1
 *
 *  This program demonstrates the use of the function FlashWin. This function
 *  "flashes" the given window once. Flashing window means changing the
 *  appearance of its caption bar or icon as if the window were changing form
 *  inactive to active status, or vice versa. (A grey caption bar or unframed
 *  incon changes to a black caption bar or framed icon; a black caption bar
 *  or framed icon changes to a grey caption bar or unframed icon.)
 *
 */

#include <windows.h>

LONG FAR PASCAL WindowProc (HANDLE, unsigned, WORD, LONG);

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
  {
  MSG  msg;
  HWND hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    WNDCLASS rClass;

    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WindowProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = (LPSTR) NULL;
    rClass.lpszClassName = (LPSTR) "flashwin";

    if (!RegisterClass ( ( LPWNDCLASS) &rClass))
      return FALSE;
    }

  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, "Flash!", 100, MF_APPEND);

  hWnd = CreateWindow ( (LPSTR) "flashwin", (LPSTR) "FlashWindow",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      (HWND) NULL, (HMENU) hMenu,
                      (HANDLE) hInstance, (LPSTR) NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG)&msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG)&msg);
    DispatchMessage ( (LPMSG)&msg);
    }
  exit (msg.wParam);
  }

long FAR PASCAL WindowProc (hWnd, message, wParam, lParam)
HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
  {
  static BOOL bInverted = TRUE;  /* To keep track of Active State of Window *

  switch (message)
    {
    case WM_COMMAND:
      if (wParam == 100)
        FlashWindow (hWnd, TRUE);
      else
        return (DefWindowProc (hWnd, message, wParam, lParam));
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
      break;
    }
  return (0L);
  }


FLOODFIL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\FLOODFIL.C

/*
 *
 *  Functions demonstrated in this program: FloodFill
 *  Compiler version: C 5.1
 *
 *  This program demonstrates the use of FloodFill function.
 *  This function fills an area of the suface with the current
 *  brush. The area is assumed to be bounded by the given
 *  rgbColor. The function begins at the point specified by
 *  the logical coordinates X, Y and continues in all directions
 *  to the color boundary.
 *
 */

#include <windows.h>

static HANDLE hInst;
static char szFileName[] = "floodfil";
static char szFuncName[] = "FloodFill";

long FAR PASCAL WindowProc (HANDLE, unsigned, WORD, LONG);

/**************************************************************************/

int PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
  {
  MSG  msg;

  WindowInit (hInstance, hPrevInstance, cmdShow);
  while (GetMessage ( (LPMSG)&msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG)&msg);
    DispatchMessage ( (LPMSG)&msg);
    }
  exit (msg.wParam);
  }
/**************************************************************************/

BOOL WindowInit (hInstance, hPrevInstance, cmdShow)
HANDLE hInstance, hPrevInstance;
int cmdShow;
  {
  HWND  hWnd;

  if (!hPrevInstance)
     {
     WNDCLASS rClass;

     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.lpfnWndProc   = WindowProc;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;
     rClass.hInstance     = hInstance;
     rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
     rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
     rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
     rClass.lpszMenuName  = (LPSTR) NULL;
     rClass.lpszClassName = (LPSTR) szFileName;

     if (!RegisterClass ( ( LPWNDCLASS) &rClass))
       return FALSE;
     }

  hInst = hInstance;

  hWnd = CreateWindow ( (LPSTR) szFileName, (LPSTR) szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      (HWND) NULL, (HMENU) NULL,
                      (HANDLE) hInstance, (LPSTR) NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
  }
/**************************************************************************/

long FAR PASCAL WindowProc (hWnd, message, wParam, lParam)
HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT)&ps);
      FunctionDemonstrated (hWnd, (PAINTSTRUCT *)&ps);
      EndPaint (hWnd, (LPPAINTSTRUCT)&ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
      break;
    }
  return (0L);
  }

/*************************************************************************/
/*              FUNCTION DEMONSTRATED HERE - LOOK HERE                   */
/*************************************************************************/

FunctionDemonstrated (hWnd, pps)
HWND hWnd;
PAINTSTRUCT *pps;
  {
  HDC hDC = pps->hdc;
  HPEN hPen;
  HPEN hMyPen;
  HBRUSH hBrush;
  HBRUSH hMyBrush;
  BOOL bFilled;

/*  Creating a rectangle to fill */
  hMyPen = CreatePen (0, 1, RGB (0, 0, 255));
  hPen = SelectObject (hDC, hMyPen);
  Rectangle (hDC, 0, 0, 500, 200);
  hMyPen = SelectObject (hDC, hPen);
  DeleteObject (hMyPen);

/* Getting a brush to do the filling */
  hMyBrush = GetStockObject (GRAY_BRUSH);
  hBrush = SelectObject (hDC, hMyBrush);

  FloodFill (hDC, 52, 48, RGB (0, 0, 255));

  hMyBrush = SelectObject (hDC, hBrush);

  return TRUE;
  }


FLUSHCOM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\FLUSHCOM.C

/*
 *
 *  Function demonstrated in this program: FlushComm
 *
 *  This program demonstrates the use of the function FlushComm.
 *  This function flushes all characters from the transmit or recieve
 *  queue of the communication device specified by the first parameter.
 *  The second parameter speifies which queue (transmit or receive) to
 *  be flushed.
 *
 */

#include <windows.h>

static char  szAppName[] = "flushcom";
static char  szFuncName[] = "FlushComm";

long    FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = szAppName;

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hWnd = CreateWindow (szAppName,
                      szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (msg.wParam);
  }

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HMENU hMenu;
  BOOL  bError;
  int  nCid;
  int  nResult;

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"Flush Port", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_COMMAND:
      if (wParam == 100)
        {
        bError = FALSE;
        nCid = OpenComm ( (LPSTR) "LPT1", 255, 256);

        if ( (nCid & IE_BADID) == IE_BADID)
          {
          MessageBox (hWnd, (LPSTR)"Invalid or unsupported ID.",
              (LPSTR)szFuncName, MB_OK);
          bError = TRUE;
          }
        if ( (nCid & IE_BAUDRATE) == IE_BAUDRATE)
          {
          MessageBox (hWnd, (LPSTR)"Unsupported baud rate.",
              (LPSTR)szFuncName, MB_OK);
          bError = TRUE;
          }
        if ( (nCid & IE_BYTESIZE) == IE_BYTESIZE)
          {
          MessageBox (hWnd, (LPSTR)"Invalid byte size.", (LPSTR)szFuncName,
              MB_OK);
          bError = TRUE;
          }
        if ( (nCid & IE_DEFAULT) == IE_DEFAULT)
          {
          MessageBox (hWnd, (LPSTR)"Error in default parameters.",
              (LPSTR)szFuncName, MB_OK);
          bError = TRUE;
          }
        if ( (nCid & IE_HARDWARE) == IE_HARDWARE)
          {
          MessageBox (hWnd, (LPSTR)"Hardware not present.", (LPSTR)szFuncName
              MB_OK);
          bError = TRUE;
          }
        if ( (nCid & IE_MEMORY) == IE_MEMORY)
          {
          MessageBox (hWnd, (LPSTR)"Device not open.", (LPSTR)szFuncName,
              MB_OK);
          bError = TRUE;
          }
        if ( (nCid & IE_NOPEN) == IE_NOPEN)
          {
          MessageBox (hWnd, (LPSTR)"Device not opened.", (LPSTR)szFuncName,
              MB_OK);
          bError = TRUE;
          }
        if ( (nCid & IE_OPEN) == IE_OPEN)
          {
          MessageBox (hWnd, (LPSTR)"Device already open.", (LPSTR)szFuncName,
              MB_OK);
          bError = TRUE;
          }
        if (!bError)
          {
          MessageBox (hWnd, (LPSTR)"Flushing LPT1", (LPSTR)szFuncName, MB_OK)
          nResult = FlushComm (nCid, 0);
          if (nResult == 0)
            MessageBox (hWnd, (LPSTR)"LPT1 flushed", (LPSTR)szFuncName,
                MB_OK);
          else
            MessageBox (hWnd, (LPSTR)"LPT1 not flushed", (LPSTR)szFuncName,
                MB_OK);
          }
        CloseComm (nCid);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, iMessage, wParam, lParam));
    }
  return (0L);
  }


FRAMEREC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\FRAMEREC.C

/*
 * Function (s) demonstrated in this program: FrameRect
 * Compiler version: C 5.1
 *
 * Description:
 *    FrameRect draws a border around a specified rectangle using
 *    a specified brush.
 */

#include "windows.h"

int     PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
BOOL FrameRectInit (HANDLE);
long    FAR PASCAL FrameRectWndProc (HWND, unsigned, WORD, LONG);

HANDLE hInst;

/**************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;           /* current instance             */
HANDLE hPrevInstance;       /* previous instance            */
LPSTR lpCmdLine;            /* command line                 */
int     nCmdShow;               /* show-window type (open/icon) */
  {
  HWND hWnd;              /* window handle                */
  MSG msg;                /* message                      */

  if (!hPrevInstance)     /* Has application been initialized? */
    if (!FrameRectInit (hInstance))
      return (NULL);  /* Exits if unable to initialize     */

  hInst = hInstance;      /* Saves the current instance        */

  hWnd = CreateWindow ("FrameRect",   /* window class            */
                      "FrameRect Sample Application", /* window name
                      WS_OVERLAPPEDWINDOW,           /* window style
                      CW_USEDEFAULT,                 /* x position
                      CW_USEDEFAULT,                 /* y position
                      CW_USEDEFAULT,                 /* width
                      CW_USEDEFAULT,                 /* height
                      NULL,                          /* parent handle
                      NULL,                          /* menu or child ID
                      hInstance,                     /* instance
                      NULL);                         /* additional info

  if (!hWnd)
    return (NULL);

  ShowWindow (hWnd, nCmdShow);        /* Shows the window        */
  UpdateWindow (hWnd);                /* Sends WM_PAINT message  */

  while (GetMessage (&msg, NULL, NULL, NULL))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return (msg.wParam);
  }


/*************************************************************************/

BOOL FrameRectInit (hInstance)
HANDLE hInstance;
  {
  HANDLE hMemory;
  PWNDCLASS pWndClass;
  BOOL bSuccess;

  hMemory = LocalAlloc (LPTR, sizeof (WNDCLASS));
  pWndClass = (PWNDCLASS) LocalLock (hMemory);

  pWndClass->style = NULL;
  pWndClass->lpfnWndProc = FrameRectWndProc;
  pWndClass->hInstance = hInstance;
  pWndClass->hIcon = NULL;
  pWndClass->hCursor = LoadCursor (NULL, IDC_ARROW);
  pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  pWndClass->lpszMenuName = (LPSTR) "FrameRectMenu";
  pWndClass->lpszClassName = (LPSTR) "FrameRect";

  bSuccess = RegisterClass (pWndClass);

  LocalUnlock (hMemory);
  LocalFree (hMemory);

  return (bSuccess);
  }


/**************************************************************************/

long    FAR PASCAL FrameRectWndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  FARPROC lpProcAbout;        /* pointer to the "About" function */
  RECT  rRect;                /* Will hold client rectangle  */
  HANDLE hDC;                 /* Handle to the display context  */
  PAINTSTRUCT ps;             /* Paint Structure  */
  HBRUSH hPaintBrush;         /* Brush to draw border with  */

  switch (message)
    {
    case WM_SIZE:
    case WM_PAINT:
      GetClientRect (hWnd, (LPRECT) & rRect); /*  Structure holding  */
      InvalidateRect (hWnd, (LPRECT) & rRect, TRUE);
        /*  Erase the background  */
      hDC = BeginPaint (hWnd, &ps);   /*  Get the display context  */
        /*  Make a border inside of the window  */
      rRect.right -= 10;
      rRect.left += 10;
      rRect.top += 10;
      rRect.bottom -= 10;
      hPaintBrush = GetStockObject (BLACK_BRUSH);
        /* Get a dark gray brush */
      FrameRect (hDC, (LPRECT) & rRect, hPaintBrush);
        /* Draw the border with a BLACK_BRUSH */
      EndPaint (hWnd, &ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

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


FRAMEREC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\FRAMEREC.C

/*
 * Function (s) demonstrated in this program: FrameRect
 * Compiler version: C 5.1
 *
 * Description:
 *    FrameRect draws a border around a specified rectangle using
 *    a specified brush.
 */

#include "windows.h"

int     PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
BOOL FrameRectInit (HANDLE);
long    FAR PASCAL FrameRectWndProc (HWND, unsigned, WORD, LONG);

HANDLE hInst;

/**************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;           /* current instance             */
HANDLE hPrevInstance;       /* previous instance            */
LPSTR lpCmdLine;            /* command line                 */
int     nCmdShow;               /* show-window type (open/icon) */
  {
  HWND hWnd;              /* window handle                */
  MSG msg;                /* message                      */

  if (!hPrevInstance)     /* Has application been initialized? */
    if (!FrameRectInit (hInstance))
      return (NULL);  /* Exits if unable to initialize     */

  hInst = hInstance;      /* Saves the current instance        */

  hWnd = CreateWindow ("FrameRect",   /* window class            */
                      "FrameRect Sample Application", /* window name
                      WS_OVERLAPPEDWINDOW,           /* window style
                      CW_USEDEFAULT,                 /* x position
                      CW_USEDEFAULT,                 /* y position
                      CW_USEDEFAULT,                 /* width
                      CW_USEDEFAULT,                 /* height
                      NULL,                          /* parent handle
                      NULL,                          /* menu or child ID
                      hInstance,                     /* instance
                      NULL);                         /* additional info

  if (!hWnd)
    return (NULL);

  ShowWindow (hWnd, nCmdShow);        /* Shows the window        */
  UpdateWindow (hWnd);                /* Sends WM_PAINT message  */

  while (GetMessage (&msg, NULL, NULL, NULL))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return (msg.wParam);
  }


/*************************************************************************/

BOOL FrameRectInit (hInstance)
HANDLE hInstance;
  {
  HANDLE hMemory;
  PWNDCLASS pWndClass;
  BOOL bSuccess;

  hMemory = LocalAlloc (LPTR, sizeof (WNDCLASS));
  pWndClass = (PWNDCLASS) LocalLock (hMemory);

  pWndClass->style = NULL;
  pWndClass->lpfnWndProc = FrameRectWndProc;
  pWndClass->hInstance = hInstance;
  pWndClass->hIcon = NULL;
  pWndClass->hCursor = LoadCursor (NULL, IDC_ARROW);
  pWndClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  pWndClass->lpszMenuName = (LPSTR) "FrameRectMenu";
  pWndClass->lpszClassName = (LPSTR) "FrameRect";

  bSuccess = RegisterClass (pWndClass);

  LocalUnlock (hMemory);
  LocalFree (hMemory);

  return (bSuccess);
  }


/**************************************************************************/

long    FAR PASCAL FrameRectWndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  FARPROC lpProcAbout;        /* pointer to the "About" function */
  RECT  rRect;                /* Will hold client rectangle  */
  HANDLE hDC;                 /* Handle to the display context  */
  PAINTSTRUCT ps;             /* Paint Structure  */
  HBRUSH hPaintBrush;         /* Brush to draw border with  */

  switch (message)
    {
    case WM_SIZE:
    case WM_PAINT:
      GetClientRect (hWnd, (LPRECT) & rRect); /*  Structure holding  */
      InvalidateRect (hWnd, (LPRECT) & rRect, TRUE);
        /*  Erase the background  */
      hDC = BeginPaint (hWnd, &ps);   /*  Get the display context  */
        /*  Make a border inside of the window  */
      rRect.right -= 10;
      rRect.left += 10;
      rRect.top += 10;
      rRect.bottom -= 10;
      hPaintBrush = GetStockObject (BLACK_BRUSH);
        /* Get a dark gray brush */
      FrameRect (hDC, (LPRECT) & rRect, hPaintBrush);
        /* Draw the border with a BLACK_BRUSH */
      EndPaint (hWnd, &ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

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


FRAMERGN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\FRAMERGN.C

/*
 *
 *  Function (s) demonstrated in this program: FrameRgn
 *  Compiler version: C 5.1
 *
 *  Description:
 *     This program demonstrates the use of the function FrameRgn.
 *     This function draws a border around the region specified by a
 *     handle to a region, using the brush specified by a hanle to a
 *     brush. The fourth parameter specifies the width of the border
 *     on vertical brush strokes, and the fifth parameter specifies
 *     the height on horizontal strokes.
 *
 */

#include <windows.h>

long    FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = "framergn";

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hWnd = CreateWindow ("framergn",            /* window class name       */
                      "FrameRgn",                 /* window caption
                      WS_OVERLAPPEDWINDOW,        /* window style
                      CW_USEDEFAULT,              /* initial x position
                      0,                          /* initial y position
                      CW_USEDEFAULT,              /* initial x size
                      0,                          /* initial y size
                      NULL,                       /* parent window handle
                      NULL,                       /* window menu handle
                      hInstance,                  /* program instance handle
                      NULL);                      /* create parameters

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (msg.wParam);
  }

long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
  {
  HDC    hDC;
  HMENU  hMenu;
  HRGN   hRgn;
  HBRUSH hBrush;

  switch (message)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"Frame", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_INITMENU:
      InvalidateRect (hWnd, NULL, TRUE);
      break;

    case WM_COMMAND:
      if (wParam == 100)
        {
        hRgn = CreateRectRgn (1, 1, 200, 100);
        hBrush = CreateSolidBrush ( (DWORD) 0x0000FF);
        hDC = GetDC (hWnd);
        FrameRgn (hDC, hRgn, hBrush, 10, 10);
        DeleteObject (hRgn);
        DeleteObject (hBrush);
        ReleaseDC (hWnd, hDC);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
    }
  return (0L);
  }


FRAMERGN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\FRAMERGN.C

/*
 *
 *  Function (s) demonstrated in this program: FrameRgn
 *  Compiler version: C 5.1
 *
 *  Description:
 *     This program demonstrates the use of the function FrameRgn.
 *     This function draws a border around the region specified by a
 *     handle to a region, using the brush specified by a hanle to a
 *     brush. The fourth parameter specifies the width of the border
 *     on vertical brush strokes, and the fifth parameter specifies
 *     the height on horizontal strokes.
 *
 */

#include <windows.h>

long    FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = "framergn";

    if (!RegisterClass (&rClass))
      return FALSE;
    }

  hWnd = CreateWindow ("framergn",            /* window class name       */
                      "FrameRgn",                 /* window caption
                      WS_OVERLAPPEDWINDOW,        /* window style
                      CW_USEDEFAULT,              /* initial x position
                      0,                          /* initial y position
                      CW_USEDEFAULT,              /* initial x size
                      0,                          /* initial y size
                      NULL,                       /* parent window handle
                      NULL,                       /* window menu handle
                      hInstance,                  /* program instance handle
                      NULL);                      /* create parameters

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (msg.wParam);
  }

long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND        hWnd;
unsigned    message;
WORD        wParam;
LONG        lParam;
  {
  HDC    hDC;
  HMENU  hMenu;
  HRGN   hRgn;
  HBRUSH hBrush;

  switch (message)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"Frame", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_INITMENU:
      InvalidateRect (hWnd, NULL, TRUE);
      break;

    case WM_COMMAND:
      if (wParam == 100)
        {
        hRgn = CreateRectRgn (1, 1, 200, 100);
        hBrush = CreateSolidBrush ( (DWORD) 0x0000FF);
        hDC = GetDC (hWnd);
        FrameRgn (hDC, hRgn, hBrush, 10, 10);
        DeleteObject (hRgn);
        DeleteObject (hBrush);
        ReleaseDC (hWnd, hDC);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
    }
  return (0L);
  }


FREERES.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\FREERES\FREERES.C

/*
 *
 *   Functions (s) demonstrated in this program: FreeResource
 *   Compiler version: C 5.1
 *
 *   Description:
 *      This program demonstrates the use of the function FreeResource.
 *      FreeResource removes a loaded resource from memory by freeing the
 *      allocated memory occupied by that resource.
 */

#include "windows.h"
#include "freeres.h"
#include "string.h"

char  szAppName[10];
static HANDLE hInst;
static short    xChar, yChar;

long    FAR PASCAL FreeresWndProc (HWND, unsigned, WORD, LONG);
void FreeresPaint (HWND hWnd, HDC hDC);
BOOL FreeresInit (HANDLE hInstance);

/***************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  if (!hPrevInstance)
    {
    if (!FreeresInit (hInstance))
      return FALSE;
    }
  else
    {
         /* Copy data from previous instance */
    GetInstanceData (hPrevInstance, (PSTR)szAppName, 10);
    }
  hWnd = CreateWindow (szAppName, "FreeResource",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      NULL, NULL, hInstance, NULL);
  hInst = hInstance;

    /* Make window visible according to the way the app is activated */
  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL FreeresWndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  PAINTSTRUCT  ps;
  TEXTMETRIC   tm;
  HDC          hDC;

  switch (message)
    {
    case WM_CREATE:
        {
        hDC = GetDC (hWnd);
        GetTextMetrics (hDC, &tm);
        ReleaseDC (hWnd, hDC);
        xChar = tm.tmAveCharWidth;
        yChar = tm.tmHeight + tm.tmExternalLeading;
        break;
        }
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      FreeresPaint (hWnd, ps.hdc);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }

/* Procedure called when the application is loaded for the first time */
BOOL FreeresInit (hInstance)
HANDLE hInstance;
  {
  PWNDCLASS  pFreeresClass;

/* Load strings from resource */
  LoadString (hInstance, IDSNAME, szAppName, 10);

  pFreeresClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));
  pFreeresClass->hCursor       = LoadCursor (NULL, IDC_ARROW);
  pFreeresClass->hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
  pFreeresClass->lpszMenuName  = NULL;
  pFreeresClass->lpszClassName = szAppName;
  pFreeresClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  pFreeresClass->hInstance     = hInstance;
  pFreeresClass->style         = CS_HREDRAW | CS_VREDRAW;
  pFreeresClass->lpfnWndProc   = FreeresWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pFreeresClass))
    return FALSE;

  LocalFree ( (HANDLE)pFreeresClass);
  return TRUE;
  }

/***************************************************************************/
void FreeresPaint (hWnd, hDC)
HWND hWnd;
HDC  hDC;
  {
  GLOBALHANDLE hBitmap1Data; /* Handle to global memory containing bitmap */
  HBITMAP hBitmap1Info;
  BOOL nResult;

/* This section demonstrates the use of FreeResource */

/* Locate the bitmap in the resource file and identify it with a handle */
  hBitmap1Info = FindResource (hInst, "face1", RT_BITMAP);

/* Identify the global memory block to receive the bitmap data */
  hBitmap1Data = LoadResource (hInst, hBitmap1Info);

  nResult = FreeResource (hBitmap1Info);         /* Free allocated memory */

  if (!nResult)
    TextOut (hDC, xChar, yChar, "FreeResource did not work", 25);
  else
    TextOut (hDC, xChar, yChar, "FreeResource worked", 19);
  }


FREERES.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\RESOURCE\FREERES.C

/*
 *
 *   Functions (s) demonstrated in this program: FreeResource
 *   Compiler version: C 5.1
 *
 *   Description:
 *      This program demonstrates the use of the function FreeResource.
 *      FreeResource removes a loaded resource from memory by freeing the
 *      allocated memory occupied by that resource.
 */

#include "windows.h"
#include "freeres.h"
#include "string.h"

char  szAppName[10];
static HANDLE hInst;
static short    xChar, yChar;

long    FAR PASCAL FreeresWndProc (HWND, unsigned, WORD, LONG);
void FreeresPaint (HWND hWnd, HDC hDC);
BOOL FreeresInit (HANDLE hInstance);

/***************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;

  if (!hPrevInstance)
    {
    if (!FreeresInit (hInstance))
      return FALSE;
    }
  else
    {
         /* Copy data from previous instance */
    GetInstanceData (hPrevInstance, (PSTR)szAppName, 10);
    }
  hWnd = CreateWindow (szAppName, "FreeResource",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      NULL, NULL, hInstance, NULL);
  hInst = hInstance;

    /* Make window visible according to the way the app is activated */
  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL FreeresWndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  PAINTSTRUCT  ps;
  TEXTMETRIC   tm;
  HDC          hDC;

  switch (message)
    {
    case WM_CREATE:
        {
        hDC = GetDC (hWnd);
        GetTextMetrics (hDC, &tm);
        ReleaseDC (hWnd, hDC);
        xChar = tm.tmAveCharWidth;
        yChar = tm.tmHeight + tm.tmExternalLeading;
        break;
        }
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      FreeresPaint (hWnd, ps.hdc);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }

/* Procedure called when the application is loaded for the first time */
BOOL FreeresInit (hInstance)
HANDLE hInstance;
  {
  PWNDCLASS  pFreeresClass;

/* Load strings from resource */
  LoadString (hInstance, IDSNAME, szAppName, 10);

  pFreeresClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));
  pFreeresClass->hCursor       = LoadCursor (NULL, IDC_ARROW);
  pFreeresClass->hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
  pFreeresClass->lpszMenuName  = NULL;
  pFreeresClass->lpszClassName = szAppName;
  pFreeresClass->hbrBackground = GetStockObject (WHITE_BRUSH);
  pFreeresClass->hInstance     = hInstance;
  pFreeresClass->style         = CS_HREDRAW | CS_VREDRAW;
  pFreeresClass->lpfnWndProc   = FreeresWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pFreeresClass))
    return FALSE;

  LocalFree ( (HANDLE)pFreeresClass);
  return TRUE;
  }

/***************************************************************************/
void FreeresPaint (hWnd, hDC)
HWND hWnd;
HDC  hDC;
  {
  GLOBALHANDLE hBitmap1Data; /* Handle to global memory containing bitmap */
  HBITMAP hBitmap1Info;
  BOOL nResult;

/* This section demonstrates the use of FreeResource */

/* Locate the bitmap in the resource file and identify it with a handle */
  hBitmap1Info = FindResource (hInst, "face1", RT_BITMAP);

/* Identify the global memory block to receive the bitmap data */
  hBitmap1Data = LoadResource (hInst, hBitmap1Info);

  nResult = FreeResource (hBitmap1Info);         /* Free allocated memory */

  if (!nResult)
    TextOut (hDC, xChar, yChar, "FreeResource did not work", 25);
  else
    TextOut (hDC, xChar, yChar, "FreeResource worked", 19);
  }


FREERES1.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\FREERES\FREERES1.C

/*
 *
 *   FreeResource
 *   freeres1.c travisd, v1.00, 29-Dec-1987
 *
 *   This program demonstrates the use of the function FreeResource.
 *   FreeResource removes a loaded resource from memory by freeing the
 *   alllocated memory occupied by that resource.
 *
 *   Microsoft Product Support Services
 *   Windows Version 2.0 function demonstration application
 *   Copyright (c) Microsoft 1987
 *
 */

#include "windows.h"
#include "freeres1.h"
#include "string.h"

char szAppName[10];
static HANDLE hInst;

/* Forward-Reference All Functions */

long FAR PASCAL FreeRes1WndProc(HWND, unsigned, WORD, LONG);

/* --------------------------------------------------------------------- */

void FreeRes1Paint(hWnd, hDC )
HWND hWnd;
HDC  hDC;

{
    GLOBALHANDLE hBitmap1Data; /* Handle to global memory containing bitmap *
    HBITMAP hBitmap1Info;
    BOOL nResult;

/***************************************************************************/
/* This section demonstrates the use of FreeResource */

   /* Locate the bitmap in the resource file and identify it with a handle */
    hBitmap1Info = FindResource(hInst, "face1", RT_BITMAP);

            /* Identify the global memory block to receive the bitmap data */
    hBitmap1Data = LoadResource(hInst, hBitmap1Info);

    nResult = FreeResource(hBitmap1Info);         /* Free allocated memory */
    if (nResult = FALSE)
       {
       TextOut( hDC, 10, 10, (LPSTR)"FreeResource did not work",
                strlen("FreeResource did not work") );
       }
    else
       {
       TextOut( hDC, 10, 10, (LPSTR)"FreeResource worked",
                strlen("FreeResource worked") );
       }

/* End of the FreeResource demonstration section */
/***************************************************************************/
}
/* End FreeRes1Paint */
/* --------------------------------------------------------------------- */

/* Procedure called when the application is loaded for the first time */
BOOL FreeRes1Init( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pFreeRes1Class;

    /* Load strings from resource */
    LoadString( hInstance, IDSNAME, (LPSTR)szAppName, 10 );

    pFreeRes1Class = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pFreeRes1Class->hCursor       = LoadCursor( NULL, IDC_ARROW );
    pFreeRes1Class->hIcon         = LoadIcon( hInstance, MAKEINTRESOURCE(FREE
    pFreeRes1Class->lpszMenuName  = (LPSTR)NULL;
    pFreeRes1Class->lpszClassName = (LPSTR)szAppName;
    pFreeRes1Class->hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pFreeRes1Class->hInstance     = hInstance;
    pFreeRes1Class->style         = CS_HREDRAW | CS_VREDRAW;
    pFreeRes1Class->lpfnWndProc   = FreeRes1WndProc;

    if (!RegisterClass( (LPWNDCLASS)pFreeRes1Class ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pFreeRes1Class );
    return TRUE;        /* Initialization succeeded */
}
/* End FreeRes1Init */
/* --------------------------------------------------------------------- */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance) {
        /* Call initialization procedure if this is the first instance */
        if (!FreeRes1Init( hInstance ))
            return FALSE;
        }
    else {
        /* Copy data from previous instance */
        GetInstanceData( hPrevInstance, (PSTR)szAppName, 10 );
        }
    hWnd = CreateWindow((LPSTR)szAppName,
                        (LPSTR)"FreeResource",
                        WS_OVERLAPPEDWINDOW | WS_MAXIMIZE,
                        10,              /*  x - ignored for tiled windows */
                        10,              /*  y - ignored for tiled windows */
                        CW_USEDEFAULT,   /* cx - ignored for tiled windows */
                        CW_USEDEFAULT,   /* cy - ignored for tiled windows */
                        (HWND)NULL,      /* no parent */
                        (HMENU)NULL,     /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Save instance handle for DialogBox */
    hInst = hInstance;

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}
/* End WinMain */
/* --------------------------------------------------------------------- */

/* Procedures which make up the window class. */
long FAR PASCAL FreeRes1WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        FreeRes1Paint(hWnd, ps.hdc );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}

/* End FreeRes1WndProc */
/* --------------------------------------------------------------------- */


GARF.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GARF.C

/*
 *
 *  GetAspectRatioFilter
 *
 *  This program demonstrates the use of the function GetAspectRatioFilter.
 *  This function retrieves the setting for the current aspect-ratio filter.
 *
 */

#include "windows.h"
#include <stdio.h>

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

static char  szAppName [] = "GARF";
static char  szFuncName [] = "GetAspectRatioFilter";

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance;
HANDLE    hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  WNDCLASS  rClass;
  HWND      hWnd;
  MSG       msg;

  if (!hPrevInstance)
    {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = (LPSTR)NULL;
    rClass.lpszClassName = szAppName;

    if (!RegisterClass (&rClass))
      return FALSE;
    }

hWnd = CreateWindow (szAppName,          /* window class name       */
                    szFuncName,          /* window caption          */
                    WS_OVERLAPPEDWINDOW, /* window style            */
                    CW_USEDEFAULT,       /* initial x position      */
                    0,                   /* initial y position      */
                    CW_USEDEFAULT,       /* initial x size          */
                    0,                   /* initial y size          */
                    NULL,                /* parent window handle    */
                    NULL,                /* window menu handle      */
                    hInstance,           /* program instance handle */
                    NULL);               /* create parameters       */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HDC   hDC;
  HMENU hMenu;
  DWORD dwAspectRatio;
  char  szBuffer[80];

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"Aspect Ratio", 1000, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_COMMAND:
      if (wParam == 1000)
        {
        hDC = GetDC (hWnd);
        SetMapperFlags (hDC, (DWORD)0);
        dwAspectRatio = GetAspectRatioFilter (hDC);
        sprintf (szBuffer, "%s%hu%s%hu\0",
            "Aspect ratio of filter zero is: x = ", HIWORD (dwAspectRatio),
            " y = ", LOWORD (dwAspectRatio));
        MessageBox (GetFocus (), (LPSTR)szBuffer, (LPSTR)szFuncName, MB_OK);

        SetMapperFlags (hDC, (DWORD)1);
        dwAspectRatio = GetAspectRatioFilter (hDC);
        sprintf (szBuffer, "%s%hu%s%hu\0",
            "Aspect ratio of filter one is: x = ", HIWORD (dwAspectRatio),
            " y = ", LOWORD (dwAspectRatio));
        MessageBox (GetFocus (), (LPSTR)szBuffer, (LPSTR)szFuncName, MB_OK);

        ReleaseDC (hWnd, hDC);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


GBITDIM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GBITDIM.C

/*
 *
 *  GetBitmapDimension
 *  gbitdim.c
 *
 *  This program demonstrates the use of the function GetBitmapDimension.
 *  This funtion returns the width and height of the bitmap specified by
 *  the parameter.
 *
 */

#include "windows.h"
#include <stdio.h>

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
  {
  HBITMAP hBitmap;          /* Handle to the loaded bitmap.   */
  DWORD   dwOldDimensions;  /* Old dimensions of the bitmap.  */
  DWORD   dwDimensions;     /* New dimensions of the bitmap.  */
  char    szOutBuf[50];     /* Output buffer for Message Box. */

       /* Load in the bitmap to examine. */
  hBitmap = LoadBitmap (hInstance, "SCOTTIE");
  if (hBitmap == NULL)
    {
    MessageBox (GetFocus (), (LPSTR)"Cannot Find Bitmap SCOTTIE",
               (LPSTR)"LoadBitmap () Error!", MB_OK | MB_ICONEXCLAMATION);
    return 1;
    }

       /* Set the new dimensions of the bitmap and show the old ones. */
  dwOldDimensions = SetBitmapDimension (hBitmap, (short)15, (short)15);
  sprintf (szOutBuf, "The old dimensions were %hu * %hu",
          LOWORD (dwOldDimensions), HIWORD (dwOldDimensions));
  MessageBox (GetFocus (), (LPSTR)szOutBuf,
             (LPSTR)"SetBitmapDimension ()", MB_OK);

       /* Get the new dimensions. */
  MessageBox (GetFocus (), (LPSTR)"Getting new dimensions.",
             "GetBitmapDimension ()", MB_OK);
  dwDimensions = GetBitmapDimension (hBitmap);

       /* And display them (or an error). */
  sprintf (szOutBuf, "New dimensions are %hu * %hu",
          LOWORD (dwDimensions), HIWORD (dwDimensions));
  if (dwDimensions)
    MessageBox (GetFocus (), (LPSTR)szOutBuf,
               (LPSTR)"GetBitmapDimension ()", MB_OK);
  else
    MessageBox (GetFocus (), (LPSTR)"Function failed",
               (LPSTR)"GetBitmapDimension () Error!",
               MB_OK | MB_ICONEXCLAMATION);

  if (!DeleteObject (hBitmap))
    {
    MessageBox (GetFocus (), (LPSTR)"Bitmap Resources Not Deleted!",
               (LPSTR)"DeleteObject () Error!",
               MB_OK | MB_ICONEXCLAMATION);
    return 1;
    }

  return 0;
  }


GBMB.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GBMB.C

/*
 *
 *  GetBitmapBits
 *  gbmb.c
 *
 *  This program demonstrates the use of the function GetBitmapBits.
 *  This funtion copies the bits of the specified bitmap into the buffer
 *  that is pointed to by the last parameter.  The middle parameter
 *  specifies the number of bytes to be copied to the buffer.
 *
 *  Other references: cffile.c
 *
 */

#include "windows.h"

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  long dwCount;
  HBITMAP hBitmap;
  PBITMAP pBitmap;
  int nBraemar[500];

  hBitmap = LoadBitmap(hInstance, "SCOTTIE");
  pBitmap = (PBITMAP)LocalAlloc(LMEM_MOVEABLE, sizeof(BITMAP));
  dwCount = GetObject(hBitmap, (long)sizeof(BITMAP), (LPSTR) pBitmap);

  MessageBox(NULL, "Get bitmap", "GetBitmapBits", MB_OK);

  if (GetBitmapBits(hBitmap, dwCount, (LPSTR) nBraemar))
     MessageBox(NULL, "Bitmap copied", "GetBitmapBits", MB_OK);
  else
     MessageBox(NULL, "Bitmap did not copy", "GetBitmapBits", MB_OK);


  return 0;
}


GBRUORG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GBRUORG.C

/*
 *
 *  GetBrushOrg
 *  gbruorg.c
 *
 *  This program demonstrates the use of the function GetBrushOrg.
 *  This function retrieves the current brush origin for the given
 *  device context.
 *
 */

#include "windows.h"

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  DWORD ptOrigin;
  HDC hDC;
  PAINTSTRUCT ps;
  char szbuff[80];

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) "gbruorg";
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) NULL;
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }

  hWnd = CreateWindow ("gbruorg", "GetBrushOrg",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
          NULL, NULL,
          hInstance, NULL );

  ShowWindow(hWnd, cmdShow);
  BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
  hDC=ps.hdc;

  MessageBox(NULL, "Getting brush origin", "GetBrushOrg", MB_OK);
  ptOrigin=GetBrushOrg(hDC);
  sprintf(szbuff, "%s%d%s%d\0", "Brush origin is: x= ", HIWORD(ptOrigin),
      " y= ", LOWORD(ptOrigin));

  MessageBox (NULL, szbuff, "GetBrushOrg", MB_OK);
  return 0;
}


GCEM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\GCEM.C

/*
 *
 *  GetCommEventMask
 *
 *  This program demonstrates the use of the function GetCommEventMask.
 *  This function retrieves the value of the current event mask, and then
 *  clears the mask.
 *
 */

#include <windows.h>

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  int nCid;         /* Comm Port ID.     */
  WORD wEvent;      /* Event mask value. */

  /* Open COM1. */
  nCid = OpenComm((LPSTR)"COM1", 50, 50);
  if (nCid < 0)
    {
    MessageBox(GetFocus(), (LPSTR)"OpenComm Failed", (LPSTR)"OpenComm()",
               MB_OK | MB_ICONEXCLAMATION);
    return 1;
    }

  /* Set the event mask to allow for detection of input break events. */
  SetCommEventMask(nCid, EV_BREAK);

  /* Get the event mask and check to see if a break was detected. This
     would normally be put in a WM_TIMER message for use over time in
     a communications setting. */
  MessageBox(GetFocus(), (LPSTR)"Requesting Communications Event Mask",
             (LPSTR)"GetCommEventMask()", MB_OK);
  wEvent = GetCommEventMask(nCid, EV_BREAK);
  if ((wEvent & EV_BREAK) != 0)
     MessageBox(GetFocus(),
                (LPSTR)"A Break Event was Detected.",
                (LPSTR)"GetCommEventMask()",
                MB_OK);
  else
     MessageBox(GetFocus(),
                (LPSTR)"A Break Event has Not Arrived.",
                (LPSTR)"GetCommEventMask()",
                MB_OK);

  /* Cleanup. */
  CloseComm(nCid);
  return 0;
}


GCURPOS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CURSOR\GCURPOS.C

/*
 *  GetCursorPos
 *
 *  This program demonstrates the use of the function GetCursorPos.
 *  GetCursorPos retrieves the cursor position in screen coordinates.
 *  This means that even if the cursor is not in the current window,
 *  it's position will be retrieved. GetCursorPos is called from
 *  WinMain () in this application.
 *
 */

#include "windows.h"
#include <stdio.h>

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);
extern int      FAR PASCAL lstrlen (LPSTR);

static char  szAppName [] = "GCURPOS";
static char  szFuncName [] = "GetCursorPos";

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  HWND      hWnd;
  WNDCLASS  wndclass;
  MSG       msg;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hWnd = CreateWindow (szAppName,
                      szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      0,
                      CW_USEDEFAULT,
                      0,
                      NULL,
                      NULL,
                      hInstance,
                      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

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


long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned  iMessage;
WORD     wParam;
LONG     lParam;
  {
  HDC   hDC;
  HMENU hMenu;
  POINT CursorPos;
  char  szBuffer[30];

  switch (iMessage)
    {
    case WM_CREATE:
      hMenu = CreateMenu ();
      ChangeMenu (hMenu, NULL, (LPSTR)"Curse Tracking", 100, MF_APPEND);
      SetMenu (hWnd, hMenu);
      break;

    case WM_INITMENU:
      InvalidateRect (hWnd, NULL, TRUE);
      break;

    case WM_COMMAND:
      if (wParam == 100)
        {
        hDC = GetDC (hWnd);
        GetCursorPos ( (LPPOINT) & CursorPos);
        sprintf (szBuffer, "Cursor Position: x = %d y = %d", CursorPos.x,
            CursorPos.y);
        TextOut (hDC, 10, 10,  (LPSTR)szBuffer, lstrlen ( (LPSTR)szBuffer));
        ReleaseDC (hWnd, hDC);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


GDBLCLKT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MOUSE\GDBLCLKT.C

/*
 * GetDoubleClickTime
 * This function returns the Double Click Time of the mouse.
 *
 */

#include "windows.h"
#include <stdio.h>

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    nCmdShow;
  {
  WORD wTime;        /* The current double click time for the mouse. */
  char szOutBuf[80]; /* Output buffer for message box.               */

      /* Get and display the current double click time for the mouse. */
  wTime = GetDoubleClickTime ();
  sprintf (szOutBuf, "%s%hu", "Double click time in milliseconds is: ", wTime
  MessageBox (GetFocus (), (LPSTR)szOutBuf, "GetDoubleClickTime ()", MB_OK);

  return 0;
  }


GDLGITM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\GDLGITM.C

/*
 *   GetDlgItem
 *
 *   This program demonstrates the use of the GetDlgItem function.
 *
 */

#include <windows.h>
#include <stdio.h>
#include "gdlgitm.h"

long FAR PASCAL DlgItmWndProc(HWND, unsigned, WORD, LONG);

HANDLE  hInst;        /* Instance handle for dialog box. */
FARPROC lpprocDialog; /* Pointer to dialog procedure.    */

BOOL FAR PASCAL DialogBoxProc(hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned message;
WORD     wParam;
LONG     lParam;
{
  switch (message)
    {
    case WM_INITDIALOG:
      SetFocus(GetDlgItem(hDlg, EDIT_CONTROL));
      return FALSE;

    case WM_COMMAND:
      if (wParam == ID_OK)
        {
        char szBuff[80]; /* Output buffer from the edit control. */
        HWND hCtl;       /* Handle to the edit control, Used by  */
                         /* GetDlgItem().                        */

        /* Get the handle to the edit control window. */
        MessageBox(GetFocus(),
                   (LPSTR)"Getting handle to control in dialog box",
                   (LPSTR)"GetDlgItem", MB_OK);
        hCtl = GetDlgItem(hDlg, EDIT_CONTROL);
        if (hCtl == NULL)
          MessageBox(GetFocus(), (LPSTR)"Error In Obatining Handle!",
                     (LPSTR)"GetDlgItem() Error!",
                     MB_OK | MB_ICONEXCLAMATION);
        else
          /* If the handle is good, get and show the edit control text. */
          SendMessage(hCtl, WM_GETTEXT, (WORD)80, (LONG)szBuff);
          MessageBox(GetFocus(), (LPSTR)szBuff,
                     (LPSTR)"Edit Box Contents using GetDlgItem()",
                     MB_OK);
        /* And Quit. */
        EndDialog(hDlg,TRUE);
        return TRUE;
        }
      else return FALSE;

    default:
      return FALSE;
   }
}

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  MSG       msg;          /* Window messages.           */
  HWND      hWnd;         /* Window handle.             */
  PWNDCLASS pDlgItmClass; /* Pointer to the class data. */

  pDlgItmClass = (PWNDCLASS)LocalAlloc(LPTR, sizeof(WNDCLASS));

  pDlgItmClass->hCursor       = LoadCursor(NULL, IDC_ARROW);
  pDlgItmClass->hIcon         = LoadIcon(hInstance, NULL);
  pDlgItmClass->lpszMenuName  = (LPSTR)"dlgmenu";
  pDlgItmClass->lpszClassName = (LPSTR)"gdlgitm";
  pDlgItmClass->hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  pDlgItmClass->hInstance     = hInstance;
  pDlgItmClass->style         = CS_HREDRAW | CS_VREDRAW;
  pDlgItmClass->lpfnWndProc   = DlgItmWndProc;

  if (!RegisterClass((LPWNDCLASS)pDlgItmClass))
    return FALSE;

  LocalFree((HANDLE)pDlgItmClass);

  hWnd = CreateWindow((LPSTR)"gdlgitm", (LPSTR)"GetDlgItem",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT,  CW_USEDEFAULT,
                      (HWND)NULL, (HMENU)NULL, (HANDLE)hInstance,
                      (LPSTR)NULL);
  hInst = hInstance;

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

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

  return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL DlgItmWndProc(hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
{
  switch (message)
    {
    case WM_COMMAND:
      switch (wParam)
        {
        case ID_DLGMENU:
          /* Show the demo dialog box. */
          lpprocDialog = MakeProcInstance((FARPROC)DialogBoxProc, hInst);
          DialogBox(hInst, MAKEINTRESOURCE(ITEMBOX), hWnd, lpprocDialog);
          FreeProcInstance((FARPROC)lpprocDialog);
          break;

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

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
      break;
    }
  return(0L);
}


GDLGITMI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\GDLGITMI.C

/*
 *   GetDlgItemInt
 *
 *   This program demonstrates the use of the GetDlgItemInt function.
 *
 */

#include "windows.h"
#include <stdio.h>
#include "gdlgitmi.h"

long FAR PASCAL ItemIWndProc(HWND, unsigned, WORD, LONG);

HANDLE  hInst;        /* Instance handle for dialog box.   */
FARPROC lpprocDialog; /* Long pointer to dialog procedure. */
char    szBuff[80];   /* Buffer for edit control text.     */

BOOL FAR PASCAL DialogBoxProc(hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned message;
WORD     wParam;
LONG     lParam;
{
  int  nNumber;      /* Integer from the edit control. */
  BOOL bTranslated;  /* Translated flag pointer.       */

  switch (message)
    {
    case WM_INITDIALOG:
      SetFocus(GetDlgItem(hDlg, EDIT_CONTROL));
      return FALSE;

    case WM_COMMAND:
      if (wParam == ID_OK)
        {
         /* Get the integer value of text entered. */
        nNumber = (int)GetDlgItemInt(hDlg, EDIT_CONTROL,
                                     (BOOL FAR *)&bTranslated,
                                     TRUE);
        if (bTranslated != FALSE)
          {  /* Display that value in a message box if valid. */
          sprintf(szBuff, "%s%d", "The number from the edit field: ", nNumber
          MessageBox(GetFocus(), (LPSTR)szBuff,
                     (LPSTR)"GetDlgItemInt()", MB_OK);
          }
        else /* Or display an error. */
          MessageBox(GetFocus(),
                     (LPSTR)"Non-numeric character or exceeded max!",
                     (LPSTR)"GetDlgItemInt() Error!",
                     MB_OK | MB_ICONEXCLAMATION);
        /* Quit the dialog box. */
        EndDialog(hDlg, TRUE);
        return TRUE;
        }
      else
        return FALSE;

    default:
      return FALSE;
    }
}

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  MSG         msg;         /* Messages.               */
  HWND        hWnd;        /* Window handle.          */
  PWNDCLASS   pItemIClass; /* Window class structure. */

  pItemIClass->hCursor        = LoadCursor(NULL, IDC_ARROW);
  pItemIClass->hIcon          = LoadIcon(hInstance,NULL);
  pItemIClass->lpszMenuName   = (LPSTR)"getintmenu";
  pItemIClass->lpszClassName  = (LPSTR)"gdlgitmi";
  pItemIClass->hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  pItemIClass->hInstance      = hInstance;
  pItemIClass->style          = CS_HREDRAW | CS_VREDRAW;
  pItemIClass->lpfnWndProc    = ItemIWndProc;

  if (!RegisterClass((LPWNDCLASS)pItemIClass))
    return FALSE;
  LocalFree((HANDLE)pItemIClass);

  hWnd = CreateWindow((LPSTR)"gdlgitmi", (LPSTR)"GetDlgItemInt",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT,  CW_USEDEFAULT,
                      (HWND)NULL, (HMENU)NULL, (HANDLE)hInstance,
                      (LPSTR)NULL);
  hInst = hInstance;

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

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

  return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL ItemIWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
  switch (message)
    {
    case WM_COMMAND:
      switch (wParam)
        {
        case ID_INTBOX:
          lpprocDialog = MakeProcInstance((FARPROC)DialogBoxProc, hInst);
          DialogBox(hInst, MAKEINTRESOURCE(INTBOX), hWnd, lpprocDialog);
          FreeProcInstance((FARPROC)lpprocDialog);
          break;

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

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
      break;
    }
  return(0L);
}



GDLGITMT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\GDLGITMT.C

/*
 *   GetDlgItemText
 *
 *   This program demonstrates the use of the GetDlgItemTxt function.
 *   GetDlgItem text retrieves the caption of or the text associated
 *   with a control in a dialog box. GetDlgItemTxt is called from
 *   DialogBoxProc in this application.
 *
 */

#include "windows.h"
#include "gdlgitmt.h"

long FAR PASCAL ItemTWndProc(HWND, unsigned, WORD, LONG);

HANDLE  hInst;        /* Instance handle.              */
FARPROC lpprocDialog; /* Dialog procedure pointer.     */

BOOL FAR PASCAL DialogBoxProc(hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned message;
WORD     wParam;
LONG     lParam;
{
  int  nNumChars;  /* Number of characters entered in the edit field. */
  char szBuff[80]; /* Buffer for edit control text.                   */

  switch (message)
    {
    case WM_INITDIALOG:
      SetFocus(GetDlgItem(hDlg, EDIT_CONTROL));
      return FALSE;

    case WM_COMMAND:
      if (wParam == ID_OK)
        {
        /* Get the text entered in the dialog box control. */
        nNumChars = GetDlgItemText(hDlg, EDIT_CONTROL,
                                   (LPSTR)szBuff, (int)80);
        if (nNumChars == 0) /* If no text, say it. */
          MessageBox(GetFocus(),
                     (LPSTR)"No characters entered in edit field",
                     (LPSTR)"GetDlgItemText()",
                     MB_OK);
        else /* Otherwise, show the text. */
          MessageBox(GetFocus(),(LPSTR)szBuff,
                     (LPSTR)"GetDlgItemText() Obtained:",
                     MB_OK);
        EndDialog(hDlg,TRUE);
        return TRUE;
        }
      else
        return FALSE;

    default:
      return FALSE;
    }
}

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  MSG       msg;         /* Message structure.      */
  HWND      hWnd;        /* Window handle.          */
  PWNDCLASS pItemTClass; /* Window class structure. */

  pItemTClass = (PWNDCLASS)LocalAlloc(LPTR, sizeof(WNDCLASS));

  pItemTClass->hCursor        = LoadCursor(NULL, IDC_ARROW);
  pItemTClass->hIcon          = LoadIcon(hInstance,NULL);
  pItemTClass->lpszMenuName   = (LPSTR)"textmenu";
  pItemTClass->lpszClassName  = (LPSTR)"gdlgitmt";
  pItemTClass->hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  pItemTClass->hInstance      = hInstance;
  pItemTClass->style          = CS_HREDRAW | CS_VREDRAW;
  pItemTClass->lpfnWndProc    = ItemTWndProc;

  if (!RegisterClass((LPWNDCLASS)pItemTClass))
    return FALSE;
  LocalFree((HANDLE)pItemTClass);

  hWnd = CreateWindow((LPSTR)"gdlgitmt",
                      (LPSTR)"GetDlgItemText",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      (HWND)NULL,
                      (HMENU)NULL,
                      (HANDLE)hInstance,
                      (LPSTR)NULL);
  hInst = hInstance;

  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

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

  return (int)msg.wParam;
}

long FAR PASCAL ItemTWndProc(hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
{
  switch (message)
    {
    case WM_COMMAND:
      switch (wParam)
        {
        case ID_TEXTBOX:
          lpprocDialog = MakeProcInstance((FARPROC)DialogBoxProc, hInst);
          DialogBox(hInst, MAKEINTRESOURCE(TEXTBOX), hWnd, lpprocDialog);
          FreeProcInstance((FARPROC)lpprocDialog);
          break;

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

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
      break;
    }
  return(0L);
}


GETACTW.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GETACTW.C

/*
 * GetActiveWindow
 *
 * This function obtains a handle to the active window.
 *
 */

#include <windows.h>
#include "getactw.h"

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    nCmdShow;
{
  HWND     hWnd;     /* Window handle.          */
  WNDCLASS wndclass; /* Window class structure. */
  MSG      msg;      /* Message structure.      */

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = ActiveWndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName  = (LPSTR)"getactw";
    wndclass.lpszClassName = (LPSTR)"getactw";

    if (!RegisterClass(&wndclass))
      return FALSE;
    }

  hWnd = CreateWindow ((LPSTR)"getactw",
                       (LPSTR)"GetActiveWindow",
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT, 0,
                       CW_USEDEFAULT, 0,
                       NULL, NULL,
                       hInstance, NULL);

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

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

long FAR PASCAL ActiveWndProc(hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
{
  HWND hWndActive; /* Handle to the active window. */

  switch(iMessage)
    {
     case WM_COMMAND:
       switch (wParam)
         {
         int i; /* Loop Counter. */
         case IDM_GETACTIVEW:
           /* Get the active window and flash that handle. */
           hWndActive = GetActiveWindow();
           for (i = 0; i < 5; i++)
             {
             FlashWindow(hWndActive, FALSE);
             MessageBeep(NULL);
             }
           break;

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

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    return DefWindowProc(hWnd, iMessage, wParam, lParam);
    break;
  }
  return (0L);
}



GETASYKS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\GETASYKS.C

/*
 * GetAsyncKeyState
 *
 * This function determines whether a key is up or down, and
 * whether the key was pressed after a previous call to the
 * GetAsyncKeyState function.
 *
 */

#include <windows.h>

long FAR PASCAL AsyncWndProc(HWND, unsigned, WORD, LONG);

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    nCmdShow;
{
  HWND     hWnd;
  WNDCLASS wndclass;
  MSG      msg;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = AsyncWndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = "getasyks";

    if (!RegisterClass(&wndclass))
         return FALSE;
    }

  hWnd = CreateWindow ((LPSTR)"getasyks",
                       (LPSTR)"GetAsyncKeyState()",
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT, 0,
                       CW_USEDEFAULT, 0,
                       NULL, NULL,
                       hInstance, NULL);

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

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

  return (msg.wParam);
}

long FAR PASCAL AsyncWndProc(hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
{
 switch(iMessage)
   {
   int Keydown;
   PAINTSTRUCT ps;
   HDC hDC;

   case WM_CHAR:
     Keydown = GetAsyncKeyState(VK_F12);
     if ((Keydown & 0x8000) == 0x8000)
       MessageBox(hWnd, (LPSTR)"'F12' is down.",
                  (LPSTR)"GetAsyncKeyState()", MB_OK);
     else if ((Keydown & 0x0001) == 0x0001)
       MessageBox(hWnd,
                  (LPSTR)"'F12' pressed since last GetAsyncState() call.",
                  (LPSTR)"GetAsyncKeyState()", MB_OK);
     else
       MessageBox(hWnd,
                  (LPSTR)"'F12' not pressed since last GetAsyncState() call."
                  (LPSTR)"GetAsyncKeyState()", MB_OK);
     break;

  case WM_PAINT:
     hDC = BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
     TextOut(hDC, (short)10, (short)10,
             (LPSTR)"Hit space bar while pressing/not pressing 'F12' to test"
             (short)55);
     EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
     break;

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    return DefWindowProc (hWnd, iMessage, wParam, lParam);
    break;
  }
  return (0L);
}



GETBITSM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GETBITSM.C

/*

Function(s) demonstrated in this program: GetStretchBltMode
Description:   This function retrieves the current stretching mode.  The
   stretching mode defines how information is to be added or removed from
   bitmaps that are stretched or compressed by using the StretchBlt function.

Additional Comments:  Possible modes are BLACKONWHITE, WHITEONBLACK,
   and COLORONCOLOR with values 1, 2, and 3 respectively.
*/


#include <windows.h>
#include "GetBitSM.h"
#include <string.h>
#include <stdio.h>

       char      szAppName[] = "GetBitSM";
       HANDLE      hInstMain;
       HWND      hWndMain;
       char      szOutputBuffer1[70];
       char      szOutputBuffer2[500];
       HBITMAP      hBitmapHelp;

struct { char *szMessage; }
       Messages [] = { "Help Message",
       "     Sample program to illustrate the use of GetStretchBltMode.\n\
       Choose the option to see the current stretch mode." };


void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
     {
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
     }

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
    HANDLE  hInstance, hPrevInstance;
    LPSTR  lpszCmdLine;
    int   nCmdShow;
    {
    HWND  hWnd;
    MSG   msg;
    WNDCLASS  wndclass;
    HBITMAP  hBitmapCirc, hBitmapDiam, hBitmapSqua, hBitmapXs, hBitmapTria,
    hBitmapPlus;
    HMENU  hMenu;
    short  xScreen, yScreen;

    if (!hPrevInstance)
  {
  wndclass.style    = CS_HREDRAW | CS_VREDRAW | CS_SAVEBITS;
  wndclass.lpfnWndProc    = WndProc;
  wndclass.cbClsExtra     = 0;
  wndclass.cbWndExtra     = 0;
  wndclass.hInstance      = hInstance;
  wndclass.hIcon    = NULL;
  wndclass.hCursor  = LoadCursor (NULL, IDC_ARROW) ;
  wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
  wndclass.lpszMenuName  = szAppName;
  wndclass.lpszClassName  = szAppName;

  if (!RegisterClass (&wndclass) )
      return FALSE;
  }

    xScreen = GetSystemMetrics (SM_CXSCREEN);
    yScreen = GetSystemMetrics (SM_CYSCREEN);

    hWnd = CreateWindow (szAppName, "Help Window",
     WS_OVERLAPPEDWINDOW, xScreen/7, yScreen/58,
     xScreen*3/4, yScreen*49/50, NULL, NULL, hInstance, NULL);

    hInstMain = hInstance;
    hWndMain  = hWnd;

    ShowWindow (hWnd, nCmdShow);
    UpdateWindow (hWnd);

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

    DeleteObject (hBitmapHelp);
    return msg.wParam;
    }
/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
   HWND      hWnd;
   unsigned  iMessage;
   WORD      wParam;
   LONG      lParam;
   {
   int           Index;
   HANDLE        hDC;
   HDC           hMemoryDC;
   BITMAP        Bitmap;
   short   foo;

   switch (iMessage)
       {
       case WM_SIZE:
      hDC = GetDC(hWnd);
            hMemoryDC = CreateCompatibleDC(hDC);
            hBitmapHelp = LoadBitmap (hInstMain, "BitmapHelp");
            GetObject(hBitmapHelp, 16, (LPSTR) &Bitmap);
            SelectObject(hMemoryDC, hBitmapHelp);
            foo = GetStretchBltMode (hDC);

            SetStretchBltMode(hDC, BLACKONWHITE);
            StretchBlt(hDC, 0, 0, LOWORD (lParam), HIWORD (lParam),
        hMemoryDC, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight, SRCCOPY);

            SetStretchBltMode(hDC, foo);
      DeleteObject (hBitmapHelp);
      DeleteDC(hMemoryDC);
      ReleaseDC(hWnd, hDC);
      break;

       case WM_COMMAND:
            switch (wParam) {
              case IDM_GETMODE:
                   hDC = GetDC(hWnd);
                   hMemoryDC = CreateCompatibleDC(hDC);
                   hBitmapHelp = LoadBitmap (hInstMain, "BitmapHelp");
                   GetObject(hBitmapHelp, 16, (LPSTR) &Bitmap);
                   SelectObject(hMemoryDC, hBitmapHelp);
                   foo = GetStretchBltMode (hDC);

                   sprintf (szOutputBuffer1, "Stretch Mode = %x, BLACKONWHITE
                            foo);
                   MessageBox (hWnd, szOutputBuffer1, "GetStretchBltMode",
                               MB_OK);

                   SetStretchBltMode(hDC, BLACKONWHITE);
                   StretchBlt(hDC, 0, 0, LOWORD (lParam), HIWORD (lParam),
                   hMemoryDC, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight, SRCCOPY)
                   SetStretchBltMode(hDC, foo);
                   DeleteObject (hBitmapHelp);
                   DeleteDC(hMemoryDC);
                   ReleaseDC(hWnd, hDC);
                   break;

              case IDM_HELP:
                   ProcessMessage (hWnd, 0);
                   break;
           }
            break;

       case WM_DESTROY:
            PostQuitMessage (0);
            break;

       default:
            return DefWindowProc( hWnd, iMessage, wParam, lParam );
       }
  return 0L;
}

/****************************************************************************



GETBKCLR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GETBKCLR.C

/*
 *
 *   This program demonstrates the use of the GetBkColor function. GetBkColor
 *   gets the double word value of the color that goes behind text, etc.
 *   in the given device.
 *
 */

#include <windows.h>
#include <stdio.h>

#define STR_PUR1  "The purpose of this program is too return the RGB value"
#define STR_PUR2  " that represents the background color. The value is"
#define STR_PUR3  " represented as (rrr, ggg, bbb)."

BOOL HelloInit (HANDLE);
int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);
long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

char  szVerbage[47] = "The Background color is behind these characters";

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit(hInstance)
HANDLE hInstance;
{
    WNDCLASS   rHelloClass;

    rHelloClass.hCursor        = LoadCursor(NULL,IDC_ARROW );
    rHelloClass.hIcon        = NULL;
    rHelloClass.lpszMenuName   = (LPSTR)NULL;
    rHelloClass.lpszClassName   = (LPSTR)"Sample Application";
    rHelloClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    rHelloClass.hInstance      = hInstance;
    rHelloClass.style          = CS_HREDRAW | CS_VREDRAW;
    rHelloClass.lpfnWndProc    = HelloWndProc;

    if (!RegisterClass((LPWNDCLASS)&rHelloClass))
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;
   char   szPurpose[255];                /* Message box buffers */
    char  szBuff[80];
    HDC   hDC;                          /*   display context   */
    DWORD dwBkColor;            /* return value from GetBkColr */

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"Sample Application",
                (LPSTR)"GetBkColor",
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    hDC = GetDC(hWnd);

   sprintf(szPurpose,"%s%s%s\0",STR_PUR1,STR_PUR2,STR_PUR3);

    MessageBox(hWnd,(LPSTR)szPurpose,(LPSTR)"GET BACKGROUNDCOLOR",MB_OK);

    TextOut(hDC,5,5,(LPSTR)szVerbage,(short)47);

    dwBkColor = GetBkColor(hDC);  /* Get the background color of the DC */

    sprintf(szBuff,
            "RGB value of the background color: (%hu, %hu, %hu)",
            GetRValue(dwBkColor), GetGValue(dwBkColor),
            GetBValue(dwBkColor));
    MessageBox(hWnd, (LPSTR)szBuff, (LPSTR)"GET BACKGROUND COLOR", MB_OK);

    SetBkColor(hDC,RGB(0x00,0x00,0x00)); /* change the background to black */
    SetTextColor(hDC,RGB(0xff,0xff,0xff));
    TextOut(hDC,5,25,(LPSTR)szVerbage,(short)47);

    dwBkColor = GetBkColor(hDC);  /* Get the background color of the DC */

    sprintf(szBuff,
            "RGB value of the background color: (%hu, %hu, %hu)",
            GetRValue(dwBkColor), GetGValue(dwBkColor),
            GetBValue(dwBkColor));
    MessageBox(hWnd, (LPSTR)szBuff, (LPSTR)"GET BACKGROUND COLOR", MB_OK);

    ReleaseDC(hWnd,hDC);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
  return DefWindowProc(hWnd,message,wParam,lParam);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_PAINT:
        BeginPaint(hWnd,(LPPAINTSTRUCT)&ps);
        EndPaint(hWnd,(LPPAINTSTRUCT)&ps);
        break;

    default:
        return DefWindowProc(hWnd,message,wParam,lParam );
        break;
    }
    return(0L);
}


GETBKMDE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GETBKMDE.C

/*
 *
 *   This program demonstrates the use of the GetBkMode function. GetBkMode
 *   retrieves the background mode of the given device. The background mode
 *   can be either OPAQUE or TRANSPARENT. The mode affects the background
 *   painting behind text, hatched brushes, and certain pens. GetBkMode is
 *   called from WinMain in this application.
 *
 */

#include "windows.h"

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;
    HDC   hDC;    /*   display context      */
    short nBkMode;  /*   return value from GetBkMode  */
    int   i;    /*   used in for loop      */

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"Sample Application",
      (LPSTR)"GetBkColor",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    hDC = GetDC(hWnd);

    for (i=0; i<=200; i+=5)
  {          /* draw line so we can see the affect */
   MoveTo(hDC,i,0);     /*      of the background mode      */
   LineTo(hDC,i,200);
  }

    TextOut(hDC,5,25,
      (LPSTR)"This line written with an OPAQUE Backgound mode",
      (short)47);

    nBkMode = GetBkMode(hDC);  /* Get the background mode of the DC */

    if (nBkMode == OPAQUE)
  MessageBox(hWnd,
       (LPSTR)"is OPAQUE",
       (LPSTR)"GetBkMode says the background mode...",
       MB_OK);
    else if(nBkMode == TRANSPARENT)
  MessageBox(hWnd,
       (LPSTR)"is TRANSPARENT",
       (LPSTR)"GetBkMode says the background mode...",
       MB_OK);
    else
  MessageBox(hWnd,
       (LPSTR)"ERROR",
       (LPSTR)"ERROR",
       MB_OK);


    SetBkMode(hDC,TRANSPARENT);  /* make background mode TRANSPARENT */


    TextOut(hDC,5,55,
      (LPSTR)"This line written with a TRANSPARENT Backgound mode",
      (short)51);

    nBkMode = GetBkMode(hDC);  /* Get the background mode of the DC */

    if (nBkMode == OPAQUE)
  MessageBox(hWnd,
       (LPSTR)"is OPAQUE",
       (LPSTR)"GetBkMode says the background mode...",
       MB_OK);
    else if(nBkMode == TRANSPARENT)
  MessageBox(hWnd,
       (LPSTR)"is TRANSPARENT",
       (LPSTR)"GetBkMode says the background mode...",
       MB_OK);
    else
  MessageBox(hWnd,
       (LPSTR)"ERROR",
       (LPSTR)"ERROR",
       MB_OK);

    ReleaseDC(hWnd,hDC);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
  return DefWindowProc( hWnd, message, wParam, lParam );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GETCAP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\GETCAP.C

/*
 *
 *  GetCapture
 *
 *  This program demonstrates the use of the function GetCapture.
 *  This function retrieves a handle that identifies the window that
 *  has the mouse capture.
 *
 */

#include "windows.h"

static HWND hWnd;
char szBuff [70];

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  HWND hWndPrev;
  HWND hWndGetCap;
  int  i;

  if (!hPrevInstance)
    {
    WNDCLASS rClass;

    rClass.lpszClassName = (LPSTR)"getcap";
    rClass.hInstance     = hInstance;
    rClass.lpfnWndProc   = DefWindowProc;
    rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon(hInstance, IDI_APPLICATION);
    rClass.lpszMenuName  = (LPSTR)NULL;
    rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;

    RegisterClass((LPWNDCLASS)&rClass);
    }

  hWnd = CreateWindow((LPSTR)"getcap", (LPSTR)"GetCapture",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      (HWND)NULL, (HMENU)NULL,
                      (HANDLE)hInstance, (LPSTR)NULL);

  ShowWindow(hWnd, cmdShow);

  MessageBox(GetFocus(), (LPSTR)"Getting window with mouse capture.",
             (LPSTR)"GetCapture()",
              MB_OK);
  SetCapture(hWnd);
  hWndGetCap = GetCapture();

  for (i = 0; i < 5; i++)
    {
    MessageBeep(NULL);
    FlashWindow(hWndGetCap, NULL);
    }

  MessageBox(GetFocus(), (LPSTR)"The capture window has been flashed.",
             (LPSTR)"GetCapture()",
             MB_OK);
  ReleaseCapture();
  return 0;
}


GETCAP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MOUSE\GETCAP.C

/*
 *
 *  GetCapture
 *
 *  This program demonstrates the use of the function GetCapture.
 *  This function retrieves a handle that identifies the window that
 *  has the mouse capture.
 *
 */

#include "windows.h"

static HWND hWnd;
char szBuff [70];

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  HWND hWndPrev;
  HWND hWndGetCap;
  int  i;

  if (!hPrevInstance)
    {
    WNDCLASS rClass;

    rClass.lpszClassName = (LPSTR)"getcap";
    rClass.hInstance     = hInstance;
    rClass.lpfnWndProc   = DefWindowProc;
    rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon(hInstance, IDI_APPLICATION);
    rClass.lpszMenuName  = (LPSTR)NULL;
    rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;

    RegisterClass((LPWNDCLASS)&rClass);
    }

  hWnd = CreateWindow((LPSTR)"getcap", (LPSTR)"GetCapture",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      (HWND)NULL, (HMENU)NULL,
                      (HANDLE)hInstance, (LPSTR)NULL);

  ShowWindow(hWnd, cmdShow);

  MessageBox(GetFocus(), (LPSTR)"Getting window with mouse capture.",
             (LPSTR)"GetCapture()",
              MB_OK);
  SetCapture(hWnd);
  hWndGetCap = GetCapture();

  for (i = 0; i < 5; i++)
    {
    MessageBeep(NULL);
    FlashWindow(hWndGetCap, NULL);
    }

  MessageBox(GetFocus(), (LPSTR)"The capture window has been flashed.",
             (LPSTR)"GetCapture()",
             MB_OK);
  ReleaseCapture();
  return 0;
}


GETCARBT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CARET\GETCARBT.C

/*
 *
 *  GetCaretBlinkTime
 *
 *  This program demonstrates the use of the function GetCaretBlinkTime.
 *  GetCaretBlinkTime returns the delay in milliseconds between each blink
 *  of the caret. So a big Blink Time means a slow blink speed. GetCaret-
 *  BlinkTime is called from WinMain in this application.
 *
 */

#include <stdio.h>
#include <windows.h>

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon     = LoadIcon (hInstance, (LPSTR)NULL);
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setcarbt";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND   hWnd;     /*    Handle to the parent window  */
    WORD   wBlinkDelay;   /* return value from GetCaretBlinkTime */
    char   szBuff[30];   /*    buffer for message box  */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setcarbt",
      (LPSTR)"GetCaretBlinkTime",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* create a caret before showing it */
    CreateCaret (hWnd, NULL, 8, 12);
    SetCaretPos (50,50);
    ShowCaret (hWnd);

/* get the delay in milliseconds of the caret blink speed */
    wBlinkDelay = (WORD)GetCaretBlinkTime();

    sprintf(szBuff,"%d milliseconds",wBlinkDelay);

    MessageBox(hWnd,(LPSTR)szBuff,
        (LPSTR)"The blink delay is",
        MB_OK);

    MessageBox(hWnd,(LPSTR)"speed the blink up",
        (LPSTR)"I am going to...",
        MB_OK);

    SetCaretBlinkTime (GetCaretBlinkTime()/5);   /* cut the delay down */

/* get the delay in milliseconds of the caret blink speed */
    wBlinkDelay = (WORD)GetCaretBlinkTime();

    sprintf(szBuff,"%d milliseconds",wBlinkDelay);

    MessageBox(hWnd,(LPSTR)szBuff,
        (LPSTR)"The blink delay is",
        MB_OK);

    return 0;
}


GETCERRO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\GETCERRO.C

/*
 *
 *  GetCommError
 *
 *  This program demonstrates the use of the function GetCommError.
 *  This function fills the status buffer pointed to by the last parameter
 *  with the current status of the communication device specified by the
 *  first parameter.  It also returns the error code that have occurred
 *  since the last GetCommError call.
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  int nCid;
  short nError;

  nCid = OpenComm ( (LPSTR)"COM1", 50, 50);
  if ( nCid < 0 )
     {
     MessageBox (NULL, (LPSTR)"OpenComm Failed", (LPSTR)"OpenComm",
        MB_OK|MB_ICONEXCLAMATION);
     exit (1);
     }
  WriteComm ( nCid, (LPSTR)"This is a test!!!", 25 );

  MessageBox (NULL, (LPSTR)"Clearing communication port", (LPSTR)"GetCommErro
     MB_OK);

  nError = GetCommError ( nCid, NULL );

  if ( nError == CE_BREAK )
     MessageBox (NULL, (LPSTR)"Hardware detected a brake condition",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_CTSTO )
     MessageBox (NULL, (LPSTR)"Clear-to-send timeout",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_DNS )
     MessageBox (NULL, (LPSTR)"Parallel device is not selected",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_DSRTO )
     MessageBox (NULL, (LPSTR)"Data-set-ready timeout",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_FRAME )
     MessageBox (NULL, (LPSTR)"Hardware detects a framing error",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_IOE )
     MessageBox (NULL, (LPSTR)"I/O error while communicate with parallel devi
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_MODE )
     MessageBox (NULL, (LPSTR)"Requested mode is not supported",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_OOP )
     MessageBox (NULL, (LPSTR)"Parallel device signals its out of paper",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_OVERRUN )
     MessageBox (NULL, (LPSTR)"A character has been overrun and lost",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_PTO )
     MessageBox (NULL, (LPSTR)"Timeout while communicating with parallel devi
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_RLSDTO )
     MessageBox (NULL, (LPSTR)"Recieve-line-signal-detect timeout",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_RXOVER )
     MessageBox (NULL, (LPSTR)"Receive queue overflow",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_RXPARITY )
     MessageBox (NULL, (LPSTR)"Hardware detected a parity error",
        (LPSTR)"GetCommError", MB_OK);
  else
  if ( nError == CE_TXFULL )
     MessageBox (NULL, (LPSTR)"Transmit gueue is full while trying \n to queu
        (LPSTR)"GetCommError", MB_OK);
  else
     MessageBox (NULL, (LPSTR)"No ERROR",
        (LPSTR)"GetCommError", MB_OK|MB_ICONEXCLAMATION);

  CloseComm ( nCid );
  return 0;
}


GETCHAND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\GETCHAND.C

/*
 *
 *  GetCodeHandle
 *
 *  This program demonstrates the use of the function GetCodeHandle.
 *  This function determines which code segment contains the funtion
 *  pointed to by the parameter.
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>
char szBuffer [70];

void FAR PASCAL GetMe ()
{
   int nTest = 0;

   nTest++;
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  HANDLE hCode;

  MessageBox (NULL, (LPSTR)"Finding code segment of GetMe function",
     (LPSTR)"GetCodeHandle", MB_OK);

  hCode = GetCodeHandle ( (FARPROC) GetMe );
  sprintf (szBuffer, "The handle to GetMe's code segment is %x", hCode);
  MessageBox (NULL, (LPSTR)szBuffer, (LPSTR)"GetCodeHandle",
              MB_OK);
  return 0;

}



GETCLIPF.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIPBORD\GETCLIPF.C

/*

Function(s) demonstrated in this program: GetClipboardFormatName

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function returns the name of the registered format
   requested.

Additional Comments:

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "GetClipF.h"


HWND     hWndParent1;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About",
"     This is a sample application to demonstrate the\n\
use of the GetClipboardFormatName Windows function.",

"Help Message",
"     This program uses the GetClipboardFormatName\n\
Windows function to retrieve the name of a format\n\
which was registered just prior to this function call\n\
under the name of TMSROMAN.  This name is then\n\
displayed in a Message Box.  Use the menu to invoke\n\
this function.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GetClipF" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "GetClipboardFormatName",   /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 HDC         hDC;
 PAINTSTRUCT ps;
 static int  xClient, yClient;
 WORD        wFormat;
 int         nCopied;
 char        lpFormatName [40];

 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_GETCLIPFNAME:
               MessageBox (NULL, (LPSTR)"Getting clipboard format name",
                  (LPSTR)"GetClipboardFormatName", MB_OK);

               wFormat = RegisterClipboardFormat ( (LPSTR)"TMSROMAN" );
               nCopied = GetClipboardFormatName ( wFormat, lpFormatName, 20 )

               if ( nCopied != 0 )
                   MessageBox (NULL, (LPSTR)lpFormatName,
                              (LPSTR)"The Format Name Is", MB_OK);
               else
                   MessageBox (NULL, (LPSTR)"Format does not exits",
                              (LPSTR)"GetClipboardFormatName", MB_OK);

               break;

          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}





GETCLONG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLASS\GETCLONG.C

/*

Function(s) demonstrated in this program: GetClassLong

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function retrieves the given LONG value from the
   respective class structure.

Additional Comments:

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "GetCLong.h"


HWND     hWndParent1;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use of the GetClassLong Windows function.",

"Help Message",
"     This program uses the GetClassLong Windows\n\
function to get a pointer to the menu name of the\n\
current window.  Use the menu to invoke this\n\
function.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GetCLong" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "GetClassLong",             /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 LONG        lpMenu;
 HMENU       hMenu;
 HDC         hDC;
 PAINTSTRUCT ps;
 static int  xClient, yClient;
 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_GETCLASSLONG:
               lpMenu = GetClassLong (hWnd, GCL_MENUNAME);
               sprintf (szOutputBuffer1,
                        "The pointer to the menu name is %x", lpMenu);
               MessageBox (hWnd, szOutputBuffer1, "GetClassLong", MB_OK);
               break;

          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}





GETCNAME.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLASS\GETCNAME.C

/*
 *
 *   GetClassName.c
 *
 *   This program demonstrates the use of the GetClassName function.
 *   Given a handle to a window, GetClassName retrieves the class name of
 *   that window. GetClassName is called from WinMain in this application.
 *
 */

#include "windows.h"

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;
    char  szClassName[30];  /* buffer to receive Class Name of hWnd */
    int   nSizeBuff;    /*   return value from GetClassName  */

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"Sample Application",
      (LPSTR)"GetClassName",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );


/*** get the class name of the window associated with hWnd ***/
    nSizeBuff = GetClassName(hWnd,(LPSTR)szClassName,30);


    if (nSizeBuff == 0)
   {
   MessageBox(hWnd,(LPSTR)"is not valid ",
        (LPSTR)"The specified window handle",
        MB_OK);
   return 1;
   }

     MessageBox(hWnd,(LPSTR)szClassName,
    (LPSTR)"The class name is:",
    MB_OK);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
  return DefWindowProc( hWnd, message, wParam, lParam );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GETCRECT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GETCRECT.C

#include "windows.h"

int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);
BOOL GetCRectInit(HANDLE);
long FAR PASCAL GetCRectWndProc(HWND, unsigned, WORD, LONG);

HANDLE hInst;

/**************************************************************************/

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;           /* current instance             */
HANDLE hPrevInstance;       /* previous instance            */
LPSTR lpCmdLine;            /* command line                 */
int nCmdShow;               /* show-window type (open/icon) */
{
    HWND hWnd;              /* window handle                */
    MSG msg;                /* message                      */


    if (!hPrevInstance)     /* Has application been initialized? */
        if (!GetCRectInit(hInstance))
            return (NULL);  /* Exits if unable to initialize     */

    hInst = hInstance;      /* Saves the current instance        */

    hWnd = CreateWindow("GetCRect",     /* window class            */
        "GetCRect Sample Application",  /* window name             */
        WS_OVERLAPPEDWINDOW,           /* window style            */
        CW_USEDEFAULT,                 /* x position              */
        CW_USEDEFAULT,                 /* y position              */
        CW_USEDEFAULT,                 /* width                   */
        CW_USEDEFAULT,                 /* height                  */
        NULL,                          /* parent handle           */
        NULL,                          /* menu or child ID        */
        hInstance,                     /* instance                */
        NULL);                         /* additional info         */

    if (!hWnd)                         /* Was the window created? */
        return (NULL);

    ShowWindow(hWnd, nCmdShow);        /* Shows the window        */
    UpdateWindow(hWnd);                /* Sends WM_PAINT message  */

    while (GetMessage(&msg,     /* message structure                      */
            NULL,               /* handle of window receiving the message */
            NULL,               /* lowest message to examine              */
            NULL))              /* highest message to examine             */
        {
        TranslateMessage(&msg); /* Translates virtual key codes           */
        DispatchMessage(&msg);  /* Dispatches message to window           */
    }
    return (msg.wParam);        /* Returns the value from PostQuitMessage */
}


/*************************************************************************/

BOOL GetCRectInit(hInstance)
HANDLE hInstance;                 /* current instance           */
{
    HANDLE hMemory;               /* handle to allocated memory */
    PWNDCLASS pWndClass;          /* structure pointer          */
    BOOL bSuccess;                /* RegisterClass() result     */

    hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
    pWndClass = (PWNDCLASS) LocalLock(hMemory);

    pWndClass->style = NULL;
    pWndClass->lpfnWndProc = GetCRectWndProc;
    pWndClass->hInstance = hInstance;
    pWndClass->hIcon = NULL;
    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
    pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
    pWndClass->lpszMenuName = (LPSTR) "GetCRectMenu";
    pWndClass->lpszClassName = (LPSTR) "GetCRect";

    bSuccess = RegisterClass(pWndClass);

    LocalUnlock(hMemory);                           /* Unlocks the memory
    LocalFree(hMemory);                             /* Returns it to Windows

    return (bSuccess);           /* Returns result of registering the window
}

/**************************************************************************/

long FAR PASCAL GetCRectWndProc(hWnd, message, wParam, lParam)
HWND hWnd;                      /* window handle                   */
unsigned message;               /* type of message                 */
WORD wParam;                    /* additional information          */
LONG lParam;                    /* additional information          */
{
    FARPROC lpProcAbout;        /* pointer to the "About" function */
    HMENU hMenu;                /* handle to the System menu       */
    RECT  rRect;                /* Will hold client rectangle  */
    HANDLE hDC;                 /* Handle to the display context  */
    PAINTSTRUCT ps;             /* Paint Structure  */

    switch (message) {
        case WM_SIZE:
        case WM_PAINT:
            GetClientRect( hWnd,           /*  Window handle  */
                         (LPRECT)&rRect ); /*  Structure holding  */
            InvalidateRect( hWnd, (LPRECT)&rRect, TRUE );
                               /*  Erase the background  */
            hDC = BeginPaint ( hWnd, &ps );   /*  Get the display context  */
/*  We are going to draw an X through the window  */
            MoveTo( hDC, rRect.left, rRect.top );
            LineTo( hDC, rRect.right, rRect.bottom );
            MoveTo( hDC, rRect.right, rRect.top );
            LineTo( hDC, rRect.left, rRect.bottom );
            EndPaint( hWnd, &ps );
            break;

        case WM_DESTROY:                  /* message: window being destroyed
            PostQuitMessage(0);
            break;

        default:                          /* Passes it on if unproccessed
            return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (NULL);
}




GETCSTAT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\GETCSTAT.C

/*
 *
 *  GetCommState
 *
 *  This program demonstrates the use of the function GetCommState.
 *  This function fills the buffer pointed to by the last parameter with the
 *  device control block of the communication device specified by the first
 *  parameter.
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  int nCid;
  WORD lpResult;
  DCB CommDCB;

  nCid = OpenComm ( (LPSTR)"COM1", 50, 50);
  if ( nCid < 0 )
     {
     MessageBox (NULL, (LPSTR)"OpenComm Failed", (LPSTR)"OpenComm",
        MB_OK|MB_ICONEXCLAMATION);
     exit (1);
     }

  CommDCB.BaudRate = 9600;
  CommDCB.ByteSize = 8;
  CommDCB.StopBits = ONESTOPBIT;
  CommDCB.TxDelay = 10;
  CommDCB.Parity = NOPARITY;
  CommDCB.PeChar = 0;
  CommDCB.RlsTimeout = 1000;
  CommDCB.CtsTimeout = 1000;
  CommDCB.DsrTimeout = 1000;
  CommDCB.XonChar = 2;
  CommDCB.XoffChar = 3;
  CommDCB.XonLim = 1000;
  CommDCB.XoffLim = 1000;
  CommDCB.EofChar = 4;
  CommDCB.EvtChar = 5;

  SetCommState( (DCB FAR *)&CommDCB );

  MessageBox (NULL, (LPSTR)"Requesting communication port state",
     (LPSTR)"GetCommState", MB_OK);

  lpResult = GetCommState ( nCid, (DCB FAR *)&CommDCB );

  if ( lpResult == 0 )
     MessageBox (NULL, (LPSTR)"Communication port state received",
                (LPSTR)"GetCommState", MB_OK);
  else
     MessageBox (NULL, (LPSTR)"Error when getting state",
        (LPSTR)"GetCommState", MB_OK);

  CloseComm ( nCid );

  return 0;
}


GETCTASK.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GETCTASK.C

/*
 *  GetCurrentTask
 *
 *  This program will get the handle to the current task and send it a
 *  message to kill itself.
 *
 */

 "windows.h"      /* required for all Windows applications */
#include "getctask.h"

HANDLE hInst;             /* current instance                      */

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;         /* current instance             */
HANDLE hPrevInstance;     /* previous instance            */
LPSTR lpCmdLine;          /* command line                 */
int nCmdShow;             /* show-window type (open/icon) */
{
    HWND hWnd;            /* window handle       */
    MSG msg;              /* message             */
    HANDLE hMenu;         /* Handle to the menu  */

    if (!hPrevInstance)              /* Has application been initialized? */
        if (!GetCTaskInit(hInstance))
            return (NULL);           /* Exits if unable to initialize     */

    hInst = hInstance;               /* Saves the current instance        */

    hMenu = LoadMenu( hInst, (LPSTR)"GetCTaskMenu" );
                                     /*  Load the menu    */

    hWnd = CreateWindow("GetCTask",   /* window class      */
        "GetCurrentTask Sample Application",  /* window name       */
        WS_OVERLAPPEDWINDOW,         /* window style      */
        CW_USEDEFAULT,               /* x position        */
        CW_USEDEFAULT,               /* y position        */
        CW_USEDEFAULT,               /* width             */
        CW_USEDEFAULT,               /* height            */
        NULL,                        /* parent handle     */
        hMenu,                       /* menu or child ID  */
        hInstance,                   /* instance          */
        NULL);                       /* additional info   */

    if (!hWnd)                       /* Was the window created? */
        return (NULL);

    ShowWindow(hWnd, nCmdShow);      /* Shows the window        */
    UpdateWindow(hWnd);              /* Sends WM_PAINT message  */

    while (GetMessage(&msg,     /* message structure                      */
            NULL,               /* handle of window receiving the message */
            NULL,               /* lowest message to examine              */
            NULL))              /* highest message to examine             */
        {
        TranslateMessage(&msg);  /* Translates virtual key codes           */
        DispatchMessage(&msg);   /* Dispatches message to window           */
    }
    return (msg.wParam);         /* Returns the value from PostQuitMessage */
}

BOOL GetCTaskInit(hInstance)
HANDLE hInstance;                /* current instance           */
{
    HANDLE hMemory;              /* handle to allocated memory */
    PWNDCLASS pWndClass;         /* structure pointer          */
    BOOL bSuccess;               /* RegisterClass() result     */

    hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
    pWndClass = (PWNDCLASS) LocalLock(hMemory);

    pWndClass->style = NULL;
    pWndClass->lpfnWndProc = GetCTaskWndProc;
    pWndClass->hInstance = hInstance;
    pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION);
    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
    pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
    pWndClass->lpszMenuName = (LPSTR) "GetCTaskMenu";
    pWndClass->lpszClassName = (LPSTR) "GetCTask";

    bSuccess = RegisterClass(pWndClass);

    LocalUnlock(hMemory);     /* Unlocks the memory    */
    LocalFree(hMemory);       /* Returns it to Windows */

    return (bSuccess);        /* Returns result of registering the window */
}

long FAR PASCAL GetCTaskWndProc(hWnd, message, wParam, lParam)
HWND hWnd;                    /* window handle                   */
unsigned message;             /* type of message                 */
WORD wParam;                  /* additional information          */
LONG lParam;                  /* additional information          */
{
    FARPROC lpProcAbout;      /* pointer to the "About" function */
    HMENU hMenu;              /* handle to the System menu       */

    switch (message) {

        case WM_COMMAND:
            if ( wParam == IDM_TRASH )
              {
              PostAppMessage( GetCurrentTask( ),  /*  Get current task  */
                              WM_QUIT,      /*  Message to quit  */
                              NULL,         /*  wParam  */
                              (LONG)NULL);  /*  lParam  */
              }
            break;

/*  PostMessage places the message into the applications message queue and
 *  does not wait for a response.  This is different from the SendMessage
 *  function in that SendMessage does wait.  The Window Procedure is called
 *  immediately when SendMessage is used.  For more information see
 *  PostMessage and SendMessage in the Programmer's Reference.
 */
        case WM_DESTROY:             /* message: window being destroyed */
            PostQuitMessage(0);
            break;

        default:                     /* Passes it on if unproccessed    */
            return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (NULL);
}


GETCTIME.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TIME\GETCTIME.C

/*
 *
 *  GetCurrentTime
 *
 *  This program demonstrates the use of the function GetCurrentTime.
 *  This function retrieves the current Window time.
 *
 *
 */

#include <windows.h>

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  DWORD dwCurTime;
  char szbuff[80];

  MessageBox (NULL, (LPSTR)"Getting current time", (LPSTR)"GetCurrentTime",
     MB_OK);

  dwCurTime = GetCurrentTime ();

  sprintf ( szbuff, "The current time in milliseconds is %ld",
     dwCurTime );
  MessageBox (NULL, (LPSTR) szbuff, (LPSTR)"GetCurrentTime", MB_OK);

  return FALSE;
}


GETCWIDT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\FONTS\GETCWIDT.C

/*
 *
 *  GetCharWidth
 *
 *  This program demonstrates the use of the function GetCharWidth.
 *  This function retrieves the widths of individual characters in a
 *  consecutive group of characters from the current font.  The funtion
 *  stores the values in the buffer pointed to by the last parameter.
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  HDC hDC;
  PAINTSTRUCT ps;
  BOOL bCharWidth;
  WORD wFirstChar = 97;
  WORD wLastChar = 122;
  char szbuff[80];
  int  lpBuffer[26];
  int  CharWidthSum, CharWidth, Index;

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) "getcwidt";
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) NULL;
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }

  hWnd = CreateWindow ( ( LPSTR ) "getcwidt", ( LPSTR ) "GetCharWidth",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      ( HWND ) NULL, ( HMENU ) NULL,
                      ( HANDLE ) hInstance, ( LPSTR ) NULL );

  ShowWindow ( hWnd , cmdShow );
  BeginPaint ( hWnd, ( LPPAINTSTRUCT ) &ps );
  hDC = ps.hdc;

  MessageBox (NULL, (LPSTR)"Getting charater string width",
     (LPSTR)"GetCharWidth", MB_OK);

  bCharWidth = GetCharWidth ( hDC, wFirstChar, wLastChar,(LPINT) lpBuffer );
  for (Index = 0, CharWidthSum = 0; Index < 26; Index++) {
    CharWidthSum += lpBuffer [Index];
  }
  CharWidth = CharWidthSum / 26;
  sprintf (szbuff, "The average character width is %i", CharWidth);
  MessageBox (hWnd, szbuff, "GetCharWidth", MB_OK);

  return 0;
}


GETCWORD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLASS\GETCWORD.C

/*
 *
 *  GetClassWord
 *
 *  This program demonstrates the use of the function GetClassWord.
 *  This function retrieves the word that is specified by the last para-
 *  meter form the WNDCLASS stucture of the window specified by the
 *  first parameter.
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  WORD wClassWord;
  char szbuff[80];

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) "getcword";
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) NULL;
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }

  hWnd = CreateWindow ( ( LPSTR ) "getcword", ( LPSTR ) "GetClassWord",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      ( HWND ) NULL, ( HMENU ) NULL,
                      ( HANDLE ) hInstance, ( LPSTR ) NULL );

  ShowWindow ( hWnd , cmdShow );

  MessageBox (NULL, (LPSTR)"Getting windows style bits",
     (LPSTR)"GetClassWord", MB_OK);

  wClassWord = GetClassWord ( hWnd, GCW_STYLE );

  sprintf ( szbuff, "%s%d\0", "Style bits are ", wClassWord );

  MessageBox (NULL, (LPSTR) szbuff, (LPSTR)"GetClassWord", MB_OK);

  return 0;
}


GETDCAPS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DEVICE\GETDCAPS.C

/*
 *
 *  GetDeviceCaps
 *
 *  This program demonstrates the use of the function GetDeviceCaps.
 *  This function retrieves device-specific information about a given
 *  display device.  The last parameter specifies the type os information
 *  desired.
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  HDC hDC;
  short nValue;
  char szbuff[80];

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) "getdcaps";
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) NULL;
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }

  hWnd = CreateWindow ( ( LPSTR ) "getdcaps", ( LPSTR ) "GetDeviceCaps",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      ( HWND ) NULL, ( HMENU ) NULL,
                      ( HANDLE ) hInstance, ( LPSTR ) NULL );

  ShowWindow ( hWnd , cmdShow );
  hDC = GetDC ( hWnd );

  MessageBox (NULL, (LPSTR)"Getting driver version number",
             (LPSTR)"GetDeviceCaps", MB_OK);

  nValue = GetDeviceCaps ( hDC, DRIVERVERSION );

  sprintf ( szbuff, "%s%d\0", "Driver version number is ",
     nValue );
  MessageBox (NULL, (LPSTR) szbuff, (LPSTR)"GetDeviceCaps", MB_OK);

  ReleaseDC ( hWnd, hDC );

  return 0;
}


GETDCORG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DEVICE\GETDCORG.C

/*
 *  GetDCOrg
 *
 *  This program demonstrates the use of the function GetDCOrg.
 *  This function obtians the final translation origin for the device
 *  context.
 *
 *  Microsoft Product Support Services
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  HDC hDC;
  LONG ptOrigin;
  char szbuff[80];

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) "getdcorg";
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) NULL;
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }

  hWnd = CreateWindow ( ( LPSTR ) "getdcorg", ( LPSTR ) "GetDCOrg",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      ( HWND ) NULL, ( HMENU ) NULL,
                      ( HANDLE ) hInstance, ( LPSTR ) NULL );

  ShowWindow ( hWnd , cmdShow );
  hDC = GetDC ( hWnd );

  MessageBox (NULL, (LPSTR)"Getting origin", (LPSTR)"GetDCOrg", MB_OK);

  ptOrigin = GetDCOrg ( hDC );

  sprintf ( szbuff, "The origin of this window is at (%d,%d)",
     LOWORD(ptOrigin), HIWORD(ptOrigin) );
  MessageBox (NULL, (LPSTR) szbuff, (LPSTR)"GetDCOrg", MB_OK);

  ReleaseDC ( hWnd, hDC );

  return 0;
}


GETDCPOS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DISPLAY\GETDCPOS.C

/*

Function(s) demonstrated in this program: GetCurrentPosition

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function returns the current position of the Display
   Context.

Additional Comments:

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "GetDCPos.h"


HWND     hWndParent1, hWndParent2, hWndChild1, hWndChild2;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use of the GetCurrentPosition Windows function.",

"Help Message",
"     This program uses the GetCurrentPosition Windows\n\
function return the current position of the Display\n\
context, this position is then displayed in a Message\n\
Box.  The position has been moved to (x,y) = (100,100)\n\
so this should be displayed when option is chosen\n\
from the menu.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GetDCPos" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "GetCurrentPosition",       /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 HDC         hDC;
 PAINTSTRUCT ps;
 static int  xClient, yClient;
 DWORD       dWord;
 char        szOutputBuffer [40];

 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_GETPOSITION:
               hDC = GetDC ( hWnd );
               MoveTo ( hDC, 100, 100 );
               dWord = GetCurrentPosition (hDC);
               sprintf (szOutputBuffer1,
                      "The Current Display Context Position = (%i,%i)",
                        LOWORD (dWord), HIWORD (dWord));
               MessageBox (hWnd, szOutputBuffer1, "GetCurrentPostion", MB_OK)
               ReleaseDC(hWnd, hDC);
               break;

          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}



GETENV.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\GETENV.C

/*
 *
 *  GetEnvironment
 *  getenv.c
 *
 *  This program demonstrates the use of the function GetEnvironment.
 *  This function retrieves the currewnt environment that is associated with
 *  the device attached to the system port specified by the first parameter,
 *  and copies it into the buffer specified by the second parameter.
 *
 */

#include <windows.h>
#include "getenv.h"

LPSTR far PASCAL lstrcpy( LPSTR, LPSTR );

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  short nCopied;
  short nSCopied;
  DEVMODE devmode;

  lstrcpy(devmode.DeviceName, "HP LaserJet Series II");
  devmode.orient = PORTRAIT;
  devmode.cartridge = DEFAULT_CTG + CARTRIDGE;
  devmode.paper = LETTER;

  nSCopied = SetEnvironment("LPT1:", (LPSTR)&devmode, sizeof(DEVMODE));
  if (!nSCopied)
     {
     MessageBox (NULL, "Environment not set!", "SetEnvironment",
        MB_OK|MB_ICONEXCLAMATION);
     return (1);
     }

  /* Clear out name string to show that we can retrieve it */
  lstrcpy(devmode.DeviceName, "xxxxxxxxxxxxxx");

  MessageBox(NULL, "Getting environment", "GetEnvironment", MB_OK);
  nCopied=GetEnvironment("LPT1:", (LPSTR)&devmode, sizeof(DEVMODE));

  if (nCopied)
     MessageBox(NULL, devmode.DeviceName, "DeviceName", MB_OK);
  else
     MessageBox(NULL, "Environment not found", "GetEnvironment", MB_OK);

  return 0;
}


GETHDC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DISPLAY\GETHDC.C

/*

Function(s) demonstrated in this program: GetDC
Windows version:  2.03
Windows SDK version:  2.00
Compiler version:  C 5.10
Description:  This function returns a handle to the display context.

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "GethDC.h"


HWND     hWndParent1, hWndParent2, hWndChild1, hWndChild2;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use of the GetDC Windows function.",

"Help Message",
"     This program uses the GetDC Windows function\n\
to get a handle to the current display context this\n\
handle is then displayed in a message box.  Use\n\
the menu to invoke this function.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GethDC" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "GetDC",                    /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 HDC         hDC;
 PAINTSTRUCT ps;
 static int  xClient, yClient;
 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_GETHDC:
               hDC = GetDC (hWnd);
               sprintf (szOutputBuffer1,
                        "The Handle to the display context is %x", hDC);
               MessageBox (hWnd, szOutputBuffer1, "GetDC", MB_OK);
               ReleaseDC(hWnd, hDC);
               break;

          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}





GETLEN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TEXT\GETLEN.C

/*
 *   GetWindowTextLength
 *
 *   This program demonstrates the use of the GetWindowTextLength function.
 *   The GetWindowTextLength function returns the length of the text in the
 *   given window's caption bar. If the return value is 0, then there is
 *   no text in the caption bar.
 *
 */

#include "windows.h"
#include <stdio.h>

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;
    int x;         /* return value from GetWindowTextLength  */
    char buffer[40];       /* buffer for outputing text    */

  HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"Sample Application",
      (LPSTR)"Sample Application",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

      /* get caption bar text length */
      x=GetWindowTextLength(hWnd);
      /* if there is a caption */
      if (x>0)
         {
         /* copy length to buffer */
         sprintf(buffer,"length of text in caption bar = %d",x);
         /* output the caption  */
         MessageBox(hWnd,(LPSTR)buffer,
        (LPSTR)"CAPTION BAR INFO",MB_OK);
         }
      else
      /* output "There is no Title Bar */
    MessageBox(hWnd,(LPSTR)NULL,
        (LPSTR)"There is no Title Bar",MB_OK);


    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
  {
   default:
            return DefWindowProc( hWnd, message, wParam, lParam );
      break;
  }
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GETMAPM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MAP\GETMAPM.C

/*
 *
 *  GetMapMode
 *
 *  This program demonstrates the use of the function GetMapMode.
 *  This function retrieves the cuurent mapping mode.
 *
 */

#include <windows.h>

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  HDC hDC;
  static char szFileName[] = "getmapm";
  static char szFuncName[] = "GetMapMode";
  short nMapMode;

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) szFileName;
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) NULL;
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }

  hWnd = CreateWindow ( ( LPSTR ) szFileName, ( LPSTR ) szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      ( HWND ) NULL, ( HMENU ) NULL,
                      ( HANDLE ) hInstance, ( LPSTR ) NULL );

  ShowWindow ( hWnd , cmdShow );
  hDC = GetDC ( hWnd );
  SetMapMode ( hDC, MM_TEXT);

  MessageBox (NULL, (LPSTR)"Getting mapping mode", (LPSTR)szFuncName, MB_OK);

  nMapMode = GetMapMode ( hDC );

  if ( nMapMode == MM_ANISOTROPIC )
     MessageBox (NULL, (LPSTR)"Mapping mode is anisotropic" ,
        (LPSTR)szFuncName, MB_OK);
  else
     if ( nMapMode == MM_HIENGLISH )
        MessageBox (NULL, (LPSTR)"Mapping mode is high english" ,
           (LPSTR)szFuncName, MB_OK);
     else
        if ( nMapMode == MM_HIMETRIC )
           MessageBox (NULL, (LPSTR)"Mapping mode is high metric" ,
              (LPSTR)szFuncName, MB_OK);
        else
           if ( nMapMode == MM_ISOTROPIC )
              MessageBox (NULL, (LPSTR)"Mapping mode is isotropic" ,
                 (LPSTR)szFuncName, MB_OK);
           else
              if ( nMapMode == MM_LOMETRIC )
                 MessageBox (NULL, (LPSTR)"Mapping mode is low metric" ,
                    (LPSTR)szFuncName, MB_OK);
              else
                 if ( nMapMode == MM_LOENGLISH )
                    MessageBox (NULL, (LPSTR)"Mapping mode is low english" ,
                       (LPSTR)szFuncName, MB_OK);
                 else
                    if ( nMapMode == MM_TEXT )
                       MessageBox (NULL, (LPSTR)"Mapping mode is text" ,
                          (LPSTR)szFuncName, MB_OK);
                    else
                       if ( nMapMode == MM_TWIPS )
                          MessageBox (NULL, (LPSTR)"Mapping mode is twips" ,
                             (LPSTR)szFuncName, MB_OK);
                       else
                          MessageBox (NULL, (LPSTR)"Error no mapping mode" ,
                             (LPSTR)szFuncName, MB_OK|MB_ICONEXCLAMATION);

  ReleaseDC ( hWnd, hDC );

  return 0;
}


GETMENU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\GETMENU.C

/*
 *
 *  GetMenu
 *
 *  This program demonstrates the use of the function GetMenu.
 *  This function retrieves a handle to the menu of the specified window.
 *
 */

#include <windows.h>
#include "getmenu.h"

long FAR PASCAL GMWndProc (HWND, unsigned int, WORD, LONG);

static HANDLE hWnd;

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  static char szFileName[] = "getmenu";
  static char szFuncName[] = "GetMenu";
  MSG   msg;
  HMENU hMenu;

  if (!hPrevInstance)
     {
     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)szFileName;
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon         = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)"GetMenuFunc";
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);
     }

  hWnd = CreateWindow((LPSTR)szFileName, (LPSTR)szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      (HWND)NULL, (HMENU)NULL,
                      (HANDLE)hInstance, (LPSTR)NULL);

   ShowWindow(hWnd, cmdShow);
   UpdateWindow(hWnd);

   MessageBox(GetFocus(), (LPSTR)"Getting Menu Handle",
              (LPSTR)"GetMenu()", MB_OK);
   hMenu = GetMenu(hWnd);
   if (hMenu == NULL)
      MessageBox(GetFocus(), (LPSTR)"Error In Getting Menu Handle",
                 (LPSTR)"GetMenu()", MB_OK);
   else
      MessageBox(GetFocus(), (LPSTR)"Menu Handle Obtained Successfully",
                 (LPSTR)"GetMenu()", MB_OK);
   EnableMenuItem(hMenu, ENTRY_1, MF_BYCOMMAND | MF_GRAYED);
   DrawMenuBar(hWnd);
   MessageBox(GetFocus(), (LPSTR)"'Item_1' Grayed",
              (LPSTR)"GetMenu()", MB_OK);

  return 0;
}



GETMOD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MODULE\GETMOD.C

/*

Function(s) demonstrated in this program: GetModuleFileName, GetModuleHandle,
  GetModuleUsage

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function returns the reference count of the module.

Additional Comments:

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "GetMod.h"


HWND     hWndParent1;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use of the GetModuleFileName, GetModuleHandle, and\n\
GetModuleUsage Windows functions.",

"Help Message",
"     This program uses the GetModuleUsage Windows\n\
function to get the reference count of the current\n\
module.  To test this function, first start several\n\
instances of this program.  Then use the menu to\n\
invoke the function.  The count displayed should\n\
directly represent the number of instances you have\n\
started.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GetMod" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "GetModuleUsage",           /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 int         nUsage;
 HMENU       hMenu;
 HDC         hDC;
 PAINTSTRUCT ps;
 HANDLE      hModule;

 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_GETMODF:
               GetModuleFileName(GetModuleHandle((LPSTR)"GetMod"),
                                 szOutputBuffer1, 70);
               MessageBox (hWnd, szOutputBuffer1, "GetModuleFileName", MB_OK)
               break;

          case IDM_GETMODH:
               hModule = GetModuleHandle ("GetMod");
               sprintf (szOutputBuffer1, "Module handle = %x", hModule);
               MessageBox (hWnd, szOutputBuffer1, "GetModuleHandle", MB_OK);
               break;

          case IDM_GETMODU:
               nUsage = GetModuleUsage (hInstMain);
               sprintf (szOutputBuffer1,
                        "The module usage of the current module = %i",nUsage)
               MessageBox (hWnd, szOutputBuffer1, "GetModuleUsage", MB_OK);
               break;


          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}





GETMSG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\GETMSG.C

/*
 *
 *  GetMessage
 *
 *  This program demonstrates the use of the GetMessage function.  The
 *   program registers and creates a window.  Then, it goes into the
 *   GetMessage loop.  On the screen is the instruction to double click
 *   the right mouse button.  This conducts the test of GetMessage by
 *   displaying a message box from within the WM_RBOTTONDBLCLK section
 *   of the window procedure .
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"getmsg";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon          = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);

     /* Permit the window class to accept double click messages by
        using the CS_DBLCLKS style.                                */

     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "getmsg",
           (LPSTR) "GetMessage",
           WS_OVERLAPPEDWINDOW,          /* Use an overlapping window. */
           CW_USEDEFAULT,                /* Use default coordinates.   */
           CW_USEDEFAULT,                /* Use default coordinates.   */
           CW_USEDEFAULT,                /* Use default coordinates.   */
           CW_USEDEFAULT,                /* Use default coordinates.   */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

   /* Go into the GetMessage loop at this time.  The user can then
      double click on the right mouse button when the cursor is in
      the client area of this application.                         */

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{
   switch (identifier) {

     case WM_PAINT: {
        RECT      rRect;
        PAINTSTRUCT ps;
        HDC      hDC;

        hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);

         /* Display the instructions in the client area for the
            user to conduct the test.                            */

       DrawText(hDC,
                  (LPSTR)"Double Click Right Mouse Button to Conduct Test.",
                  48,
                  (LPRECT)&rRect,
                  DT_SINGLELINE);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);

    }
    break;

     /* Check to see if the user has double clicked the right
        mouse button.                                          */

    case WM_RBUTTONDBLCLK:        /* If so, display a success message box. */
      MessageBox(hWnd,
                 (LPSTR)"GetMessage Retrieved a WM_RBUTTONDBLCLK Message",
                 (LPSTR)"GetMessage",
                 MB_OK);
      break;                    /* And return for more message processing. */

    case WM_CLOSE:
     DestroyWindow(hWnd);
     break;

    case WM_DESTROY:
     PostQuitMessage(0);
     break;

    default:
     return(DefWindowProc(hWnd, identifier, wParam, lParam));
     break;

   }

   return(0L);

}


GETOBJ.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\OBJECT\GETOBJ.C

/*
 *
 *  GetObject
 *  getobj.c
 *
 *  This program demonstrates the use of the function GetObject.
 *  This funtion fills a buffer with the logical data the defines the
 *  logical object specified by the first parameter.
 *
 *  Other references: cfclip.c, cfnew.c
 *
 */

#include "windows.h"

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  long    dwCopied;
  long    dwCount;
  HBITMAP hBitmap;
  BITMAP  bitmap;
  char    szJunk[50];

  hBitmap = LoadBitmap(hInstance, "SCOTTIE");

  MessageBox (NULL, "Getting object ", "GetObject", MB_OK);
  dwCount = GetObject(hBitmap, (long)sizeof(BITMAP), (LPSTR) &bitmap);

  if (dwCount)
     {
     sprintf(szJunk, "Bitmap Width=%d, Height=%d",
       bitmap.bmWidth, bitmap.bmHeight);
     MessageBox(NULL, szJunk, "GetObject Successful", MB_OK);
     }
  else
     MessageBox(NULL, "Object not gotten", "GetObject", MB_OK);

  return 0;
}


GETOBJ.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GETOBJ.C

/*
 *
 *  GetObject
 *  getobj.c
 *
 *  This program demonstrates the use of the function GetObject.
 *  This funtion fills a buffer with the logical data the defines the
 *  logical object specified by the first parameter.
 *
 *  Other references: cfclip.c, cfnew.c
 *
 */

#include "windows.h"

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  long    dwCopied;
  long    dwCount;
  HBITMAP hBitmap;
  BITMAP  bitmap;
  char    szJunk[50];

  hBitmap = LoadBitmap(hInstance, "SCOTTIE");

  MessageBox (NULL, "Getting object ", "GetObject", MB_OK);
  dwCount = GetObject(hBitmap, (long)sizeof(BITMAP), (LPSTR) &bitmap);

  if (dwCount)
     {
     sprintf(szJunk, "Bitmap Width=%d, Height=%d",
       bitmap.bmWidth, bitmap.bmHeight);
     MessageBox(NULL, szJunk, "GetObject Successful", MB_OK);
     }
  else
     MessageBox(NULL, "Object not gotten", "GetObject", MB_OK);

  return 0;
}


GETOPWND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GETOPWND.C

/*
 *
 *   This program demonstrates the use of the GetTopWindow() function.
 *   GetTopWindow() searches for the top level child window that belongs
 *   to the parent window specified by the "hWnd" parameter. GetTopWindow()
 *   is called twice in WinMain(). It is first called when no child windows
 *   exist, and then after two child windows have been created.
 *
 *   Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);
long FAR PASCAL ChildAProc(HWND, unsigned, WORD, LONG);
long FAR PASCAL ChildBProc(HWND, unsigned, WORD, LONG);

HWND hChildAWnd = NULL;
HWND hChildBWnd = NULL;

/* Procedure called when the application is loaded for the first time */

BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"GetTopWindow";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc  = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"CHILD A";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc  = ChildAProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"CHILD B";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc  = ChildBProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    HWND  hTopWindow;    /*** return value from GetTopWindow() ***/

    HelloInit( hInstance );

    hWnd = CreateWindow((LPSTR)"GetTopWindow",
      (LPSTR)"GetTopWindow()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    MessageBox(NULL,
         (LPSTR)"Will destroy window if handle returned.",
         (LPSTR)"First call to GetTopWindow().",
         MB_OK);

/*** get handle to top level child to "hWnd" (if one exists) ***/
    hTopWindow = GetTopWindow(hWnd);
    if (hTopWindow)
  DestroyWindow(hTopWindow);
    else
  MessageBox(NULL,
       (LPSTR)"No top level child window exists",
       (LPSTR)"GetTopWindow() info:",
       MB_OK);

    hChildAWnd = CreateWindow((LPSTR)"CHILD A",
      (LPSTR)"Child A",
      WS_CHILD | WS_SIZEBOX | WS_VISIBLE | WS_CAPTION |
      WS_CLIPSIBLINGS,
      5,
      5,
      250,
      250,
      (HWND)hWnd,
      (HMENU)1,     /* child: use constant */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    hChildBWnd = CreateWindow((LPSTR)"CHILD B",
      (LPSTR)"Child B",
      WS_CHILD | WS_SIZEBOX | WS_VISIBLE | WS_CAPTION |
      WS_CLIPSIBLINGS,
      5,
      5,
      150,
      150,
      (HWND)hChildAWnd,
      (HMENU)2,     /* child: use constant */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    MessageBox(NULL,
         (LPSTR)"Will destroy window if handle returned.",
         (LPSTR)"Second call to GetTopWindow().",
         MB_OK);

/*** get handle to top level child to "hWnd" (if one exists) ***/
    hTopWindow = GetTopWindow(hWnd);
    if (hTopWindow)
  DestroyWindow(hTopWindow);
    else
  MessageBox(NULL,
       (LPSTR)"No top level child window exists",
       (LPSTR)"GetTopWindow() info:",
       MB_OK);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}

long FAR PASCAL ChildAProc( hChildAWnd, message, wParam, lParam )
HWND hChildAWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
  BeginPaint( hChildAWnd, (LPPAINTSTRUCT)&ps );
  EndPaint( hChildAWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
  return DefWindowProc( hChildAWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}

long FAR PASCAL ChildBProc( hChildBWnd, message, wParam, lParam )
HWND hChildBWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
  BeginPaint( hChildBWnd, (LPPAINTSTRUCT)&ps );
  EndPaint( hChildBWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
  return DefWindowProc( hChildBWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GETPADDR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\GETPADDR.C

/*

Function(s) demonstrated in this program: GetProcAddress, LoadLibrary,
   FreeLibrary

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function returns a handle to the given library function.

Additional Comments:

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "GetPAddr.h"


HWND     hWndParent1;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use of the GetProcAddress, LoadLibrary, and FreeLibrary\n\
Windows functions.",

"Help Message",
"     This program uses the GetProcAddress Windows\n\
function to get a handle to the StartSelection\n\
function in the SELECT library.  This address is\n\
then displayed in a message box.  Use the menu to\n\
invoke this function.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GetPAddr" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "GetProcAddress",           /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 HDC         hDC;
 PAINTSTRUCT ps;
 static int  xClient, yClient;
 HANDLE      hLibModule;
 FARPROC     lpAddress;

 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_GETPROCADDRESS:
               hLibModule = LoadLibrary( "select" );

               MessageBox (NULL,
                 (LPSTR)"Retrieving address of the StartSelection function.",
                 (LPSTR)"GetProcAddress", MB_OK);

               lpAddress = GetProcAddress( hLibModule, "StartSelection" );

               if ( lpAddress != NULL ) {
                  sprintf (szOutputBuffer1,
                           "The Address of StartSelection is %x",
                           lpAddress);
                  MessageBox (NULL, szOutputBuffer1, "GetProcAddress", MB_OK)
               }
               else
                  MessageBox (NULL,
                              "Error detected while searching for address.",
                              "GetProcAddress", MB_OK);

               FreeLibrary ( hLibModule );

               break;

          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}





GETPARNT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SPAWN\GETPARNT.C

/*
 *
 *   This program demonstrates use of the GetParent() function.
 *   GetParent() returns the parent (if one exists) of the given window.
 *   GetParent() is called three times in WinMain() in this application.
 *
 *   Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);
long FAR PASCAL ChildAProc(HWND, unsigned, WORD, LONG);
long FAR PASCAL ChildBProc(HWND, unsigned, WORD, LONG);

HWND hChildAWnd = NULL;     /*  handle to child window       */
HWND hChildBWnd = NULL;     /*  handle to grandchild window  */
HWND hMainWnd = NULL;       /*   handle to main window        */

/* Procedure called when the application is loaded for the first time */

BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"GetParent";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc  = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"CHILD A";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc  = ChildAProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"CHILD B";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc  = ChildBProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    HWND  hParent;  /* return value from GetParent() */

    HelloInit( hInstance );

    hMainWnd = CreateWindow((LPSTR)"GetParent",
      (LPSTR)"GetParent() [hMainWnd]",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hMainWnd, cmdShow );
    UpdateWindow( hMainWnd );

    hChildAWnd = CreateWindow((LPSTR)"CHILD A",
      (LPSTR)"Child A [hChildAWnd]",
      WS_CHILD | WS_SIZEBOX | WS_VISIBLE | WS_CAPTION |
      WS_CLIPSIBLINGS,
      5,
      5,
      400,
      300,
      (HWND)hMainWnd,
      (HMENU)1,     /* child: use constant */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    hChildBWnd = CreateWindow((LPSTR)"CHILD B",
      (LPSTR)"Child B [hChildBWnd]",
      WS_CHILD | WS_SIZEBOX | WS_VISIBLE | WS_CAPTION |
      WS_CLIPSIBLINGS,
      5,
      5,
      300,
      250,
      (HWND)hChildAWnd,
      (HMENU)2,     /* child: use constant */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

/*
 *     hWnd is the parent of hChildAWnd and hChildAWnd is the parent of
 *     hChildBWnd. The following calls to GetParent() should confirm this
 */

hParent = GetParent(hMainWnd);
if (!hParent)
    MessageBox(NULL,
         (LPSTR)"because hMainWnd has no parent",
         (LPSTR)"GetParent(hMainWnd) returned NULL, which is correct...",
         MB_OK);
else
    MessageBox(NULL,
         (LPSTR)"which is an ERROR",
         (LPSTR)"GetParent(hWnd) did not return NULL...",
         MB_OK);

hParent = GetParent(hChildAWnd);
if (hParent == hMainWnd)
    MessageBox(NULL,
         (LPSTR)"because hMainWnd is hChildAWnd's parent",
         (LPSTR)"GetParent(hChildAWnd) returned hMainWnd, which is correct...
         MB_OK);
else
    MessageBox(NULL,
         (LPSTR)"which is an ERROR",
         (LPSTR)"GetParent(hChildAWnd) did not return hMainWnd,",
         MB_OK);

hParent = GetParent(hChildBWnd);
if (hParent == hChildAWnd)
    MessageBox(NULL,
         (LPSTR)"because hChildAWnd is hChildBWnd's parent",
         (LPSTR)"GetParent(hChildBWnd) returned hChildAWnd, which is correct.
         MB_OK);
else
    MessageBox(NULL,
         (LPSTR)"which is an ERROR",
         (LPSTR)"GetParent(hChildBWnd) did not return hChildAWnd",
         MB_OK);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
  return DefWindowProc( hWnd, message, wParam, lParam );
  break;

    case WM_LBUTTONDOWN:
  MessageBox(hChildBWnd,(LPSTR)"Left Button Click",
            (LPSTR)"PARENT WINDOW",
            MB_OK);
  break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}

long FAR PASCAL ChildAProc( hChildAWnd, message, wParam, lParam )
HWND hChildAWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_LBUTTONDOWN:
  MessageBox(hChildBWnd,(LPSTR)"Left Button Click",
            (LPSTR)"CHILD A",
            MB_OK);
  break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
  BeginPaint( hChildAWnd, (LPPAINTSTRUCT)&ps );
  EndPaint( hChildAWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
  return DefWindowProc( hChildAWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}

long FAR PASCAL ChildBProc( hChildBWnd, message, wParam, lParam )
HWND hChildBWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_LBUTTONDOWN:
  MessageBox(hChildBWnd,(LPSTR)"Left Button Click",
            (LPSTR)"CHILD B",
            MB_OK);
  break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
  BeginPaint( hChildBWnd, (LPPAINTSTRUCT)&ps );
  EndPaint( hChildBWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
  return DefWindowProc( hChildBWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GETPIXEL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GETPIXEL.C

/*

Function(s) demonstrated in this program: ChildWindowFromPoint

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function retrieves the RGB color value of the pixel at
   the point specified by the X and Y parameters.  If the point is not in
   the clipping region, the function is ignored.

Additional Comments:  This program also illustrates the subclassing of
    windows.

*/

#define NOMINMAX
#include <stdlib.h>
#include <windows.h>
#include "GetPixel.h"
#include "string.h"
#include "stdio.h"

       char         szAppName             [] = "GetPixel"          ;
       HANDLE       hInstMain                                      ;
       HWND         hWndMain                                       ;
       char         szOutputBuffer1       [70]                     ;
       char         szOutputBuffer2       [500]                    ;
       HBITMAP      hBitmapHelp                                    ;

       HWND         hWndChild1, hWndChild2, hX, hY, hOK2;
       FARPROC      lpProcEnterPoint;
       FARPROC      lpProcNewEnterPoint;
       FARPROC      lpProcOldX;
       FARPROC      lpProcOldY;
       char         szXValue [40];
       char         szYValue [40];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About",
"     Sample Application to demonstrate the use of\n\
the GetPixel Windows function.",

"Help Message",
"     Select a pixel, and the program will use the\n\
GetPixel Windows function to display the attributes\n\
of that pixel; ffff = White, 0 = Black.  Select a\n\
pixel by clicking the left mouse button, entering\n\
the pixel coordinates through the keyboard, or let\n\
the computer choose random pixel coordinates."
};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
    HANDLE  hInstance, hPrevInstance;
    LPSTR  lpszCmdLine;
    int   nCmdShow;
    {
    HWND  hWnd;
    MSG   msg;
    WNDCLASS  wndclass;
    HMENU  hMenu;
    short   xScreen, yScreen;


    if (!hPrevInstance)
  {
  wndclass.style           = CS_HREDRAW | CS_VREDRAW | CS_SAVEBITS;
  wndclass.lpfnWndProc    = WndProc;
  wndclass.cbClsExtra     = 0;
  wndclass.cbWndExtra     = 0;
  wndclass.hInstance      = hInstance;
  wndclass.hIcon           = NULL;
   wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
  wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
  wndclass.lpszMenuName  = szAppName;
  wndclass.lpszClassName  = szAppName;

    if (!RegisterClass (&wndclass) )
        return FALSE;
    }

   xScreen = GetSystemMetrics (SM_CXSCREEN);
    yScreen = GetSystemMetrics (SM_CYSCREEN);

    hWnd = CreateWindow (szAppName, "GetPixel",
           WS_OVERLAPPEDWINDOW, xScreen / 7, yScreen / 58,
           xScreen * 3 / 4, yScreen * 49 / 50, NULL, NULL,
           hInstance, NULL);

    hInstMain = hInstance;
    hWndMain  = hWnd;

    ShowWindow (hWnd, nCmdShow);
    UpdateWindow (hWnd);

    lpProcEnterPoint    = MakeProcInstance (EnterPointDlgProc, hInstance);
    lpProcNewEnterPoint = MakeProcInstance (NewEnterPointDlgProc,hInstance);


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

    DeleteObject (hBitmapHelp);

    return msg.wParam;
}
/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
   HWND      hWnd;
   unsigned  iMessage;
   WORD      wParam;
   LONG      lParam;
   {
   int           Index;
   HANDLE        hDC;
   HDC           hMemoryDC;
   BITMAP        Bitmap;
  short         foo;

   HMENU         hMenu;
   PAINTSTRUCT   ps;
   POINT         pt;
   static int    xClient, yClient;
   static int    xDevisor, yDevisor, randNum;
   DWORD         Attribute;


   switch (iMessage)
       {
       case WM_CREATE:
            hMenu = GetSystemMenu (hWnd, FALSE);

            ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                        MF_APPEND | MF_STRING);
            break;

       case WM_SIZE:
            xClient = LOWORD (lParam);
            yClient = HIWORD (lParam);

            hDC = GetDC(hWnd);

            hMemoryDC = CreateCompatibleDC(hDC);
            hBitmapHelp = LoadBitmap (hInstMain, "BitmapHelp");
            GetObject(hBitmapHelp, 16, (LPSTR) &Bitmap);
            SelectObject(hMemoryDC, hBitmapHelp);
            foo = GetStretchBltMode (hDC);

            SetStretchBltMode(hDC, BLACKONWHITE);
            StretchBlt(hDC, 0, 0, LOWORD (lParam), HIWORD (lParam),
        hMemoryDC, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight, SRCCOPY);

            SetStretchBltMode(hDC, foo);
            DeleteObject (hBitmapHelp);
        DeleteDC(hMemoryDC);
            ReleaseDC(hWnd, hDC);

            break;

       case WM_LBUTTONDOWN:
            pt = MAKEPOINT (lParam) ;
            hDC = GetDC (hWnd);
            Attribute = GetPixel (hDC, pt.x, pt.y);
            sprintf (szOutputBuffer1, "The Point [%i, %i]", pt.x, pt.y);
            sprintf (szOutputBuffer2, "Has Attribute %x", Attribute);
            MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1,MB_OK);
            ReleaseDC(hWnd, hDC);
            break;


       case WM_SYSCOMMAND:
            switch (wParam) {
               case IDM_ABOUT:
                    ProcessMessage (hWnd, 0);
                    break;
               default:
                    return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
            }
            break;


       case WM_COMMAND:
            switch (wParam) {
               case IDM_RANDOM:
                    pt.x = pt.y = -1;
                    while (((pt.x < 0) || (pt.x > xClient)) || ((pt.y < 0) ||
                            (pt.y > yClient))) {
                       pt.x = (rand () / 47);
                       pt.y = (rand () / 102);
                    }
                    hDC = GetDC (hWnd);
                    Attribute = GetPixel (hDC, pt.x, pt.y);
                    sprintf (szOutputBuffer1, "The Point [%i, %i]", pt.x, pt.
                    sprintf (szOutputBuffer2, "Has Attribute %x", Attribute);
                    MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1,MB_OK)
                    ReleaseDC(hWnd, hDC);
                    break;

               case IDM_ENTER:
                    pt.x = pt.y = -1;
                    while (((pt.x < 0) || (pt.x > xClient)) || ((pt.y < 0) ||
                            (pt.y > yClient))) {
                      DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                             lpProcEnterPoint);
                      pt.x = atoi (szXValue);
                      pt.y = atoi (szYValue);
                    }
                    hDC = GetDC (hWnd);
                    Attribute = GetPixel (hDC, pt.x, pt.y);
                    sprintf (szOutputBuffer1, "The Point [%i, %i]", pt.x, pt.
                    sprintf (szOutputBuffer2, "Has Attribute %x", Attribute);
                    MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1,MB_OK)
                    ReleaseDC(hWnd, hDC);
                    break;

               case IDM_HELP:
                    ProcessMessage (hWnd, 2);
                    break;

           }
            break;

       case WM_DESTROY:
            PostQuitMessage (0);
            break;

      default:
            return DefWindowProc( hWnd, iMessage, wParam, lParam );
       }
  return 0L;
}

/****************************************************************************

BOOL FAR PASCAL EnterPointDlgProc (hDlg, iMessage, wParam, lParam)
HWND hDlg;
unsigned iMessage;
WORD wParam;
LONG lParam;
{
     int Index;
     char szChange [10];
     long lReturn;

     switch (iMessage) {
     case WM_INITDIALOG:
       SendDlgItemMessage (hDlg, IDD_X, EM_LIMITTEXT,
                           (WORD)40, 0L);
       SendDlgItemMessage (hDlg, IDD_Y, EM_LIMITTEXT,
                           (WORD)40, 0L);

       hX = GetDlgItem (hDlg, IDD_X);
         lpProcOldX = (FARPROC) GetWindowLong (hX, GWL_WNDPROC);
         SetWindowLong (hX, GWL_WNDPROC, (LONG) lpProcNewEnterPoint);
         SendMessage (hX, EM_SETSEL, 0, MAKELONG (0,32767));
       hY = GetDlgItem (hDlg, IDD_Y);
         lpProcOldY = (FARPROC) GetWindowLong (hY, GWL_WNDPROC);
         SetWindowLong (hY, GWL_WNDPROC, (LONG) lpProcNewEnterPoint);
         SendMessage (hY, EM_SETSEL, 0, MAKELONG (0,32767));
       hOK2 = GetDlgItem (hDlg, IDOK);

       return TRUE;
       break;

     case WM_COMMAND:
       switch (wParam) {
         case IDD_X:
              break;

         case IDD_Y:
              break;

         case IDOK:
              GetDlgItemText (hDlg, IDD_X, szXValue, 10) ;
              GetDlgItemText (hDlg, IDD_Y, szYValue, 10) ;
              EndDialog (hDlg, TRUE);
              break;

         default:
              return FALSE;
      }
    default:
      return FALSE;
  }
  return TRUE;
}

/****************************************************************************

BOOL FAR PASCAL NewEnterPointDlgProc  (hWnd, iMessage, wParam, lParam)
     HWND     hWnd;
     unsigned iMessage;
     WORD     wParam;
     LONG     lParam;
{
     switch (iMessage) {
       case WM_GETDLGCODE:
            return (DLGC_WANTALLKEYS);

       case WM_CHAR:
            if ((wParam == VK_TAB) || (wParam == VK_RETURN)) {
                SendMessage (hWndMain, WM_USER, 0, 0L);
                SetFocus (FindNextWindow (hWnd));
                return TRUE;
            }
            else {
              if (hWnd == hX)
                return ((BOOL)CallWindowProc (lpProcOldX, hWnd,
                        iMessage, wParam, lParam));
              if (hWnd == hY)
                return ((BOOL)CallWindowProc (lpProcOldY, hWnd,
                        iMessage, wParam, lParam));
            }
            break;

       default:
         if (hWnd == hX)
            return ((BOOL)CallWindowProc (lpProcOldX, hWnd,
                    iMessage, wParam, lParam));
         if (hWnd == hY)
            return ((BOOL)CallWindowProc (lpProcOldY, hWnd,
                    iMessage, wParam, lParam));
     }
}

/****************************************************************************

HWND FindNextWindow (hWnd)
     HWND   hWnd;
{
     if (hWnd == hX)      return hY;
     if (hWnd == hY)      return hOK2;
     return NULL;
}



GETPROFI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MOUSE\GETPROFI.C

#include <windows.h>
#include <stdio.h>

 BUFSIZE 80 /* Output Buffer Size */

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    nCmdShow;
{
   char szOutBuf[BUFSIZE];              /* Output Buffer                  */
   int iReturn;                         /* WIN.INI DoubleClickSpeed Value */

   iReturn = GetProfileInt((LPSTR)"windows",          /* Application Name */
                           (LPSTR)"DoubleClickSpeed", /* Key Name         */
                           (int)-999);                /* Default Value    */
   if (iReturn == -999) {  /* If the default was returned, say so */
      sprintf(szOutBuf, "%s%d",
              "The Default Value was Returned: ",
              iReturn);
      MessageBox(GetFocus(), (LPSTR)szOutBuf,
                 (LPSTR)"GetProfileInt() - Default!",
                 MB_OK | MB_ICONEXCLAMATION);
      }
   else {  /* Otherwise, display the speed in a message box */
      sprintf(szOutBuf, "%s%d",
              "The DoubleClickSpeed Returned is: ",
              iReturn);
      MessageBox(GetFocus(), (LPSTR)szOutBuf,
                 (LPSTR)"GetProfileInt()", MB_OK);
      }
   return FALSE;
}


GETPROFS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MOUSE\GETPROFS.C

/*
 * This program demonstrates the GetProfileString() function. It attempts
 * to obtain the string corresponding to the following:
 *
 *   [windows]
 *   spooler=<string>
 *
 */

#include <windows.h>
#include <stdio.h>

#define BUFSIZE 10

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    nCmdShow;
{
   int iCopied;             /* Number of Characters Copied from WIN.INI */
   char szOutBuf[BUFSIZE];  /* Output Buffer to Receive WIN.INI info.   */

   iCopied = GetProfileString((LPSTR)"windows",     /* Application Name */
                              (LPSTR)"spooler",     /* Key Name         */
                              (LPSTR)"Default!",    /* Default String   */
                              (LPSTR)szOutBuf,      /* Output Buffer    */
                              (int)BUFSIZE);        /* Number of Chars. */
   if (iCopied == 0) /* If No Chars. Copied, Issue Error. */
      MessageBox(GetFocus(), (LPSTR)"Error Getting Profile String!",
                 (LPSTR)"GetProfileString() Error!",
                 MB_OK | MB_ICONEXCLAMATION);
   else /* Otherwise, print out the results. */
      MessageBox(GetFocus(), (LPSTR)szOutBuf,
                 (LPSTR)"GetProfileString() - spooler =",
                 MB_OK);
   return FALSE;
}


GETROP2.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GETROP2.C

/*

Windows Version 2.03 function demonstration application

Function(s) demonstrated in this program: GetROP2

Compiler version: 5.01


Description:

The GetROP2 function returns the current drawing mode.  The drawing mode
specifies how the pen or interior color and the color already on the
display surface are combined to yield a new color.  This program
simply calls GetROP2 and displays the current drawing mode based on
the function return value.


Additional Comments:

Note that the drawing modes define how GDI combines source and destination
colors when drawing with the current pen.

****************************************************************************/

#include <windows.h>

long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GetROP2" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     HDC             hDC;                 /* For the GetROP2 demonstration */
     short           iROP2;               /* For the GetROP2 demonstration */

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWnd = CreateWindow (szAppName,            /* window class name       */
                    "GetROP2",                  /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWnd, nCmdShow) ;

     UpdateWindow (hWnd) ;

/***************************************************************************/
/* Begin the GetROP2 demonstration */

     hDC = GetDC (hWnd);
     iROP2 = GetROP2 (hDC);                /* Get the current drawing mode */

     switch (iROP2)
        {
        case R2_BLACK:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_BLACK.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_NOTMERGEPEN:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_NOTMERGEPEN.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_MASKNOTPEN:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_MASKNOTPEN.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_NOTCOPYPEN:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_NOTCOPYPEN.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_MASKPENNOT:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_MASKPENNOT.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_NOT:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_NOT .",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_XORPEN:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_XORPEN.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_NOTMASKPEN:
           {
           MessageBox (hWnd,
                       (LPSTR)" The current drawing mode returned by GetROP2
is R2_NOTMASKPEN.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_MASKPEN:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_MASKPEN.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_NOTXORPEN:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_NOTXORPEN.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_NOP:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_NOP.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_MERGENOTPEN:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_MERGENOTPEN.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_COPYPEN:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_COPYPEN.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_MERGEPENNOT:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_MERGEPENNOT.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_MERGEPEN:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_MERGEPEN.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        case R2_WHITE:
           {
           MessageBox (hWnd,
                       (LPSTR)"The current drawing mode returned by GetROP2 \
is R2_WHITE.",
                       (LPSTR)"GetROP2",
                       MB_OK
                      );
           break;
           }
        default:
           MessageBox (hWnd,
                       (LPSTR)"Something is wrong.  GetROP2 is supposed to \
return the current drawing mode but instead returns an unknown value.",
                       (LPSTR)"GetROP2",
                       NULL
                      );
           break;
        } /* end switch */

     ReleaseDC (hWnd, hDC);

/* End the GetROP2 demonstration */
/***************************************************************************/

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{

 switch(iMessage)
 {
  case WM_DESTROY:
  {
   PostQuitMessage(0);
   break;
  }
  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }

 return (0L);
}


GETSCPOS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SCROLL\GETSCPOS.C

/*
 *
 *  GetScrollPos
 *
 *  This program demonstrates the use of the function GetScrollPos.
 *  It retrieves the current position of a scroll bar elevator.
 *
 */

#include "windows.h"
#include "stdio.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Getscpos";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;                /* Handle to the parent window    */
    WORD  nPos;                /* The position of the elevator   */
    char  szBuffer[35];        /* string buffer for the message
                                * box                            */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Getscpos",
                        (LPSTR)"Getting Scroll Position",
                        WS_OVERLAPPEDWINDOW|WS_VSCROLL,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Setting up the vertical and horizontal scroll bars range */
    SetScrollRange (hWnd, SB_VERT, 1, 10, (BOOL)TRUE);

    /* initial position on a vertical scroll bar */
    SetScrollPos (hWnd, SB_VERT, 2, (BOOL)TRUE);
    nPos = GetScrollPos (hWnd, SB_VERT);
    sprintf (szBuffer, "The elevator is currently at %d", nPos);
    MessageBox (hWnd, (LPSTR)szBuffer, (LPSTR)"Vertical", MB_OK);

    /* moved to a new location */
    SetScrollPos (hWnd, SB_VERT, 9, (BOOL)TRUE);
    nPos = GetScrollPos (hWnd, SB_VERT);
    sprintf (szBuffer, "The elevator is currently at %d", nPos);
    MessageBox (hWnd, (LPSTR)szBuffer, (LPSTR)"Vertical", MB_OK);

    return 0;
}


GETSCRNG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SCROLL\GETSCRNG.C

/*
 *
 *  GetScrollRange
 *
 *  This program demonstrates the use of the function GetScrollRange.
 *  It retrieves the current minimum and maximum scroll bar range
 *  for the given scroll bar.
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"
#include "stdio.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Getscrng";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;                /* Handle to the parent window    */
    short nMinPos, nMaxPos;    /* The range of the scroll bar    */
    char  szBuffer[50];        /* string buffer for the message
                                * box                            */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Getscrng",
                        (LPSTR)"GetScrollRange",
                        WS_OVERLAPPEDWINDOW|WS_VSCROLL,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Setting up the vertical scroll bar range and use GETSCROLLRANGE
     * to retrieve the range
     */
    SetScrollRange (hWnd, SB_VERT, 1, 10, (BOOL)TRUE);
    GetScrollRange (hWnd, SB_VERT, (LPINT) &nMinPos, (LPINT) &nMaxPos);
    sprintf (szBuffer, "The range of the scroll bar is between %d and %d",
             nMinPos, nMaxPos);
    MessageBox (hWnd, (LPSTR)szBuffer, (LPSTR)"GetScrollRange", MB_OK);

    return 0;
}



GETSTOCK.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GETSTOCK.C

/*
 *  GetStockObject
 *
 *  This function demonstrates the use of the GetStockObject function.  It wi
 *  create a window using the CreateWindow function, show the window using
 *  the ShowWindow command and procede to draw a triangle in the window in
 *  the MM_ANISOTROPIC mapping mode.  It will use the GetStockObject function
 *  to get the handle to a new brush.
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

/* Forward Declarations  */

BOOL FAR PASCAL InitGetStockObject ( HANDLE , HANDLE , int );
long FAR PASCAL GetStockObjectWindowProc ( HANDLE , unsigned , WORD , LONG );

/*
 *  MAIN PROCEDURE
 */

int PASCAL WinMain  (hInstance , hPrevInstance , lpszCmdLine , nCmdShow )

HANDLE hInstance , hPrevInstance;
LPSTR  lpszCmdLine;
int nCmdShow;
  {
  MSG  msg;          /*  Temp buffer to hold message  */

  InitGetStockObject (hInstance, hPrevInstance, nCmdShow );  /*  Init Routine

  while ( GetMessage((LPMSG)&msg, NULL, 0 , 0 ))
    {
    TranslateMessage((LPMSG)&msg);
    DispatchMessage((LPMSG)&msg);     /*  Give Your windowproc the  */
    }              /*  message        */

  exit(msg.wParam);
  }

BOOL FAR PASCAL InitGetStockObject (hInstance , hPrevInstance , nCmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
int nCmdShow;

  {
  WNDCLASS  wcGetStockObjectClass;
  HWND  hWnd;

  wcGetStockObjectClass.lpszClassName = (LPSTR) "GetStockObject";
  wcGetStockObjectClass.hInstance     = hInstance;
  wcGetStockObjectClass.lpfnWndProc   = GetStockObjectWindowProc;
  wcGetStockObjectClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
  wcGetStockObjectClass.hIcon        = NULL;
  wcGetStockObjectClass.lpszMenuName  = (LPSTR) NULL;
  wcGetStockObjectClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcGetStockObjectClass.style        = CS_HREDRAW | CS_VREDRAW;
  wcGetStockObjectClass.cbClsExtra    = 0;
  wcGetStockObjectClass.cbWndExtra    = 0;

  RegisterClass ((LPWNDCLASS) &wcGetStockObjectClass);

  hWnd = CreateWindow((LPSTR) "GetStockObject",   /*  Window class name
          (LPSTR) "GetStockObject",   /*  Window title        */
          WS_OVERLAPPEDWINDOW,    /*  Type of window        */
          CW_USEDEFAULT,      /*  default x pos        */
          CW_USEDEFAULT,      /*  default y pos        */
          CW_USEDEFAULT,      /*  default change in x pos */
          CW_USEDEFAULT,      /*  default change in y pos */
          (HWND)NULL,      /*  No parent for this wind */
          (HMENU)NULL,      /*  Use the Class menu      */
          (HANDLE)hInstance,    /*  Who created this window */
          (LPSTR)NULL      /*  No params. to pass on.  */
         );

  ShowWindow (hWnd , nCmdShow);   /*  Display this window on the screen
           *  nCmdShow is passed in by WinMain, and
           *  should only be used with ShowWindow
           *  once during a program.  Any further
           *  calls to ShowWindow will need to have
           *  certain values.  See entry in manual
           *  for ShowWindow for further details
           */

  UpdateWindow (hWnd);     /*  Cause a paint message    */

  return TRUE;
  }

/*
 *  THE WINDOW PROCEDURE - Process messages
 */

long FAR PASCAL GetStockObjectWindowProc (hWnd , message , wParam , lParam)

HWND      hWnd;        /*  Handle of the window  */
unsigned    message;        /*  Message type    */
WORD      wParam;        /*  Message 16-bit param  */
LONG      lParam;        /*  Message 32-bit param  */
  {
  switch (message)        /*  Check the message type  */
    {
    case WM_PAINT:        /*  Process the Paint  */
  PaintGetStockObjectWindow (hWnd); /*  message          */
  break;

    case WM_DESTROY:        /*  If close requested  */
  PostQuitMessage(0);      /*    send yourself a quit  */
  break;          /*    message    */

    default:
  return( DefWindowProc( hWnd , message , wParam , lParam ) );
  break;
    }
  return( 0L );
  }

/*
 *  THE PAINT PROCEDURE
 */

PaintGetStockObjectWindow (hWnd)

HWND  hWnd;             /*  Handle of the window  */
  {
  PAINTSTRUCT  ps;
  HDC    hDC;
  POINT   lpTriangle[4];
  HANDLE  hOldBrush , hBrush;        /*  For loading new brushes  */
  RECT    rRect;            /*  Will hold the client     */
                /*  Rectangle       */

  BeginPaint (hWnd , (LPPAINTSTRUCT) &ps);    /*  Prepare the client area  */
  hDC = ps.hdc;             /*  Get the Display Context  */

  hBrush    = GetStockObject ( GRAY_BRUSH );  /*  Get a gray brush     */

  hOldBrush = SelectObject ( hDC , hBrush );  /*  Select the new brush     */

  lpTriangle[0].x = 150;    /*  The values of the points  */
  lpTriangle[0].y = 100;
  lpTriangle[1].x = 100;
  lpTriangle[1].y = 200;
  lpTriangle[2].x = 200;
  lpTriangle[2].y = 200;

  SetMapMode ( hDC , MM_ANISOTROPIC );   /*  Set the mapping mode        */

  SetWindowExt ( hDC , 300 , 300 );   /*  Set the extent of the drawing
            *  area.  This is the area that
            *  holds graphics that you create
            *  with GDI functions.  Do not
            *  confuse this function with
            *  the actual window.  The
            *  SetViewportExt sets the
            *  extent of the area to be mapped
            *  to which is the actual window
            */

  GetClientRect ( hWnd , (LPRECT) &rRect );
           /*  Get the size of the client area
            *  so that we can set the viewport
            *  extent
            */

  SetViewportExt ( hDC , rRect.right , rRect.bottom );
           /*  Set the Extent of the viewport   */

  Polygon ( hDC , lpTriangle , 3 );   /*  Draw the triangle          */

  ValidateRect (hWnd , (LPRECT) NULL);   /*  Disable any more paint messages
  EndPaint (hWnd, (LPPAINTSTRUCT) &ps );

  SelectObject( hDC , hOldBrush );   /*  Replace the old brush  */
  return TRUE;
  }


GETTEXT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TEXT\GETTEXT.C

/*
 *   GetWindowText
 *
 *   This program demonstrates the use of the GetWindowText function. The
 *   GetWindowText function copies the given window's caption bar (if one
 *   exists) into the second parameter. GetWindowText returns an integer
 *   specifying the length of the caption. If GetWindowText returns 0, then
 *   there is no caption for the given window.
 *
 */

#include "windows.h"
 <stdio.h>     /* required for sprintf */

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;
    int x;           /* return value from GetWindowText  */
    char buffer[40];         /* buffer that GetWindowText places text */

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"Sample Application",
      (LPSTR)"Sample Application",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* get caption bar text if it exists */
    x=GetWindowText(hWnd,buffer,40);
    /* if there is a caption */
    if (x>0)
      /* output the caption    */
      MessageBox(hWnd,(LPSTR)buffer,
         (LPSTR)"THE CAPTION BAR SAYS:",MB_OK);
    else
      /* output "There is no Title Bar */
      MessageBox(hWnd,(LPSTR)NULL,
         (LPSTR)"There is no Title Bar",MB_OK);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GETTIMER.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TIME\GETTIMER.C

/*

Function(s) demonstrated in this program: GetTimerResolution

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function returns a handle to the display context.

Additional Comments:  This function is undocumented in the SDK manuals.

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "GetTimeR.h"


HWND     hWndParent1;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use of the GetTimerResolution Windows function.",

"Help Message",
"     This program uses the GetTimerResolution Windows\n\
function to get the timer resolution.  Use the menu\n\
to invoke this function.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GetTimeR" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "GetTimerResolution",       /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 HDC         hDC;
 PAINTSTRUCT ps;
 DWORD       nTimerResolution;

 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_GETTIMER:
               nTimerResolution = GetTimerResolution ();
               sprintf (szOutputBuffer1, "Timer Resolution = %i", nTimerResol
               MessageBox (hWnd, szOutputBuffer1, "GetTimerResolution", MB_OK
               break;

          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}





GETVWORG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\GETVWORG.C

/*
 *
 * GetViewportOrg
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  The WinMain proceeds to execute the GetViewportOrg function.
 *  Two message boxes are created which display the x and y coordinates
 *  of the viewport origin respectively.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;
  HDC hDC;            /* Handle to the Display Context. */
  unsigned int xOrg;  /* X coordinate of the origin.    */
  unsigned int yOrg;  /* Y coordinate of the origin.    */
  long ptOrigin;      /* Long pointer to the origin.    */
  char szbuf[19];     /* Output buffer.                 */

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"getvworg";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon          = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "getvworg",
           (LPSTR) "GetViewportOrg",
           WS_OVERLAPPEDWINDOW,           /* Use overlapped window.   */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

   hDC = GetDC(hWnd);

   ptOrigin = GetViewportOrg(hDC);      /* Get the viewport origin.  */

   xOrg = LOWORD(ptOrigin);             /* Isolate the X coordinate. */
   yOrg = HIWORD(ptOrigin);             /* Isolate the Y coordinate. */

   sprintf(szbuf,                       /* Place the X coordinate in */
           "%s%d",                      /*  the output buffer along  */
           "The x Origin is ",          /*  with some explanatory    */
           xOrg);                       /*  text.                    */
   MessageBox(NULL,                     /* Display the information   */
              (LPSTR)szbuf,             /*  in a message box.        */
              (LPSTR)"GetViewportOrg",
              MB_OK);

   sprintf(szbuf,                       /* Place the Y origin in the */
           "%s%d",                      /*  output buffer along with */
           "The y Origin is ",          /*  some text.               */
           yOrg);
   MessageBox(NULL,                     /* Output the information in */
              (LPSTR)szbuf,             /*  another message box.     */
              (LPSTR)"GetViewportOrg",
              MB_OK);

} /* WinMain */


GETWIND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GETWIND.C

/*

Function(s) demonstrated in this program: GetWindow

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function returns a handle to the next or previous Window
   in the Window Manager list.  If no match is found a NULL handle is
  returned.

Additional Comments:

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "GetWind.h"


HWND     hWndParent1;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use of the GetWindow Windows function.",

"Help Message",
"     This program uses the GetWindow Windows function\n\
to get a handle to the next window in the Window\n\
manager handle list.  This handle is then displayed\n\
in a message box.  The window corresponding to that\n\
handle is then iconized.  Use the menu to invoke\n\
this function.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GetWind" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "GetWindow",               /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 HWND        hNextWindow;
 PAINTSTRUCT ps;
 static int  xClient, yClient;
 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_GETWINDOW:
               hNextWindow = GetWindow (hWnd, GW_HWNDNEXT);
               sprintf (szOutputBuffer1,
                      "The Handle to the Next Window is %x", hNextWindow);
               MessageBox (hWnd, szOutputBuffer1, "GetWindow", MB_OK);
               if (!IsIconic (hNextWindow))
                  ShowWindow (hNextWindow, SW_SHOWMINIMIZED);
               break;

          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}





GETWINDC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GETWINDC.C

/*
 * GetWindowDC
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  The WinMain proceeds to execute the GetWinDC function.
 *  If the function call is successful, a message box is created which
 *  reflects success.  Otherwise, failure is reported via message box.
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG  msg;
  HDC  hDC;     /* Handle to the Display Context. */
  BOOL bResult; /* Result from using the DC.      */

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"getwindc";  /* Unique class name. */
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon          = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);
     }

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "getwindc", /* Create the window.        */
           (LPSTR) "GetWindowDC",        /* Title: GetWindowDC.       */
           WS_OVERLAPPEDWINDOW,          /* Set to overlapped window. */
           CW_USEDEFAULT,                /* Use default coordinates.  */
           CW_USEDEFAULT,                /* Use default coordinates.  */
           CW_USEDEFAULT,                /* Use default coordinates.  */
           CW_USEDEFAULT,                /* Use default coordinates.  */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

   if ((hDC = GetWindowDC(hWnd)) != NULL)     /* If successful at getting */
      MessageBox(GetFocus(),                  /*  the DC, send success    */
     (LPSTR)"Got The Window DC",            /*  message via message    */
     (LPSTR)"GetWindowDC",                  /*  box.                 */
     MB_OK);
   else                                     /* Otherwise,               */
      MessageBox(GetFocus(),                  /*  send the failure        */
     (LPSTR)"Do Not Have the DC",           /*  message via message    */
     (LPSTR)"GetWindowDC",                  /*  box.                 */
     MB_OK);

   bResult = Rectangle(hDC, 100, 100, 200, 200);

   if (bResult != NULL)
      MessageBox(GetFocus(), (LPSTR)"Used DC Successfully",
                 (LPSTR)"Rectangle()", MB_OK);
   else
      MessageBox(GetFocus(), (LPSTR)"Error Using DC",
                 (LPSTR)"Rectangle()", MB_OK);

   ReleaseDC(hWnd, hDC);

} /* WinMain */


GETWINWD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GETWINWD.C

/*
 *   GetWindowWord
 *
 *   This program demonstrates the use of the GetWindowWord function.
 *   GetWindowWord returns information about the window identified by
 *   the first parameter. The information it returns is specified by the
 *   second parameter. In this sample application, GetWindowWord was
 *   called in WinMain and passed "hWnd" and "GWW_HINSTANCE," telling it
 *   to return the instance handle of the module owning "hWnd."
 *
 *   Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;
    HDC hDC;      /* handle to display context */
    HANDLE ourhInstance;  /* return value from GetWindowWord */

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"Sample Application",
      (LPSTR)"GetWindowWord",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    hDC = GetDC(hWnd);    /** get a display context for hWnd **/

    TextOut(hDC,
      20,
      5,
  (LPSTR)"I will now call GetWindowWord and pass it 'hWnd' and 'GWW_HINSTANCE
  (short)68);

    TextOut(hDC,
      20,
      15,
(LPSTR)"telling it to retrieve the instance handle of the module owning the",
  (short)67);

    TextOut(hDC,
      20,
      25,
  (LPSTR)"window associated with hWnd. GetWindowWord should return 'hInstance
  (short)69);

  MessageBox(hWnd,(LPSTR)"  OKAY",(LPSTR)" ",MB_OK);

/**   call GetWindowWord, tell it to retrieve the instance handle  **/
/**   of the module owning the window associated with hWnd     **/
  ourhInstance = GetWindowWord(hWnd,GWW_HINSTANCE);

/**   clear screen **/
  InvalidateRect(hWnd,(LPRECT)NULL,(BOOL)TRUE);
  UpdateWindow(hWnd);

/**  if GetWindowWord correctly returned the instance handle **/
/**  of the  module owning the window associated with hWnd.. **/
  if (ourhInstance = hInstance)
      MessageBox(hWnd,
    (LPSTR)"instance handle of the module owning hWnd.",
    (LPSTR)"GetWindowWord correctly retrieved the...",
    MB_OK);
    else
      MessageBox(hWnd,
    (LPSTR)"instance handle of the module owning hWnd.",
    (LPSTR)"GetWindowWord DID NOT correctly retrieve the...",
    MB_OK);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
  return DefWindowProc( hWnd, message, wParam, lParam );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GETWNEXT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GETWNEXT.C

/*
 * GetWindowExt()
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  The WinMain proceeds to execute the GetWindowExt function.
 *  Two message boxes are created which display the coordinates of the
 *  window extentions.
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG   msg;
  HDC   hDC;             /* Handle to the Display Context.  */
  WORD  xExt;            /* X extent.                       */
  WORD  yExt;            /* Y extent.                       */
  DWORD dwExtent;        /* Long pointer to the extent.     */
  char szbuf[50];        /* Output buffer, zero terminated. */

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"getwnext"; /* Unique class name. */
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon          = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "getwnext", /* Create the Window.        */
           (LPSTR) "GetWindowExt",       /* Title: GetWindowExt.      */
           WS_OVERLAPPEDWINDOW,          /* Set to overlapped window. */
           CW_USEDEFAULT,                /* Use default coordinates.  */
           CW_USEDEFAULT,                /* Use default coordinates.  */
           CW_USEDEFAULT,                /* Use default coordinates.  */
           CW_USEDEFAULT,                /* Use default coordinates.  */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);
   UpdateWindow(hWnd);

   hDC = GetDC(hWnd);               /* Get the handle to the DC. */
   dwExtent = GetWindowExt(hDC);    /* Get the window extents.   */

   xExt = LOWORD(dwExtent);         /* Isolate the X extent.     */
   yExt = HIWORD(dwExtent);         /* Isolate the Y extent.     */

   sprintf(szbuf,                   /* Place X extent, with      */
           "%s%hu",                 /*  message, into the output */
           "The Original x Extent is ",  /*  buffer for display  */
           xExt);                   /* in a message box.         */
   MessageBox(GetFocus(),           /* Output the X extent in a  */
              (LPSTR)szbuf,         /*  message box.             */
              (LPSTR)"GetWindowExt() - MM_TEXT",
              MB_OK);

   sprintf(szbuf,                   /* Place Y extent, with      */
           "%s%hu",                 /*  message, into the output */
           "The Original y Extent is ", /*  buffer for display   */
           yExt);                   /* in a message box.         */
   MessageBox(GetFocus(),           /* Output the Y extent in a  */
              (LPSTR)szbuf,         /*  message box.             */
              (LPSTR)"GetWindowExt() - MM_TEXT",
              MB_OK);

   MessageBox(GetFocus(), (LPSTR)"Settting Extents to (2,4)",
              (LPSTR)"SetWindowExt() - MM_ISOTROPIC", MB_OK);
   SetMapMode(hDC, MM_ISOTROPIC);   /* Need this or SetWindowExt */
   SetWindowExt(hDC, 2, 4);         /* will be ignored.          */

   dwExtent = GetWindowExt(hDC);    /* Get the window extents.   */

   xExt = LOWORD(dwExtent);         /* Isolate the X extent.     */
   yExt = HIWORD(dwExtent);         /* Isolate the Y extent.     */

   sprintf(szbuf,                   /* Place X extent, with      */
           "%s%hu",                 /*  message, into the output */
           "The New x Extent is ",  /*  buffer for display       */
           xExt);                   /* in a message box.         */
   MessageBox(GetFocus(),           /* Output the X extent in a  */
              (LPSTR)szbuf,         /*  message box.             */
              (LPSTR)"GetWindowExt() - MM_ISOTROPIC",
              MB_OK);

   sprintf(szbuf,                   /* Place Y extent, with      */
           "%s%hu",                 /*  message, into the output */
           "The New y Extent is ",  /*  buffer for display       */
           yExt);                   /* in a message box.         */
   MessageBox(GetFocus(),           /* Output the Y extent in a  */
              (LPSTR)szbuf,         /*  message box.             */
              (LPSTR)"GetWindowExt() - MM_ISOTROPIC",
              MB_OK);

   ReleaseDC(hWnd, hDC);            /* Release the DC.           */

} /* WinMain */


GETWNLNG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GETWNLNG.C

/*
 * GetWindowLong
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  The WinMain proceeds to execute the GetWindowLong function.
 *  If the function call is successful, two message boxes are created which
 *  show if the window is tiled and the pointer to the window procedure.
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;
  HDC hDC;         /* Handle to the Display Context.       */
  LONG lLong;      /* LONG returned by GetWindowLong.       */
  char szbuf[80];  /* String buffer used in Message Boxes. */

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"getwnlng";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor      = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style        = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "getwnlng",
           (LPSTR) "GetWindowLong",
           WS_OVERLAPPEDWINDOW,            /* Use overlapped window.   */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

   /* Get the style of the Window */

   lLong = GetWindowLong(hWnd, GWL_STYLE);

   /*  If the Window is tiled, say so; otherwise, report that it is not */

   if ((lLong & WS_OVERLAPPEDWINDOW) == WS_OVERLAPPEDWINDOW)
   {  sprintf(szbuf,"%s","The Window has the Overlapped Style!");
      MessageBox(NULL, (LPSTR)szbuf, (LPSTR)"GWL_STYLE", MB_OK);
   }
   else
   {  sprintf(szbuf, "%s", "The Window is not Overlapped!!!");
      MessageBox(NULL, (LPSTR)szbuf, (LPSTR)"GWL_STYLE", MB_OK);
   }

   /*  Now, get the pointer to the function's window procedure.         */

   lLong = GetWindowLong(hWnd, GWL_WNDPROC);

   /*  Print out the address of the window procedure in a message box.  */

   sprintf(szbuf,"%s%lx","The Pointer to the Window Procedure is ",lLong);
   MessageBox(NULL, (LPSTR)szbuf, (LPSTR)"GWL_WNDPROC", MB_OK);

} /* WinMain */


GETWNORG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GETWNORG.C

/*
 * GetWindowOrg
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  The WinMain proceeds to execute the GetWindowOrg function.
 *  Two message boxes are created which display the x and y coordinates
 *  respectively.  The x and y values here are the default values.
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;
  HDC hDC;            /* Handle to the Display Context. */
  unsigned int xOrg;  /* X origin.                      */
  unsigned int yOrg;  /* Y origin.                      */
  long ptOrigin;      /* Pointer to the origin.         */
  char szbuf[50];     /* Output buffer.                 */

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"getwnorg";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style        = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "getwnorg",
           (LPSTR) "GetWindowOrg",
           WS_OVERLAPPEDWINDOW,           /* Use overlapped window.   */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);
   UpdateWindow(hWnd);

   hDC = GetDC(hWnd);                /* Get the handle to the DC.     */
   ptOrigin = GetWindowOrg(hDC);     /* Get the origin of the window. */
   ReleaseDC(hWnd, hDC);             /* Release the DC.               */
   xOrg = LOWORD(ptOrigin);          /* Isolate the x coordinate.     */
   yOrg = HIWORD(ptOrigin);          /* Isolate the y coordinate.     */

      /* Display the X coordinate in a message box. */

   sprintf(szbuf,"%s%d","The Original x Origin is ",xOrg);
   MessageBox(GetFocus(), (LPSTR)szbuf, (LPSTR)"GetWindowOrg", MB_OK);

      /* Display the Y coordinate in a message box. */

   sprintf(szbuf,"%s%d","The Original y Origin is ",yOrg);
   MessageBox(GetFocus(), (LPSTR)szbuf, (LPSTR)"GetWindowOrg", MB_OK);

   MessageBox(GetFocus(), (LPSTR)"Setting a New Origin at (5,5)",
              (LPSTR)"SetWindowOrg", MB_OK);

      /* Set a new origin and get it too.           */
   SetWindowOrg(hDC, 5, 5);          /* Set new origin of the window. */
   ptOrigin = GetWindowOrg(hDC);     /* Get new origin of the window. */
   xOrg = LOWORD(ptOrigin);          /* Isolate the x coordinate.     */
   yOrg = HIWORD(ptOrigin);          /* Isolate the y coordinate.     */

      /* Display the X coordinate in a message box. */

   sprintf(szbuf,"%s%d","The New x Origin is ",xOrg);
   MessageBox(GetFocus(), (LPSTR)szbuf, (LPSTR)"GetWindowOrg", MB_OK);

      /* Display the Y coordinate in a message box. */

   sprintf(szbuf,"%s%d","The New y Origin is ",yOrg);
   MessageBox(GetFocus(), (LPSTR)szbuf, (LPSTR)"GetWindowOrg", MB_OK);

} /* WinMain */


GETWNRCT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\GETWNRCT.C

/*
 *
 * GetWindowRect
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  The WinMain proceeds to execute the GetWindowRect function.
 *  If the function call is successful, message boxes are created which
 *  display the rectangle coordinates.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;
  RECT *rect;         /* Pointer to Window Rectangle. */
  char szbuf[31];       /* Buffer for Message Box.      */

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"getwnrct";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "getwnrct",
           (LPSTR) "GetWindowRect",
           WS_OVERLAPPEDWINDOW,           /* Use overlapped window.   */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

   GetWindowRect(hWnd, (LPRECT)rect);  /* Get the Window Rectangle.    */

   /* Report the top left and the bottom right of the window rectangle */
   /* in separate message boxes.                                     */

   sprintf(szbuf,"%s%d%s%d%s","The top left is (", rect->top,
     ",", rect->left, ").");
   MessageBox(NULL, (LPSTR)szbuf, (LPSTR)"GetWindowRect", MB_OK);

   sprintf(szbuf,"%s%d%s%d%s","The bottom right is (", rect->bottom,
     ",", rect->right, ").");
   MessageBox(NULL, (LPSTR)szbuf, (LPSTR)"GetWindowRect", MB_OK);

} /* WinMain */

/* WINDOWPROC */


GFOCUS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GFOCUS.C

/*

Function(s) demonstrated in this program: GetFocus

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function returns a handle to the Window which currently
   has the input focus.

Additional Comments:

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "gFocus.h"


HWND     hWndParent1;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use of the GetFocus Windows function.",

"Help Message",
"     This program uses the GetFocus Windows function\n\
to get a handle to the Window which has the input\n\
focus.  This handle is then displayed in a message\n\
box.  Use the menu to invoke this function.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "gFocus" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "GetDC",                    /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 HWND        hWndFocus;
 PAINTSTRUCT ps;
 static int  xClient, yClient;
 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_GETFOCUS:
               hWndFocus = GetFocus ();
               sprintf (szOutputBuffer1,
                        "The Handle to the Focus Window is %x", hWndFocus);
               MessageBox (hWnd, szOutputBuffer1, "GetFocus", MB_OK);
               break;

          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}





GINSTAT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\GINSTAT.C

/*
 *
 *  GetInputState
 *
 *  This program demonstrates the use of the function GetInputState.
 *  This function determines whether there are mouse, keyboard, or timer
 *  events in the system queue that require processing.
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  BOOL bState;

  MessageBox (NULL, (LPSTR)"Getting input state", (LPSTR)"GetInputState",
     MB_OK);

  bState = GetInputState ();

  if ( bState != 0 )
     MessageBox (NULL, (LPSTR)"No Important Messages on the Queue", (LPSTR)"G
        MB_OK);
  else
     MessageBox (NULL, (LPSTR)"Important Messages are Waiting",
        (LPSTR)"GetInputState", MB_OK|MB_ICONEXCLAMATION);

  return 0;
}


GINSTDAT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\GINSTDAT.C

/*
 *
 *  GetInstanceData
 *
 *  This program demonstrates the use of the function GetInstanceData.
 *  This function copies data from a previous intance of an application
 *  into the data area of the current instance.
 *
 *  Other references: numerous apps. with SDK
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

LPSTR far PASCAL lstrcpy( LPSTR, LPSTR );

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  int nBytes = 0;
  char szAppName[25];
  char szFuncName[25];
  char szBuffer[80];

  lstrcpy ( (LPSTR) szAppName, (LPSTR) "ginstdat" );

  lstrcpy ( (LPSTR) szFuncName, (LPSTR) "GetIntanceData" );

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) szAppName;
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) NULL;
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }
  else
     {
     MessageBox (NULL, (LPSTR)"Getting instance data",
       (LPSTR)szFuncName, MB_OK );

     nBytes = GetInstanceData( hPrevInstance, (PSTR)szAppName, 25 );

     sprintf ( szBuffer, "%s%d", "The number of bytes copied is ", nBytes );

     MessageBox ( NULL, (LPSTR)szBuffer, (LPSTR)szFuncName, MB_OK );
     }

  hWnd = CreateWindow ( ( LPSTR ) szAppName, ( LPSTR ) szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      ( HWND ) NULL, ( HMENU ) NULL,
                      ( HANDLE ) hInstance, ( LPSTR ) NULL );

  ShowWindow ( hWnd , cmdShow );

  if ( nBytes == 0 )
  MessageBox ( NULL, (LPSTR)"Start another instance before \npushing ok",
      (LPSTR)szFuncName, MB_OK );

  return 0;
}


GKEYBSTA.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\GKEYBSTA.C

/*
 *  GetKeyboardState
 *
 *  This program demonstrates the use of the function GetKeyboardState.
 *  This function copies the status of the 256 virtual-keyboard keys to the
 *  buffer specified by the parameter.
 *
 */

#include <windows.h>

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  static char szFuncName[] = "GetKeyboardState";
  char rgcKeyState[256];
  char szOutputBuffer1 [500];
  int ncount, I;

  MessageBox(GetFocus(), (LPSTR)"Getting the state of the keyboard",
             (LPSTR)szFuncName, MB_OK);

  (void)GetKeyboardState((LPSTR)rgcKeyState);

  if (rgcKeyState [VK_F1] & 0x80)
     MessageBox(GetFocus(), (LPSTR)"The F1 key is Down",
                (LPSTR)szFuncName, MB_OK);
  else
     MessageBox(GetFocus (), (LPSTR)"The F1 Key is Up",
                (LPSTR)szFuncName, MB_OK);

  rgcKeyState [VK_F1] = 0x80;

  MessageBox (GetFocus (),(LPSTR)"The F1 key has been set to the down state."
              (LPSTR)"About to use SetKeyboardState.", MB_OK);

  SetKeyboardState (rgcKeyState);
  GetKeyboardState (rgcKeyState);

  if (rgcKeyState [VK_F1] & 0x80)
     MessageBox(GetFocus(), (LPSTR)"The F1 key has been set successfully",
                (LPSTR)"The F1 key is Down", MB_OK);
  else
     MessageBox(GetFocus(), (LPSTR)"The F1 was not set successfully",
                (LPSTR)"The F1 Key is Up", MB_OK);
  return 0;
}



GKEYSTAT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\GKEYSTAT.C

/*
 *
 *  GetKeyState
 *
 *  This program demonstrates the use of the function GetKeyState
 *  This function retrieves the state of the virtual key specified by the
 *  parameter.
 *
 */

#include <windows.h>

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  static char szFuncName[] = "GetKeyState";
  int nState;

  MessageBox (NULL, (LPSTR)"Getting the key state of F1", (LPSTR)szFuncName,
     MB_OK);

  nState = GetKeyState ( VK_F1 );

  if ( ( nState & 0x8000 ) != 0x8000 )
     MessageBox (NULL, (LPSTR)"The key F1 is up", (LPSTR)szFuncName, MB_OK);
  else
     MessageBox (NULL, (LPSTR)"The key F1 is down", (LPSTR)szFuncName, MB_OK)

  return 0;
}


GLOBALLO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBALLO.C

/*
 *   GlobalAlloc
 *
 *   This program demonstrates the use of the GlobalAlloc function. The
 *   GlobalAlloc function allocates memory from the Global heap. GlobalAlloc
 *   was called from WinMain in this sample application.
 *
 */

#include <windows.h>

int sprintf();

typedef struct {    /* structure we are going */
    int x;    /* to allocate and lock   */
    int y;
         } MYSTRUCT;

typedef MYSTRUCT far *lpMyPtr;  /* far pointer to MYSTRUCT type */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE hMemBlock;    /* Handle to memory block       */
    lpMyPtr  ThisPtr;    /* Pointer to MYSTRUCT structure   */
    char szBuff[30];    /* buffer for message box       */

/* allocate space in global heap for a MYSTRUCT structure */
    hMemBlock = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
        (long)sizeof(MYSTRUCT));

/* if memory allocated properly */
    if (hMemBlock != NULL)
  {
  MessageBox(NULL,(LPSTR)"The memory was allocated properly",
      (LPSTR)" ",MB_OK);

  /* lock memory into current address */
  ThisPtr = (lpMyPtr)GlobalLock(hMemBlock);

  /* if lock worked */
  if (ThisPtr != NULL)
      {
      /* use memory from global heap and output results*/
      ThisPtr->x = 4;
      ThisPtr->y = 4;
      ThisPtr->x = ThisPtr->x*ThisPtr->y;
      sprintf(szBuff,"ThisPtr->x * ThisPtr->y = %d",ThisPtr->x);
      MessageBox(NULL,(LPSTR)szBuff,
          (LPSTR)"Info from GlobalAlloc'ed memory",
          MB_OK);
      GlobalUnlock(hMemBlock);  /* unlock block */
      GlobalFree(hMemBlock);  /* free block  */
      }
  else ;
  }
    else
  MessageBox(NULL,(LPSTR)"The memory was not allocated",
      (LPSTR)" ",MB_OK);
    return 0;
}


GLOBCMPC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBCMPC.C

/*
 *   GlobalCompact
 *   globcmpc.c, jeffst, v1.00, 22-Sept-1987
 *
 *   This program demonstrates the use of the GlobalCompact function. The
 *   GlobalCompact function compacts the global heap. GlobalCompact was
 *   called from WinMain in this sample application.
 *
 *   Microsoft Product Support Services
 *   Windows Version 2.0 function demonstration application
 *   Copyright (c) Microsoft 1987
 *
 */

#include "windows.h"

int sprintf();

typedef struct {
    int x;
    int y;
         } MYSTRUCT;
typedef MYSTRUCT far *lpMyPtr;

typedef struct {
    char smallstruct[2];
         } SMALLSTRUCT;
typedef struct {
    char bigstruct[20000];
         } BIGSTRUCT;

typedef BIGSTRUCT far *lpBIGPtr;
typedef SMALLSTRUCT far *lpSMALLPtr;


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE    hMemBlock1;    /* Handle to memory block */
    HANDLE    hMemBlock2;    /* Handle to memory block */
    lpMyPtr    ThisPtr;    /* Pointer to myStruct    */
    lpBIGPtr    HugePtr;
    lpSMALLPtr    MiniPtr;
    char szBuff[50];
    DWORD ContigFreeBytes;

/* GlobalCompact to ask for FFFF continguous bytes */
    ContigFreeBytes = (DWORD)GlobalCompact((DWORD)-1);
    sprintf(szBuff,"Number of contiguous free bytes before allocation = %lu",
                  ContigFreeBytes);
    MessageBox(NULL,(LPSTR)szBuff,(LPSTR)" ",MB_OK);

/* Allocate 2 bytes from global heap */
    hMemBlock1 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DISCARDABLE
        (long)sizeof(SMALLSTRUCT));
/* if block allocated properly */
    if (hMemBlock1 != NULL)
  /* lock block into memory */
  MiniPtr = (lpSMALLPtr)GlobalLock(hMemBlock1);

/* ask for FFFF contiguous free bytes */
    ContigFreeBytes = (DWORD)GlobalCompact((DWORD)-1);
    sprintf(szBuff,"Number of contiguous free bytes = %lu",ContigFreeBytes);
    MessageBox(NULL,(LPSTR)szBuff,(LPSTR)"After allocating 2 bytes...",MB_OK)

/* Allocate 50000 bytes from global heap */
    hMemBlock2 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE |GMEM_DISCARDABLE,
        (long)sizeof(BIGSTRUCT));
/* if memory allocated properly */
    if (hMemBlock2 != NULL)
  /* lock block into memory */
  HugePtr = (lpBIGPtr)GlobalLock(hMemBlock2);

/* ask for FFFF contiguous free bytes */
    ContigFreeBytes = (DWORD)GlobalCompact((DWORD)-1);
    sprintf(szBuff,"Number of contiguous free bytes = %lu",ContigFreeBytes);
    MessageBox(NULL,(LPSTR)szBuff,(LPSTR)"After allocating 50000 bytes...",MB

    GlobalUnlock(hMemBlock2);    /* unlock the blocks */
    GlobalUnlock(hMemBlock1);    /*           */


/* ask for FFFF contiguous free bytes */
    ContigFreeBytes = (DWORD)GlobalCompact((DWORD)-1);
    sprintf(szBuff,"Number of contiguous free bytes = %lu",ContigFreeBytes);
    MessageBox(NULL,(LPSTR)szBuff,(LPSTR)"After unlocking 50000 bytes...",MB_


    return 0;
}


GLOBCOMP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBCOMP.C

/*

Function(s) demonstrated in this program: GlobalCompact

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function compacts global memory.

Additional Comments:

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "GlobComp.h"

HWND     hWndParent1;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About",
"     This is a sample application to demonstrate the\n\
use of the GlobalCompact Windows function.",

"Help Message",
"     This program uses the GlobalCompact Windows\n\
function to compact global memory.  Use the menu\n\
to invoke this function.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GlobComp" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "GlobalCompact",            /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 HDC         hDC;
 PAINTSTRUCT ps;
 static int  xClient, yClient;

 DWORD ContigFreeBytes;

 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_GLOBALCOMPACT:
               ContigFreeBytes = (DWORD)GlobalCompact((DWORD)0);
               sprintf(szOutputBuffer1, "%s%lu",
                 "Number of contiguous free bytes = ",
                 ContigFreeBytes);

               MessageBox(hWnd, szOutputBuffer1, "GlobalCompact", MB_OK);

               break;

          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}





GLOBDISC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBDISC.C

/*
 *   GlobalDiscard
 *   globdisc.c
 *
 *   This program demonstrates the use of the GlobalDiscard function.
 *   The GlobalDiscard function marks a block of memory for discarding.
 *   After GlobalDiscarding, to check if a block has really been discarded,
 *   try to GlobalLock. If the return value is NULL, then the block has
 *   been discarded.
 *
 */

#include "windows.h"

int sprintf();

typedef struct {     /* structure we are going */
    char x[50];   /* to allocate and lock  */
    int y;
         } MYSTRUCT;

typedef MYSTRUCT far *lpMyPtr;  /* far pointer to MYSTRUCT type */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE hMemBlock;    /* Handle to memory block       */
    lpMyPtr  ThisPtr;    /* Pointer to myStruct       */
    char szBuff[60];    /* buffer for message box       */
    HANDLE Discarded;    /* return value from GlobalDiscard */

    (DWORD)GlobalCompact((DWORD)-1);

/* allocate space in global heap for a MYSTRUCT structure */
    hMemBlock = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DISCARDABLE,
        (long)sizeof(MYSTRUCT));

/* if memory allocated properly */
    if (hMemBlock)
  {
  /* lock memory into current address */
  ThisPtr = (lpMyPtr)GlobalLock(hMemBlock);

  /* if lock worked */
  if (ThisPtr != NULL)
      {

        GlobalUnlock(hMemBlock);    /* unlock memory */

   /* mark hMemBlock for discarding */
        GlobalDiscard(hMemBlock);

   /* if GlobalLock works (meaning hMemBlock not discarded) */
      if ( (ThisPtr = (lpMyPtr)GlobalLock(hMemBlock)) != NULL)
    MessageBox(NULL,(LPSTR)"It has not been discarded",
        (LPSTR)" ",MB_OK);
      else
    MessageBox(NULL,(LPSTR)"It HAS been discarded",
        (LPSTR)"Before compaction...",MB_OK);
      GlobalCompact((DWORD)-1);

   /* if GlobalLock works (meaning hMemBlock not discarded) */
      if ((ThisPtr = (lpMyPtr)GlobalLock(hMemBlock)) != NULL)
    MessageBox(NULL,(LPSTR)"it has not been discarded",
        (LPSTR)"After compaction...",MB_OK);
      else
    MessageBox(NULL,(LPSTR)"it HAS been discarded",
        (LPSTR)"After compaction...",MB_OK);
      }
  }
    return 0;
}


GLOBFLAG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBFLAG.C

/*
 *   This program demonstrates the use of the GlobalFlags function. The
 *   GlobalFlags function returns information about the specified block
 *   of memory allocated in the Global heap. GlobalFlags was called from
 *   WinMain in this sample application.
 */

#include "windows.h"
#include <stdio.h>

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE hMemBlock;    /* Handle to memory block */
    char far *lpszMem;   /* Pointer to Double Word in Global Memory. */
    char szBuff[30];     /* buffer for message box */
    BOOL unlocked;       /* return value from GlobalUnlock */
    WORD FlagCall;       /* return value from GlobalFlags */

/* allocate space in global heap for MOVEABLE and DISDCARDABLE memory */
    MessageBox(GetFocus(), (LPSTR)"Obtaining Global Memory.",
               (LPSTR)"GlobalAlloc()", MB_OK);
    hMemBlock = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_DISCARDABLE,
                            (long)sizeof(DWORD));

/* if memory allocated properly */
    if (hMemBlock != NULL)
  {
  /* lock memory into current address */
  lpszMem = GlobalLock(hMemBlock);
  /* if lock worked */
  if (lpszMem != NULL)
      {
       MessageBox(GetFocus(), (LPSTR)"Locking Global Memory.",
                  (LPSTR)"GlobalLock()", MB_OK);
       FlagCall = GlobalFlags(hMemBlock);  /* get global flags */
       /* if discardable */
       if ((FlagCall & GMEM_DISCARDABLE))
          MessageBox(GetFocus(), (LPSTR)"This block is discardable.",
                     (LPSTR)"According to GlobalFlags()...", MB_OK);
       else
       MessageBox (GetFocus(), (LPSTR)"This block is NOT discardable.",
                   (LPSTR)"According to GlobalFlags()...", MB_OK);

       /* if lockcount 0 */
       if ((FlagCall & GMEM_LOCKCOUNT) == 0)
          MessageBox(GetFocus(),(LPSTR)"The lock count is 0.",
                     (LPSTR)"Before unlocking, according to GlobalFlags()..."
                     MB_OK);
       else
          MessageBox(GetFocus(),(LPSTR)"The lock count is NOT 0.",
                     (LPSTR)"Before unlocking, according to GlobalFlags()..."
                     MB_OK);

       MessageBox(GetFocus(), (LPSTR)"Unlocking Global Memory.",
                  (LPSTR)"GlobalUnlock()", MB_OK);
       unlocked = GlobalUnlock(hMemBlock);    /* unlock memory */
       FlagCall = GlobalFlags(hMemBlock);
       /* if lockcount 0 */
       if ((FlagCall & GMEM_LOCKCOUNT) == 0)
          {
          MessageBox(GetFocus(),(LPSTR)"The lock count is 0.",
                     (LPSTR)"After unlocking, According to GlobalFlags()...",
                     MB_OK);
          GlobalFree(hMemBlock);              /* free memory   */
          }
       else
          MessageBox(GetFocus(),(LPSTR)"The lock count is NOT 0.",
                     (LPSTR)"Before unlocking, according to GlobalFlags()..."
                     MB_OK);
       }
    else
       MessageBox(GetFocus(),(LPSTR)"The lock DID NOT work properly.",
                  (LPSTR)" ", MB_OK);
    }
    return 0;
}


GLOBFREE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBFREE.C

/*
 *   This program demonstrates the use of the GlobalFree function. The
 *   GlobalFree function frees memory allocated from the Global heap.
 *   GlobalFree returns NULL if the memory is free. GlobalFree was called
 *   from WinMain in this sample application.
 *
 */

#include "windows.h"

int sprintf();

typedef struct {     /* structure we are going */
      int x;         /* to allocate and lock   */
      int y;
        } MYSTRUCT;

typedef MYSTRUCT far *lpMyPtr;  /* far pointer to MYSTRUCT type */

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE hMemBlock;   /* Handle to memory block       */
    lpMyPtr  ThisPtr;   /* Pointer to myStruct          */
    char szBuff[30];     /* buffer for message box       */
    BOOL freed;         /* return value from GlobalFree */

    /* allocate space in global heap for a MYSTRUCT structure */
    hMemBlock = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
                            (long)sizeof(MYSTRUCT));

    /* if memory allocated properly */
    if (hMemBlock != NULL)
       {
       /* lock memory into current address */
       ThisPtr = (lpMyPtr)GlobalLock(hMemBlock);

    /* if lock worked */
    if (ThisPtr != NULL)
       {
       /* use memory from global heap and output results*/
       ThisPtr->x = 4;
       ThisPtr->y = 4;
       ThisPtr->x = ThisPtr->x*ThisPtr->y;
       sprintf(szBuff,"ThisPtr->x * ThisPtr->y = %d",ThisPtr->x);
       MessageBox(GetFocus(),(LPSTR)szBuff,
                   (LPSTR)"Info from GlobalAlloc'ed memory",
                   MB_OK);
       GlobalUnlock(hMemBlock);        /* unlock memory */

       freed = GlobalFree(hMemBlock);    /* free memory */
       if (!freed)  /* if memory freed */
       MessageBox(GetFocus(),(LPSTR)"The memory was freed properly",
                 (LPSTR)" ",MB_OK);
       else      /* if memory not freed */
       MessageBox(GetFocus(),(LPSTR)"The memory WAS NOT freed",
                  (LPSTR)" ",MB_OK);
       }
   }
    return 0;
}


GLOBHAND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBHAND.C

/*
 *   GlobalHandle
 *   globlock.c
 *
 *   This program demonstrates the use of the GlobalHandle function. The
 *   GlobalHandle function returns the handle of the specified global
 *   memory block. GlobalHandle is called from WinMain in this sample
 *   application.
 *
 */

#include "windows.h"
 "dos.h"    /* FP_SEG located in dos.h */

int sprintf();

typedef struct {    /* structure we are going */
    int x;    /* to allocate and lock   */
    int y;
         } MYSTRUCT;

typedef MYSTRUCT far *lpMyPtr;  /* far pointer to MYSTRUCT type */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE hMemBlock1;  /* Handle to memory block */
    DWORD hMemBlock2;   /* Handle to memory block returned from GlobalHandle
    lpMyPtr  FirstPtr;  /* Pointer to MYSTRUCT structure */
    char szBuff[30];  /* buffer for message box   */

/* allocate space in global heap for a MYSTRUCT structure */
    hMemBlock1 = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
        (long)sizeof(MYSTRUCT));

/* if memory allocated properly */
    if (hMemBlock1 != NULL)
  {

  /* lock memory into current address */
  FirstPtr = (lpMyPtr)GlobalLock(hMemBlock1);

  /* if lock worked */
  if (FirstPtr != NULL)
      {
      /* get handle of segment pointed to by FirstPtr */
      hMemBlock2 = GlobalHandle(FP_SEG(FirstPtr));

      /* if GlobalHandle returned original handle */
      if ((HANDLE)hMemBlock2 == hMemBlock1)
         MessageBox(NULL,(LPSTR)"DID return the correct handle",
             (LPSTR)"GlobalHandle...",MB_OK);
      else
         MessageBox(NULL,(LPSTR)"DID NOT return the correct handle",
             (LPSTR)"GlobalHandle...",MB_OK);

      GlobalUnlock(hMemBlock1);   /* unlock memory */
      GlobalFree(hMemBlock1);   /* free memory   */
      }
  else
      MessageBox(NULL,(LPSTR)"The lock DID NOT work properly",
           (LPSTR)" ",MB_OK);
  }
    return 0;
}


GLOBLOCK.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBLOCK.C

/*
Function(s) demonstrated in this program: GlobalLock
Compiler version: 5.10
Description: When the right mouse button is clicked, this program will
       attempt to allocate and lock a small block of global memory.
       As a check, an arithmetic operation is performed on data
       stored in this global memory.
*/

#include <windows.h>
#include <stdio.h>

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

typedef struct {     /* structure we are going */
          int x;     /* to allocate and lock   */
          int y;
          } MYSTRUCT;

typedef MYSTRUCT far *lpMyPtr;   /* far pointer to MYSTRUCT type */

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       nCmdShow;
{
   static char szAppName [] = "globlock";
   HWND     hWnd;
   WNDCLASS wndclass;
   MSG      msg;

   if (!hPrevInstance)
      {
      wndclass.style          = CS_HREDRAW | CS_VREDRAW;
      wndclass.lpfnWndProc   = WndProc;
      wndclass.cbClsExtra    = 0;
      wndclass.cbWndExtra    = 0;
      wndclass.hInstance     = hInstance;
      wndclass.hIcon          = LoadIcon (NULL, IDI_APPLICATION);
      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
      wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
      wndclass.lpszMenuName  = NULL;
      wndclass.lpszClassName = szAppName;

      if (!RegisterClass (&wndclass))
         return FALSE;
      }

   hWnd = CreateWindow (szAppName,   /* window class name   */
                        "Using GlobalLock (Click the Right Mouse Button for D
                        WS_OVERLAPPEDWINDOW,  /* window style            */
                        CW_USEDEFAULT,        /* initial x position      */
                        0,                    /* initial y position      */
                        CW_USEDEFAULT,        /* initial x size          */
                        0,                    /* initial y size          */
                        NULL,                 /* parent window handle    */
                        NULL,                 /* window menu handle      */
                        hInstance,            /* program instance handle */
                        NULL);                /* create parameters       */

   ShowWindow (hWnd, nCmdShow);
   UpdateWindow (hWnd);

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

long FAR PASCAL WndProc(hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
{
    HANDLE  hMemBlock;    /* Handle to memory block */
    lpMyPtr  ThisPtr;    /* far pointer to MYSTRUCT structure */
    char  szBuff[150];    /* buffer for message box */

    switch(iMessage)
       {
       case WM_RBUTTONDOWN:
          {
          hMemBlock = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
                                  (long)sizeof(MYSTRUCT));

          /* if memory allocated properly */
          if (hMemBlock)
             {
             /* lock memory into current address */
             ThisPtr = (lpMyPtr)GlobalLock(hMemBlock);

             /* if lock worked */
             if (ThisPtr)
                {
                MessageBox(GetFocus(),
                           (LPSTR)"The lock worked properly",
                           (LPSTR)"GlobalLock",
                           MB_OK);
                /* use memory from global heap */
                ThisPtr->x = 4;
                ThisPtr->y = 4;
                ThisPtr->x = ThisPtr->x * ThisPtr->y;
                sprintf(szBuff, "%s%d", "The values referenced by these point
 in the global heap. \n\nThisPtr->x * ThisPtr->y = ", ThisPtr->x);
                MessageBox(GetFocus(), (LPSTR)szBuff,
                           (LPSTR)"Info from GlobalLock'ed memory", MB_OK);
                GlobalUnlock(hMemBlock);   /* unlock memory */
                GlobalFree(hMemBlock);     /* free memory   */
                }
             else
                {
                MessageBox(GetFocus(),
                           (LPSTR)"The lock DID NOT work properly",
                           (LPSTR)"GlobalLock", MB_OK);
                GlobalFree(hMemBlock);     /* free memory   */
                }
             }
          break;
          }
      case WM_DESTROY:
         {
         PostQuitMessage(0);
         break;
         }
      default:
         return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
   }
   return (0L);
}


GLOBREAL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBREAL.C

/*
 *   GlobalReAlloc
 *   globreal.c
 *
 *   This program demonstrates the use of the GlobalReAlloc function. The
 *   GlobalRealloc changes the size of the specified allocated memory block
 *   and returns a handle to the different size memory block. GlobalSize
 *   was called from WinMain in this sample application.
 *
 */

#include <windows.h>
#include <stdio.h>

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
    HANDLE hInstance, hPrevInstance;
    LPSTR lpszCmdLine;
    int cmdShow;
    {
    HANDLE hMemBlock;    /* Handle to memory block    */
    char szBuff[80];
    DWORD SizeMem;    /* holds sizes of memory blocks  */

    hMemBlock = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE, 200L);

    /* if memory allocated properly */
    if (hMemBlock)
  {
  MessageBox(NULL,"The memory was allocated properly",
       "GlobalAlloc",MB_OK);

  /* get the size of hMemBlock */
  SizeMem = GlobalSize(hMemBlock);
  sprintf(szBuff,"Size allocated = %lu",SizeMem);
  MessageBox(NULL, szBuff, "Before GlobalReAlloc...", MB_OK);

  hMemBlock = GlobalReAlloc(hMemBlock,    /* change the size of the */
          (DWORD)30,    /* allocated block to 30  */
          GMEM_MOVEABLE); /*     bytes      */
  if (hMemBlock)
      {
      SizeMem = GlobalSize(hMemBlock);
      sprintf(szBuff,"Size allocated = %lu",SizeMem);
      MessageBox(NULL, szBuff, "After GlobalReAlloc...",MB_OK);
      }
  else
      MessageBox(NULL, "GlobalReAlloc failed", "GlobaReAlloc",MB_OK);

  GlobalFree(hMemBlock);      /* free hMemblock */
  }
    return 0;
    }


GLOBSIZE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBSIZE.C

/*
 *   GlobalSize
 *
 *   This program demonstrates the use of the GlobalSize function. The
 *   GlobalSize function returns the size in bytes of the specified
 *   global memory block. GlobalSize was called from WinMain in this
 *   sample application.
 *
 */

#include <windows.h>
#include <stdio.h>

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE hMemBlock;    /* Handle to memory block      */
    char szBuff[ 40 ];    /* Local buffer for sprintf     */
    DWORD dwSizeMem;    /* holds sizes of memory blocks */

    hMemBlock = GlobalAlloc(GMEM_ZEROINIT | GMEM_NODISCARD, 400L );
         /* allocate space in global heap for a buffer */

    if ( hMemBlock != NULL )   /* if memory allocated properly */
    {
      dwSizeMem = GlobalSize( hMemBlock );
       /* Get the size of the block of memory  */
    sprintf( szBuff, "Size allocated = %lu", dwSizeMem);
    MessageBox( NULL, (LPSTR)szBuff, (LPSTR)"", MB_OK);
       /* Put size into string and output the string  */
      GlobalFree( hMemBlock );         /* free hMemblock */
    }

 return FALSE;
}


GLOBUNLK.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBUNLK.C

/*
 *   GlobalUnlock
 *
 *   This program demonstrates the use of the GlobalUnlock function. The
 *   GlobalUnlock function decrements the reference count of a block of
 *   memory allocated in the Global heap. GlobalUnlock returns zero if the
 *   reference count of the block is zero. GlobalUnlock was called from
 *   WinMain in this sample application.
 *
 */

#include "windows.h"

int sprintf();

typedef struct {    /* structure we are going */
    int x;    /* to allocate and lock   */
    int y;
         } MYSTRUCT;

typedef MYSTRUCT far *lpMyPtr;  /* far pointer to MYSTRUCT type */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE hMemBlock;    /* Handle to memory block */
    lpMyPtr  ThisPtr;    /* Pointer to myStruct    */
    char szBuff[30];    /* buffer for message box */
    BOOL unlocked;    /* return value from GlobalUnlock */

/* allocate space in global heap for a MYSTRUCT structure */
    hMemBlock = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
        (long)sizeof(MYSTRUCT));

/* if memory allocated properly */
    if (hMemBlock != NULL)
  {

  /* lock memory into current address */
  ThisPtr = (lpMyPtr)GlobalLock(hMemBlock);

  /* if lock worked */
  if (ThisPtr != NULL)
      {
      MessageBox(NULL,(LPSTR)"The lock worked properly",
           (LPSTR)" ",MB_OK);
      /* use memory from global heap and output results*/
      ThisPtr->x = 4;
      ThisPtr->y = 4;
      ThisPtr->x = ThisPtr->x*ThisPtr->y;
      sprintf(szBuff,"ThisPtr->x * ThisPtr->y = %d",ThisPtr->x);
      MessageBox(NULL,(LPSTR)szBuff,
          (LPSTR)"Info from GlobalLock'ed memory",
          MB_OK);

      /* unlock the block (decrement reference count) */
      unlocked = GlobalUnlock(hMemBlock);
      if (unlocked == 0)    /* if reference count == 0 */
    MessageBox (NULL,(LPSTR)"The block was properly unlocked",
         (LPSTR)" ",MB_OK);
      else    /* if (reference count != 0) */
    MessageBox (NULL,(LPSTR)"The block was NOT unlocked",
         (LPSTR)" ",MB_OK);

      GlobalFree(hMemBlock);  /* free memory   */
      }
  else
      MessageBox(NULL,(LPSTR)"The lock DID NOT work properly",
           (LPSTR)" ",MB_OK);
  }
    return 0;
}


GLOBUNWR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBUNWR.C

/*
 *   GlobalUnWire
 *   globwire.c
 *
 *   This program demonstrates the use of the GlobalUnWire function. The
 *   GlobalUnWire function unlocks a block that has been locked into low
 *   memory using the GlobalWire function. GlobalUnWire is called from
 *   WinMain in this sample application.
 *
 */

#include "windows.h"

int sprintf();

typedef struct {
    char smallstruct[20];
         } SMALLSTRUCT;        /* structure we're going to allocate */
            /*   space for    */
typedef SMALLSTRUCT far *lpSMALLPtr;  /* pointer to SMALLSTRUCT structure */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE    hMemBlock;   /* Handle to memory block       */
    lpSMALLPtr       ThisPtr;   /* Pointer to SMALLSTRUCT structure */
    char szBuff[50];     /* buffer for output         */

/* Allocate space for SMALLSTRUCT in global heap */
    hMemBlock = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
        (long)sizeof(SMALLSTRUCT));
/* if memory allocated properly */
    if (hMemBlock)
  /* GlobalWire the block into low memory */
  ThisPtr = (lpSMALLPtr)GlobalWire(hMemBlock);

/******************** GlobalUnwire the block *******************************/
    GlobalUnWire(hMemBlock);

    MessageBox(NULL,(LPSTR)"The block has been GlobalUnwire'ed",
        (LPSTR)" ",MB_OK);

/* Free the block */
    GlobalFree(hMemBlock);  /* free the block */

    return 0;
}


GLOBWIRE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\GLOBAL\GLOBWIRE.C

/*
 *   GlobalWire
 *   globwire.c
 *
 *   This program demonstrates the use of the GlobalWire function. The
 *   GlobalWire function locks a block into low memory. GlobalWire is
 *   called from WinMain in this sample application. GlobalWire is often
 *   used when a block is going to be locked in memory for a long time
 *   so there will be larger continuous free spaces than if GlobalLock was
 *   used. Before allocation  and after GlobalWire'ing, GlobalCompact is
 *   called to show the affect of locking the block in memory has on the
 *   largest continuous block
 *
 */

#include "windows.h"

int sprintf();

typedef struct {
    char smallstruct[20];
         } SMALLSTRUCT;        /* structure we're going to allocate */
            /*   space for    */
typedef SMALLSTRUCT far *lpSMALLPtr;  /* pointer to SMALLSTRUCT structure */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE     hMemBlock;       /* Handle to memory block    */
    lpSMALLPtr     ThisPtr;       /* Pointer to myStruct    */
    char     szBuff[80];       /* buffer for output    */
    DWORD     ContigFreeBytes;  /* return value from GlobalCompact */

/* Allocate space for SMALLSTRUCT in global heap */
    hMemBlock = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
        (long)sizeof(SMALLSTRUCT));
/* if memory allocated properly */
    if (hMemBlock)
  /* GlobalWire the block into low memory */
  ThisPtr = (lpSMALLPtr)GlobalWire(hMemBlock);
  if (ThisPtr == NULL)
      MessageBox(NULL,(LPSTR)"GlobalWire Failure",
          (LPSTR)" ",MB_OK);
  else
      MessageBox(NULL,(LPSTR)"GlobalWire worked properly",
          (LPSTR)" ",MB_OK);

/* GlobalUnwire the block */
    GlobalUnWire(hMemBlock);

/* Free the block */
    GlobalFree(hMemBlock);

    return 0;
}


GMENUITC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\GMENUITC.C

/*
 *
 *  GetMenuItemCount
 *
 *  This program demonstrates the use of the function GetMenuItemCount.
 *  This function determines the number of items in the menu identifed by
 *  the parameter.  This may be either a pop-up of top-level menu.
 *
 */

#include <windows.h>

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  static char szFileName[] = "gmenuitc";
  static char szFuncName[] = "GetMenuItemCount";
  HMENU hMenu;
  WORD wCount;
  char szBuff[80];

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) szFileName;
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) "GetMenuItemCountFunc";
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }

  hWnd = CreateWindow ( ( LPSTR ) szFileName, ( LPSTR ) szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      ( HWND ) NULL, ( HMENU ) NULL,
                      ( HANDLE ) hInstance, ( LPSTR ) NULL );

  ShowWindow ( hWnd , cmdShow );
  hMenu = GetMenu ( hWnd );

  MessageBox (NULL, (LPSTR)"Getting number of menu items", (LPSTR) szFuncName
     MB_OK);

  wCount = GetMenuItemCount ( hMenu );

  if ( wCount != -1 )
     {
     sprintf ( szBuff, "%s%d", "Number of menu items is ", wCount );
     MessageBox (NULL, (LPSTR) szBuff, (LPSTR) szFuncName, MB_OK);
     }
  else
     MessageBox (NULL, (LPSTR)"Error", (LPSTR) szFuncName,
        MB_OK|MB_ICONEXCLAMATION);

  return 0;
}


GMENUITI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\GMENUITI.C

/*
 *  GetMenuItemID
 *
 *  This program demonstrates the use of the function GetMenuItemID.
 *  This function
 *
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  static char szFileName[] = "gmenuiti";
  static char szFuncName[] = "GetMenuItemID";
  HMENU hMenu;
  WORD wID;
  char szBuff[80];

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) szFileName;
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) "GetMenuItemCountFunc";
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }

  hWnd = CreateWindow ( ( LPSTR ) szFileName, ( LPSTR ) szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      ( HWND ) NULL, ( HMENU ) NULL,
                      ( HANDLE ) hInstance, ( LPSTR ) NULL );

  ShowWindow ( hWnd , cmdShow );
  hMenu = GetMenu ( hWnd );

  MessageBox (NULL, (LPSTR)"Getting ID of menu item Before", (LPSTR) szFuncNa
     MB_OK);

  wID = GetMenuItemID ( hMenu, 0 );

  if ( wID != -1 )
     {
     sprintf ( szBuff, "%s%d", "ID of menu item Before is ", wID );
     MessageBox (NULL, (LPSTR) szBuff, (LPSTR) szFuncName, MB_OK);
     }
  else
     MessageBox (NULL, (LPSTR)"Error", (LPSTR) szFuncName,
        MB_OK|MB_ICONEXCLAMATION);

  return 0;
}


GMENUSTR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\GMENUSTR.C

/*
 *
 * GetMenuString
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  The WinMain proceeds to execute the GetMenuString function
 *  if the user selects the "GetMenuString" selection from the main menu bar.
 *  If the function call is successful, a message box is created which
 *  copies the menu string into a buffer.  The function is duplicated for
 *  use by position of the menu selection and by the resource ID.
 *
 */

#include "windows.h"
  IDM_TEST      100     /* ID of the Test menu.    */
  N_MAX_COUNT   14      /* Temporary buffer count. */
  SIZE_OUTBUFF  36      /* Output Buffer size.     */

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;
  HDC hDC;     /* Handle to the Display Context. */

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gmenustr";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon          = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)"TestMenu";            /* Load the menu. *
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gmenustr",
           (LPSTR) "GetMenuString",
           WS_OVERLAPPEDWINDOW,           /* Use overlapped window.   */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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


} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{
   char szbuf[N_MAX_COUNT];     /* Temp Buffer, stores results of function */
   char szoutbuf[SIZE_OUTBUFF]; /* Formatted output buffer for message Box */
   short int nCopied;           /* Number of characters copied, error chk  */

   switch (identifier) {                              /*******************/
    case WM_COMMAND:                                  /* Process the     */
       switch (wParam) {                              /* menu selections */
       case IDM_TEST:                                /* here.           */
           nCopied = GetMenuString(GetMenu(hWnd),     /* Get the string  */
                                   wParam,            /* of the menu and */
                                   (LPSTR) szbuf,     /* put it into a   */
                                   N_MAX_COUNT,       /* temporary buf-  */
                                   MF_BYCOMMAND);     /* fer by command. */
           if (nCopied == 0)                            /* If no charac- */
             {                                          /* ters were     */
             MessageBox(hWnd,                           /* copied, issue */
                        (LPSTR)"GetMenuString Failed!", /* an error in   */
                        (LPSTR)"ERROR!!!",              /* the form of a */
                        MB_OK | MB_ICONEXCLAMATION);    /* message box.  */
             break;
             }
           else                                       /* Otherwise, put  */
             {                                        /* a more meaning- */
             sprintf(szoutbuf,                        /* ful message in  */
                     "%s%s%s",                        /* a buffer for    */
                     "The Menu String is '",          /* the user to     */
                     szbuf,                           /* recognize.      */
                     "'");                            /* Then...         */
             MessageBox(hWnd,                         /* show the result */
                        (LPSTR)szoutbuf,              /* in a message    */
                        (LPSTR)"MF_BYCOMMAND",        /* box.            */
                        MB_OK);
             nCopied = GetMenuString(GetMenu(hWnd),   /* Now, get the    */
                                     0,               /* same string     */
                                     (LPSTR)szbuf,    /* from the same   */
                                     N_MAX_COUNT,     /* menu by using   */
                                     MF_BYPOSITION);  /* the position of */
             if (nCopied == 0)                        /* the menu.       */
                {                                     /* If no charac-   */
                MessageBox(hWnd,                      /* ters were       */
                           (LPSTR)"GetMenuString Failed!", /* found,     */
                           (LPSTR)"MF_BYPOSITION",         /* issue an   */
                           MB_OK | MB_ICONEXCLAMATION);    /* error in a */
                break;                                /* message box.    */
                }
             else                                     /* Finally,        */
                {                                     /* display the     */
                sprintf(szoutbuf,                     /* results of the  */
                        "%s%s%s",                     /* GetMenuString   */
                        "The Menu String is '",       /* using position  */
                        szbuf,                        /* rather than ID. */
                        "'");                         /* But put it in a */
                MessageBox(hWnd,                      /* form which is   */
                           (LPSTR)szoutbuf,           /* more pleasing   */
                           (LPSTR)"MF_BYPOSITION",    /* to the user.    */
                           MB_OK);                    /*******************/
                };
            break;
             }
       }

    default:
       return(DefWindowProc(hWnd, identifier, wParam, lParam));
       break;

   }

   return(0L);

}


GMESSPOS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MOUSE\GMESSPOS.C

/*
 *
 * GetMessagePos
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  If the user proceeds to close the window, the GetMessagePos
 *  function is executed.  The mouse coordinates are then displayed on
 *  the screen in a message box before the window is actually closed and
 *  destroyed.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gmesspos";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, (LPSTR)"simpleton");
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style        = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gmesspos",
           (LPSTR) "GetMessagePos",
           WS_OVERLAPPEDWINDOW,         /* Use overlapped window.   */
           CW_USEDEFAULT,               /* Use default coordinates. */
           CW_USEDEFAULT,               /* Use default coordinates. */
           CW_USEDEFAULT,               /* Use default coordinates. */
           CW_USEDEFAULT,               /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{

   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);       /* Paint a window  */
       SetMapMode(hDC, MM_ANISOTROPIC);                /* which will tell */
       SetWindowOrg(hDC, 0, 0);                        /* the user to     */
       SetWindowExt(hDC, 110, 110);                    /* double click    */
       GetClientRect(hWnd, (LPRECT)&rRect);            /* the right mouse */
       SetViewportOrg(hDC, 0, 0);                      /* button to con-  */
       SetViewportExt(hDC, rRect.right, rRect.bottom); /* the test.       */
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button to Conduct Test.",
                48, (LPRECT)&rRect, DT_SINGLELINE);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);

    }
      break;

    case WM_RBUTTONDBLCLK: {                  /* If the user double       */
                                              /*  clicks the right        */
       char szbuf[32];                        /*  mouse button, then      */
       unsigned long ptPos;                   /*  an output buffer is     */
       POINT point;                           /*  allocated along with    */
                                              /*  a pointer to a position */
       ptPos = GetMessagePos();               /*  and a point.  The fn    */
      point = MAKEPOINT(ptPos);              /*  GetMessagePos is exec-  */
      sprintf(szbuf,                         /*  uted and the mouse      */
               "%s%d%s%d%s",                  /*  position is printed in  */
               "The Mouse Position is ",      /*  a messge box.           */
              point.x, ",", point.y, ".");
      MessageBox(hWnd,
                  (LPSTR)szbuf,
                  (LPSTR)"GetMessagePos",
                 MB_OK);
       }
       break;

    case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


GMESSTIM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\GMESSTIM.C

/*
 *
 * GetMessageTime
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  If the user proceeds to close the window, the GetMessagePos
 *  function is executed.  The time (in milliseconds) since the last
 *  are then displayed on the screen in a message box before the window
 *  is actually closed and destroyed.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gmesstim";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;       /* Add double click capabilities. */
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gmesstim",
           (LPSTR) "GetMessageTime",       /* Create a window.         */
           WS_OVERLAPPEDWINDOW,            /* Make it overlapped.      */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{

   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button To Conduct Test.",
                48, (LPRECT)&rRect, DT_SINGLELINE);  /* Place text to    */
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);          /* prompt for test. */

    }
      break;

     case WM_RBUTTONDBLCLK:                    /* If the user double   */
       {                                       /* clicks on the right  */
       char szbuf[40];   /* Output buffer       | mouse button, then   */
       long lTime;   /* Time since last message | establish needed     */
                                               /* variables and call   */
       lTime = GetMessageTime();               /* the GetMessageTime   */
      sprintf(szbuf,                          /* function.  Capture   */
               "%s%ld%s\0",                    /* the time information */
               "Time Since Last Message is ",  /* in a zero terminated */
              lTime,                          /* buffer.              */
               ".");
      MessageBox(hWnd,                        /* Output the buffer in */
                  (LPSTR)szbuf,                /* a message box format */
                  (LPSTR)"GetMessageTime",     /* so that the user can */
                 MB_OK);                      /* have a readable and  */
       }                                       /* useful format.       */
       break;

     case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


GMETAFB.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\GMETAFB.C

/*
 *  This program demonstrates the use of the function GetMetaFileBits.
 *  This function returns a handle to a global memory block containing the
 *  specified metafile as a collection of bits.
 */

#include <windows.h>

static HANDLE hWnd;
HANDLE hMem;

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  static char szFuncName[] = "GetMetaFileBits()";
  char szOutBuf[40];
  HANDLE hMF;
  HANDLE hMetaDC;

  MessageBox(GetFocus(), (LPSTR)"Creating Memory Metafile",
             (LPSTR)"CretaeMetaFile()", MB_OK);
  hMetaDC = CreateMetaFile(NULL);
  if (hMetaDC == NULL)
     MessageBox(GetFocus(), (LPSTR)"Error in Creating Memory Metafile",
                (LPSTR)"CreateMetaFile() Error!", MB_OK | MB_ICONEXCLAMATION)
  else {
     Rectangle(hMetaDC, 10, 10, 200, 200);
     Rectangle(hMetaDC, 201, 10, 401, 200);
     LineTo(hMetaDC, 100, 250);
     Ellipse(hMetaDC, 0, 0, 100, 100);
     hMF = CloseMetaFile(hMetaDC);
     MessageBox (GetFocus(),
                 (LPSTR)"Getting Handle to Metafile Bits",
                 (LPSTR)szFuncName, MB_OK);
     hMem = GetMetaFileBits(hMF);
     if (hMem == NULL)
        MessageBox (GetFocus(), (LPSTR)"Error in Obtaining Metafile Bit Handl
                    (LPSTR)szFuncName, MB_OK);
     else {
        MessageBox (GetFocus(), (LPSTR)"Handle Obtained Successfully",
                    (LPSTR)szFuncName, MB_OK);
        if (GlobalSize(hMem) != 0) {
           sprintf(szOutBuf, "%s%lu%s", "The Size of the Metafile is: ",
                   GlobalSize(hMem), " bytes.");
           MessageBox(GetFocus(), (LPSTR)szOutBuf, (LPSTR)"GlobalSize()", MB_
           }
        else
           MessageBox(GetFocus(), (LPSTR)"Error in Obtaining the Size of the
                      (LPSTR)"GlobalSize", MB_OK);
        }
     }
  return 0;
}


GMETAFIL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\GMETAFIL.C

/*
 *
 *  GetMetaFile
 *
 *  This program demonstrates the use of the function GetMetaFile.
 *  This function creates a handle for the metafile named by the parameter.
 *
 */

#include <windows.h>

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  static char szFileName[] = "gmetafil";
  static char szFuncName[] = "GetMetaFile";
  HDC hDC;
  HANDLE hMF;

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) szFileName;
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) "GetMenuFunc";
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }

  hWnd = CreateWindow ( ( LPSTR ) szFileName, ( LPSTR ) szFuncName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      ( HWND ) NULL, ( HWND ) NULL,
                      ( HANDLE ) hInstance, ( LPSTR ) NULL );

  ShowWindow ( hWnd , cmdShow );
  hDC = GetDC ( hWnd );

  MessageBox (NULL, (LPSTR)"Getting handle to metafile", (LPSTR) szFuncName,
     MB_OK);

  hMF = GetMetaFile ( (LPSTR) "GMETAFIL.MET" );

  if ( hMF != NULL )
     MessageBox (NULL, (LPSTR)"Metafile handle gotten", (LPSTR) szFuncName,
        MB_OK);
  else
     MessageBox (NULL, (LPSTR)"Metafile handle not gotten", (LPSTR) szFuncNam
        MB_OK);

  PlayMetaFile ( hDC, hMF );
  MessageBox (NULL, (LPSTR)"This is the metafile", (LPSTR) szFuncName, MB_OK)
  ReleaseDC ( hWnd, hDC);
  return 0;
}


GMNUSTAT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\GMNUSTAT.C

/*
 *
 * GetMenuState
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  When the user executes the "Test" menu selection, the
 *  state of the popup menu selection "Item 2", in the "GetMenuState"
 *  menu, is verified as "CHECKED" in a message box.  Otherwise, an
 *  error message is issued, also in the form of a message box.
 *
 */

#include "windows.h"
  IDM_TEST       100  /* ID of the Test menu.                */
  IDM_ITEM2      102  /* ID of Item 2.                       */
  IDM_GETMENUPOS   1  /* Position of the GetMenuState Popup. */
  SIZE_OUTBUFF    80  /* Output Buffer size.                 */

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;
  HDC hDC;     /* Handle to the Display Context. */

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gmnustat";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon          = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)"TestMenu";            /* Load the menu. *
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gmnustat",
           (LPSTR) "GetMenuState",
           WS_OVERLAPPEDWINDOW,           /* Use overlapped window.   */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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


} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{
   char szoutbuf[SIZE_OUTBUFF]; /* Formatted output buffer for message Box */
   WORD wMState;                /* The WORD state of the menu selection.   */

   switch (identifier) {                              /*******************/
    case WM_COMMAND:                                  /* Process the     */
       switch (wParam) {                              /* menu selections */
       case IDM_TEST:                                /* here.           */
           wMState = GetMenuState(GetSubMenu(GetMenu(hWnd),
                                             IDM_GETMENUPOS),
                                  IDM_ITEM2,          /* Get the number  */
                                  MF_BYCOMMAND);      /* of the menu     */
                                                      /* a temp buffer.  */
           if (wMState == NULL)                       /* If the menu    */
             {                                          /* does not      */
             MessageBox(hWnd,                           /* exist, issue  */
                        (LPSTR)"Menu Does Not Exist!",  /* an error in   */
                        (LPSTR)"ERROR!!!",              /* the form of a */
                        MB_OK | MB_ICONEXCLAMATION);    /* message box.  */
             break;
             }
           else                                       /* Otherwise, put  */
             {                                        /* a more meaning- */
             if (wMState && MF_CHECKED != 0)
                {
                sprintf(szoutbuf,                        /* ful message in  *
                        "%s%s",                       /* a buffer for    */
                        "The State of GetMenuState ", /* the user to     */
                        "(Item 2) is CHECKED.");      /* recognize.      */
                MessageBox(hWnd,                      /* Then...         */
                           (LPSTR)szoutbuf,           /* show the result */
                           (LPSTR)"GetMenuState",     /* in a message    */
                           MB_OK);                    /* box.            */
                }
             else
                {
                sprintf(szoutbuf,
                        "%s%s",
                        "The State of GetMenuState ",
                        "(Item 2) is UNCHECKED.");
                MessageBox(hWnd,
                           (LPSTR)szoutbuf,
                           (LPSTR)"GetMenuState",
                           MB_OK);
                }
            break;
             }
       }

    default:
       return(DefWindowProc(hWnd, identifier, wParam, lParam));
       break;

   }

   return(0L);

}


GNEARCLR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GNEARCLR.C

/*
 * This example demonstrates the use of GetNearestColor(). This example
 * begins with the main menu selection where the user enters RGB values
 * into a dialog box. These values are used to compute the nearest
 * color and displayed in a message box. This loop continues until the
 * user chooses the "Done" selection.
 *
 */

#include "windows.h"
#include <stdio.h>
#include "gnearclr.h"

/* Global Variables */
static HANDLE hInst;
FARPROC lpprocColor;

/* Forward References */
long FAR PASCAL NearestWndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL ColorDlg(HWND, unsigned, WORD, LONG);

/* Color Dialog Function */
BOOL FAR PASCAL ColorDlg(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
   char szOutBuf[80];      /* Output Buffer for Message Box    */
   unsigned uiRValue;      /* Edit Input for Red Value         */
   unsigned uiGValue;      /* Edit Input for Green Value       */
   unsigned uiBValue;      /* Edit Input for Blue Value        */
   BOOL bSuccess;          /* Flag if All Edit Values are Good */
   DWORD dwrgbValue;       /* RGB Value of Nearest Color       */
   HDC hDC;                /* Display Context of Dialog Box    */
   BOOL bReceived;         /* Flag if Edit Received Set Value  */

   switch (message) {
      case WM_COMMAND:
         switch (wParam) {
            case ID_DONE:  /* If all done, quit the dialog box */
               EndDialog(hDlg, TRUE);
               return TRUE;

            case ID_MYOK:  /* If ready to accept dialog values */
               /* Innocent until proven guilty */
               bSuccess = TRUE;
               /* Get all of the edit values and check them for range */
               uiRValue = GetDlgItemInt(hDlg, ID_REDIT,
                                        (BOOL FAR *)&bReceived, NULL);
               if ((bReceived == NULL) || (uiRValue > 255) ||
                   (uiRValue < 0))
                  {
                  MessageBox(hDlg, (LPSTR)"Invalid Red Value",
                             (LPSTR)"Range Error (0-255)!", MB_OK);
                  bSuccess = FALSE;
                  }
               uiGValue = GetDlgItemInt(hDlg, ID_GEDIT,
                                        (BOOL FAR *)&bReceived, NULL);
               if ((bReceived == NULL) || (uiGValue > 255) ||
                   (uiGValue < 0))
                  {
                  MessageBox(hDlg, (LPSTR)"Invalid Green Value",
                             (LPSTR)"Range Error (0-255)!", MB_OK);
                  bSuccess = FALSE;
                  }
               uiBValue = GetDlgItemInt(hDlg, ID_BEDIT,
                                        (BOOL FAR *)&bReceived, NULL);
               if ((bReceived == NULL) || (uiBValue > 255) ||
                   (uiBValue < 0))
                  {
                  MessageBox(hDlg, (LPSTR)"Invalid Blue Value",
                             (LPSTR)"Range Error (0-255)!", MB_OK);
                  bSuccess = FALSE;
                  }
               if (bSuccess) { /* If all are OK, continue */
                  /* Get the DC and get the nearest color of the user's
                     input. */
                  hDC = GetDC(hDlg);
                  dwrgbValue = GetNearestColor(hDC, RGB((BYTE)uiRValue,
                                                        (BYTE)uiGValue,
                                                        (BYTE)uiBValue)
                                              );
                  ReleaseDC(hDlg, hDC);
                  sprintf(szOutBuf, "%s%d%s%d%s%d%s",
                          "The Nearest Color is: (",
                          GetRValue(dwrgbValue),
                          " , ", GetGValue(dwrgbValue),
                          " , ", GetBValue(dwrgbValue), ").");
                  /* Print a message box and set the focus back so that
                     the user can enter values at will in a loop. */
                  MessageBox(hDlg, (LPSTR)szOutBuf,
                             (LPSTR)"GetNearestColor()", MB_OK);
                  }
               SetFocus(GetDlgItem(hDlg, ID_REDIT));
               SendMessage(GetDlgItem(hDlg, ID_REDIT), EM_SETSEL, NULL,
                           MAKELONG((WORD)0, (WORD)32767));
               return TRUE;

            default:
               return FALSE;
            };
         break;

      case WM_INITDIALOG:
         /* When the box first comes up, limit the text for each
            numeric value to three digits so that the user is
            less likely to enter an erroneus value. */
         SendMessage(GetDlgItem(hDlg, ID_REDIT), EM_LIMITTEXT,
                     (WORD)3, (LONG)NULL);
         SendMessage(GetDlgItem(hDlg, ID_GEDIT), EM_LIMITTEXT,
                     (WORD)3, (LONG)NULL);
         SendMessage(GetDlgItem(hDlg, ID_BEDIT), EM_LIMITTEXT,
                     (WORD)3, (LONG)NULL);
         /* Intialize all of the edit controls to zero. */
         SetDlgItemInt(hDlg, ID_REDIT, (unsigned)0, NULL);
         SetDlgItemInt(hDlg, ID_GEDIT, (unsigned)0, NULL);
         SetDlgItemInt(hDlg, ID_BEDIT, (unsigned)0, NULL);
         SetFocus(GetDlgItem(hDlg, ID_REDIT));
         SendMessage(GetDlgItem(hDlg, ID_REDIT), EM_SETSEL, NULL,
                     MAKELONG((WORD)0, (WORD)32767));
         return FALSE;

      default:
         return FALSE;
      }
}


int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG       msg;
    HWND      hWnd;
    PWNDCLASS pNearClass;

    if (!hPrevInstance) {
       pNearClass = (PWNDCLASS)LocalAlloc(LPTR, sizeof(WNDCLASS));

       pNearClass->hCursor        = LoadCursor(NULL, IDC_ARROW);
       pNearClass->hIcon          = NULL;
       pNearClass->lpszMenuName   = (LPSTR)"NearMenu";
       pNearClass->lpszClassName  = (LPSTR)"gnearclr";
       pNearClass->hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
       pNearClass->hInstance      = hInstance;
       pNearClass->style          = CS_HREDRAW | CS_VREDRAW;
       pNearClass->lpfnWndProc    = NearestWndProc;

       if (!RegisterClass((LPWNDCLASS)pNearClass))
           /* Initialization failed.
            * Windows will automatically deallocate all allocated memory.
            */
           return FALSE;

       LocalFree((HANDLE)pNearClass);
        }

    hWnd = CreateWindow((LPSTR)"gnearclr",
                        (LPSTR)"GetNearestColor() Demo",
                        WS_TILEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL);      /* no params to pass on */

    /* Save instance handle for DialogBox */
    hInst = hInstance;

    /* Bind callback function with module instance */
    lpprocColor = MakeProcInstance((FARPROC)ColorDlg, hInstance);

    /* Make window visible according to the way the app is activated */
    ShowWindow(hWnd, cmdShow);
    UpdateWindow(hWnd);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL NearestWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_COMMAND:
        switch (wParam)
        {
        case ID_NEAR:
           /* Let 'er rip. */
            DialogBox(hInst, MAKEINTRESOURCE(NEARBOX), hWnd, lpprocColor);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
        break;
    }
    return(0L);
}


GNEXTITM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\GNEXTITM.C

/*
 * This application demonstrates the use of GetNextDlgGroupItem() and
 * GetNextDlgTabItem(). In the dialog box, choosing the radiobutton
 * and selecting the direction and the "NextTab" or "NextGroup" push
 * button will change the focus to the next repsective item -- depending
 * upon whether the previous flag and the "Tab" or "Group" selection.
 *
 */

#include "windows.h"
#include "gnextitm.h"

/* Global Variables */
static HANDLE hInst;       /* Instance handle for dialog box.          */
FARPROC       lpprocNext;  /* Long pointer to dialog procedure.        */
HWND          hGrpCurrent; /* Handle to the current group push button. */
HWND          hTabCurrent; /* Handle to the current tab push button.   */
BOOL          bDirCurrent; /* Current direction to get the next item.  */

/* Forward References */
long FAR PASCAL NextWndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL NextItem(HWND, unsigned, WORD, LONG);

/* Dialog Procedure */
BOOL FAR PASCAL NextItem(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
   HWND hGNextItem; /* Next Group Item */
   HWND hTNextItem; /* Next Tab Item   */
   int  i;          /* Counter         */

   switch (message) {
      case WM_COMMAND:
         switch (wParam) {
            case ID_DONE: /* If all done, quit */
               EndDialog(hDlg, TRUE);
               return TRUE;

            case ID_DIRECTION: /* Change the "Previous" flag for direction */
               if (bDirCurrent == TRUE)
                  bDirCurrent = FALSE;
               else
                  bDirCurrent = TRUE;
               return TRUE;

            case ID_TABFRST: /* Manually set the tab button focus */
            case ID_TABSEC:
            case ID_TABTHRD:
               CheckRadioButton(hDlg, ID_TABFRST,
                                ID_TABTHRD, wParam);
               hTabCurrent = GetDlgItem(hDlg, wParam);
               return TRUE;

            case ID_GRPFRST: /* Manually set the group button focus */
            case ID_GRPSEC:
            case ID_GRPTHRD:
               CheckRadioButton(hDlg, ID_GRPFRST,
                                ID_GRPTHRD, wParam);
               hGrpCurrent = GetDlgItem(hDlg, wParam);
               return TRUE;

            case ID_NEXTTAB: /* Get the next tab item */
               /* The first two cases are needed because the dialog
                  manager does neat things with tabs. */
               if ((hTabCurrent == GetDlgItem(hDlg, ID_TABFRST)) &&
                   (bDirCurrent == TRUE)) {
                   CheckRadioButton(hDlg, ID_TABFRST,
                                    ID_TABTHRD, ID_TABTHRD);
                   hTabCurrent = GetDlgItem(hDlg, ID_TABTHRD);
                   }
               else if ((hTabCurrent == GetDlgItem(hDlg, ID_TABTHRD)) &&
                        (bDirCurrent == FALSE)) {
                   CheckRadioButton(hDlg, ID_TABFRST,
                                    ID_TABTHRD, ID_TABFRST);
                   hTabCurrent = GetDlgItem(hDlg, ID_TABFRST);
                   }
               else { /* Finally, you can do things properly */
                  hTNextItem = GetNextDlgGroupItem(hDlg,
                                                  hTabCurrent,
                                                  bDirCurrent);
                  hTabCurrent = hTNextItem;
                  for (i = ID_TABFRST; i <= ID_TABTHRD; i = i + 25)
                     if (GetDlgItem(hDlg, i) == hTabCurrent)
                        CheckRadioButton(hDlg, ID_TABFRST,
                                         ID_TABTHRD, i);
                  }
               return TRUE;

            case ID_NEXTGROUP: /* Groups are much neater to implement */
               hGNextItem = GetNextDlgGroupItem(hDlg,
                                               hGrpCurrent,
                                               bDirCurrent);
               hGrpCurrent = hGNextItem;
               for (i = ID_GRPFRST; i <= ID_GRPTHRD; i = i + 25)
                  if (GetDlgItem(hDlg, i) == hGrpCurrent)
                     CheckRadioButton(hDlg, ID_GRPFRST,
                                      ID_GRPTHRD, i);
               return TRUE;

            default:
               return FALSE;
            }

      case WM_INITDIALOG: /* Initalize everything */
         hTabCurrent = GetDlgItem(hDlg, ID_TABFRST);
         CheckRadioButton(hDlg, ID_TABFRST, ID_TABTHRD, ID_TABFRST);
         hGrpCurrent = GetDlgItem(hDlg, ID_GRPFRST);
         CheckRadioButton(hDlg, ID_GRPFRST, ID_GRPTHRD, ID_GRPFRST);
         bDirCurrent = FALSE;
         CheckDlgButton(hDlg, ID_DIRECTION, bDirCurrent);
         SetFocus(GetDlgItem(hDlg, ID_DONE));
         return FALSE;

      default:
         return FALSE;
      }
}

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance) {
       PWNDCLASS   pNextClass;

       pNextClass = (PWNDCLASS)LocalAlloc(LPTR, sizeof(WNDCLASS));

       pNextClass->hCursor        = LoadCursor(NULL, IDC_ARROW);
       pNextClass->hIcon          = (HANDLE)NULL;
       pNextClass->lpszMenuName   = (LPSTR)"NextMenu";
       pNextClass->lpszClassName  = (LPSTR)"gnextitm";
       pNextClass->hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
       pNextClass->hInstance      = hInstance;
       pNextClass->style          = CS_HREDRAW | CS_VREDRAW;
       pNextClass->lpfnWndProc    = NextWndProc;

       if (!RegisterClass((LPWNDCLASS)pNextClass))
           /* Initialization failed.
            * Windows will automatically deallocate all allocated memory.
            */
           return FALSE;

       LocalFree((HANDLE)pNextClass);
       }

    hWnd = CreateWindow((LPSTR)"gnextitm",
                        (LPSTR)"GetNextDlgTabItem() & GetNextDlgGroupItem() D
                        WS_TILEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent                 */
                        (HMENU)NULL,       /* use class menu            */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL);      /* no params to pass on      */

    /* Save instance handle for DialogBox */
    hInst = hInstance;

    /* Bind callback function with module instance */
    lpprocNext = MakeProcInstance((FARPROC)NextItem, hInstance);

    /* Make window visible according to the way the app is activated */
    ShowWindow(hWnd, cmdShow);
    UpdateWindow(hWnd);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL NextWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message)
    {
    case WM_COMMAND:
        switch (wParam)
        {
        case ID_NEXTBOX: /* Go for it! */
            DialogBox(hInst, MAKEINTRESOURCE(NEXTBOX), hWnd, lpprocNext);
            break;

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

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
        break;
    }
    return(0L);
}


GNEXTWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\GNEXTWIN.C

/*
 *
 *   gnextwin.c
 *
 *   This program demonstrates the use of the GetNextWindow() function.
 *   GetNextWindow() searches for a handle that identifies the next (or
 *   previous window, depending on the second parameter) in the window-
 *   manager's list. GetNextWindow() is called from WinMain() in this
 *   application, and if a non-null handle is returned, CloseWindow() is
 *   is called to make the window whose handle was returned iconic. If
 *   this application's window is not the active window, but no other
 *   window is over it, then that may mean the previous window is the
 *   blank window that you see in the background.
 *
 */

#include "windows.h"

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon          = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"GetNextWindow";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;
    HWND  hNextWindow;   /*** return value from GetNextWindow() ***/

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"GetNextWindow",
                        (LPSTR)"GetNextWindow()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    MessageBox(NULL,
               (LPSTR)"     If a non-null handle is returned, the window\n\
corresponding to this handle is brought to the\n\
top.",
               (LPSTR)"This application calls GetNextWindow().",
               MB_OK);

/***   get the handle to the next window in window-manager's list  ***/

    hNextWindow = GetNextWindow(hWnd,GW_HWNDNEXT);

    if (!hNextWindow)
        MessageBox(NULL,
                   (LPSTR)"There is no next window",
                   (LPSTR)"GetNextWindow() info:",
                   MB_OK);
    else if (hNextWindow == hWnd)
        MessageBox(NULL,
                   (LPSTR)"which is already the top window",
                   (LPSTR)"GetNextWindow returned this window...",
                   MB_OK);
    else if ( !IsIconic(hNextWindow) )
        BringWindowToTop(hNextWindow);
    else
        ShowWindow(hNextWindow,SW_SHOWMAXIMIZED);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GRAY.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\GRAY.C

/*
 *   GrayString
 *
 *   This program demonstrates the use of the GrayString function. The
 *   GrayString function outputs gray text to the specified window.
 *
 */

#include "windows.h"

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;
    HDC   hDC;          /* Handle to display context */
    HBRUSH hMyBrush;        /* Handle to a brush   */
    DWORD gray=RGB(0x22,0x22,0x22); /* Red, Green, Blue, values for brush */

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"Sample Application",
      (LPSTR)"Sample Application",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

/******************************************************************/
  /* get handle to display context */
     hDC = GetDC(hWnd);
  /* create brush with the colors specified by "gray" */
    hMyBrush = CreateSolidBrush(gray);
  /* if brush not created succesfully */
    if (hMyBrush = NULL)
  /* output error */
  MessageBox(hWnd,(LPSTR)"Unable to Create Brush",(LPSTR)"Too Bad",
       MB_OK);
    else
  /* else output gray text */

  GrayString(hDC,hMyBrush,NULL,(DWORD)(LPSTR)"This is gray text",0,5,5,0,0);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GSPOLYFM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GSPOLYFM.C

/*
Function(s) demonstrated in this program: GetPolyFillMode
            SetPolyFillMode

Description:  This program demonstrates differences in the two
        Polygon filling modes, ALTERNATE and WINDING.  In ALTERNATE
        mode, every other region is filled.  In WINDING, all regions
        are filled.  The two shapes drawn here demonstrate the
        difference.

        SetPolyFillMode is used to select the mode;

        GetPolyFillMode is used to retrieve the current fill mode and
        print it on the screen while the polygon is drawn.

*/

#include <windows.h>

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
void DrawPoly (HDC, short, short, short, short);


int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
    HANDLE  hInstance, hPrevInstance;
    LPSTR  lpszCmdLine;
    int   nCmdShow;
    {
    static char szAppName[]="Get/Set/PolyFillMode";
    static BYTE byExtra[]={32,66,121,32,75,114,97,105,103,32,
         66,114,111,99,107,115,99,104,109,105,100,116,32};
    HWND  hWnd;
    WNDCLASS  wndclass;
    MSG   msg;

    if (!hPrevInstance)
   {
   wndclass.style   = CS_HREDRAW | CS_VREDRAW;
   wndclass.lpfnWndProc  = WndProc;
   wndclass.cbClsExtra  = 0;
   wndclass.cbWndExtra  = 0;
   wndclass.hInstance  = hInstance;
   wndclass.hIcon   = LoadIcon(NULL, IDI_APPLICATION);
   wndclass.hCursor  = LoadCursor(NULL, IDC_ARROW);
   wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
   wndclass.lpszMenuName  = szAppName;
   wndclass.lpszClassName = szAppName;

   if (!RegisterClass(&wndclass))
        return FALSE;
   }

    hWnd=CreateWindow(szAppName, szAppName,
       WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
       NULL, NULL, hInstance, NULL);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
    HWND  hWnd;
    unsigned  iMessage;
    WORD  wParam;
    LONG  lParam;
    {
    HDC   hDC;
    HMENU  hMenu;
    HPEN  hPen;
    PAINTSTRUCT ps;

    switch(iMessage)
  {
  case WM_PAINT:
      hDC=BeginPaint(hWnd, &ps);
      hPen=CreatePen(PS_SOLID, 2, 0L);

      SelectObject(hDC, hPen);
      SelectObject(hDC, GetStockObject(GRAY_BRUSH));

      TextOut(hDC, 10, 10, "PolyFillMode=", 13);
      TextOut(hDC, 10, 190, "ALTERNATE", 9);
      TextOut(hDC, 140,190, "WINDING", 7);

      DrawPoly (hDC,  40,  70, ALTERNATE, 0);
      DrawPoly (hDC, 170,  70, WINDING,  0);
      DrawPoly (hDC,  40, 150, ALTERNATE, 1);
      DrawPoly (hDC, 170, 150, WINDING,  1);

      EndPaint(hWnd, &ps);
      DeleteObject(hPen);
      break;

  case WM_DESTROY:
      PostQuitMessage(0);
      break;

  default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
  }
    return (0L);
    }

void DrawPoly (hDC, xOrg, yOrg, nMode, nPt)
    HDC   hDC;
    short  xOrg, yOrg, nMode, nPt;
    {
    short  xOld, yOld;
    long  lView;
    /* Define points in figures */
    static POINT pts0[]={0,30, -30,-30, 30,0, -30,30,
       0,-30, 30,30, -30,0, 30,-30,
       0,30};

    static POINT pts1[]={0,-30, 25,25, -35,-10,
       35,-10, -25,25, 0,-30};

    xOld=LOWORD(lView=GetViewportOrg(hDC));
    yOld=HIWORD(lView);

    SetPolyFillMode(hDC, nMode);
    if (GetPolyFillMode(hDC)==ALTERNATE)
  TextOut(hDC, 40,20, "ALTERNATE",9);
    else
  TextOut(hDC, 40,20, "WINDING  ",9);

    /* Set selected origin */
    SetViewportOrg(hDC, xOrg, yOrg);

    /* Draw either Polygon 1 or 2 */
    if (nPt)
  Polygon(hDC, pts1, sizeof(pts1)/sizeof(POINT));
    else
  Polygon(hDC, pts0, sizeof(pts0)/sizeof(POINT));

    /* Restore old origin */
    SetViewportOrg(hDC, xOld, yOld);
    return;
    }


GSUBMENU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\GSUBMENU.C

/*
 *
 * GetSubMenu
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  The WinMain proceeds to execute the GetSubMenu function
 *  if the user selects the "GetSubMenu" selection from the main menu bar.
 *  If the function call is successful, a message box is created which
 *  copies the menu string into a buffer.
 *
 */

#include "windows.h"
  IDM_SUB      100   /* ID of the submenu.                          */
  N_MAX_COUNT   11   /* Maximum count of the characters of submenu. */
  SIZE_OUTBUFF  33   /* Size of the output buffer.                  */

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;
  HDC hDC;     /* Handle to the Display Context. */

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gsubmenu";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor      = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon          = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)"TestSubMenu"; /* Load menu name. */
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gsubmenu",
           (LPSTR) "GetSubMenu",
           WS_OVERLAPPEDWINDOW,           /* Use overlapped window.   */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           CW_USEDEFAULT,                 /* Use default coordinates. */
           (HWND)NULL,
           LoadMenu(hInst, (LPSTR)"TestSubMenu"),  /* Load submenu.   */
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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


} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{
   char szbuf[N_MAX_COUNT];        /* Buffer for submenu string.   */
   char szoutbuf[SIZE_OUTBUFF];    /* Buffer for output.           */
   short int nCopied;              /* Number of characters copied. */
   HMENU hSubMenu;                 /* Handle to the submenu.       */

   switch (identifier) {
    case WM_COMMAND:
       switch (wParam) {
       case IDM_SUB:              /* If the submenu is selected,         */
             hSubMenu = GetSubMenu(GetMenu(hWnd), 0); /* Get the submenu. */
             if (hSubMenu == NULL)
                {                  /* If the submenu is invalid,          */
                MessageBox(hWnd,   /*  display a error message box.       */
                           (LPSTR)"No Popup Menu Exists Here!",
                           (LPSTR)"ERROR!!!",
                           MB_OK | MB_ICONEXCLAMATION);
                break;             /* And stop here.                      */
                };                 /* Otherwise, get the menu string by posit
             nCopied = GetMenuString(hSubMenu,
                                     0,
                                     (LPSTR)szbuf,
                                     N_MAX_COUNT,
                                     MF_BYPOSITION);
             if (nCopied == 0)   /* and issue an error message if fails.   */
                {
                MessageBox(hWnd,
                           (LPSTR)"GetMenuString Failed!",
                           (LPSTR)"MF_BYPOSITION",
                           MB_OK | MB_ICONEXCLAMATION);
                break;
                }
             else       /* Otherwise, display success through message box. */
                {
                sprintf(szoutbuf,
                        "%s%s%s",
                        "The SubMenu is '",
                        szbuf,
                        "'");
                MessageBox(hWnd,
                           (LPSTR)szoutbuf,
                           (LPSTR)"GetSubMenu",
                           MB_OK);
                };
            break;
       }

    default:
       return(DefWindowProc(hWnd, identifier, wParam, lParam));
       break;

   }

   return(0L);

}


GSYSCOLR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\GSYSCOLR.C

/*
 *
 * GetSysColor
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  If the user couble clicks the right mouse button, the
 *  GetSysColor function is executed with the COLOR_BACKGROUND index.
 *  The RGB color is returned and displayed in a message box.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gsyscolr";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;       /* Add double click capabilities. */
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gsyscolr",
           (LPSTR) "GetSysColor",          /* Create a window.         */
           WS_OVERLAPPEDWINDOW,            /* Make it overlapped.      */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{

   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button To Conduct Test.",
                48, (LPRECT)&rRect, DT_SINGLELINE);  /* Place text to    */
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);          /* prompt for test. */

    }
      break;

     case WM_RBUTTONDBLCLK:                    /* If the user double   */
       {                                       /* clicks on the right  */
       char szbuf[40];   /* Output buffer       | mouse button, then   */
       DWORD dwclr;  /* RGB color of background | establish needed     */
       unsigned short bRed, bGreen, bBlue;     /* variables and call   */
       dwclr = GetSysColor(COLOR_BACKGROUND);  /* the GetSysColor      */
       bRed = GetRValue(dwclr);                /* (with the individual */
       bGreen = GetGValue(dwclr);              /* colors separated to  */
       bBlue = GetBValue(dwclr);               /* different variables) */
      sprintf(szbuf,                          /* function.  Capture   */
          "%s%u%s%u%s%u%s\0",                  /* the RGB information  */
          "The Background Color is RGB(",      /* in a zero terminated */
         bRed, ",", bGreen, ",", bBlue, ")."); /* buffer.             */
      MessageBox(hWnd,                        /* Output the buffer in */
                  (LPSTR)szbuf,                /* a message box format */
                  (LPSTR)"GetSysColor",        /* so that the user can */
                 MB_OK);                      /* have a readable and  */
       }                                       /* useful format.       */
       break;

     case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


GSYSMENU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\GSYSMENU.C

/*
 *
 *   This program demonstrates the use of the GetSystemMenu() function.
 *   GetSystemMenu() returns a handle to the system menu of the specified
 *   Window. GetSystemMenu() is called in WinMain and then the handle
 *   returned by GetSystemMenu() is used to add a "Get....." option to
 *   the system menu.
 *
 *   Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"

#define IDS_MY_OPTION 99

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"GetSystemMenu";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    if (!HelloInit( hInstance ))
  return (FALSE);

    hWnd = CreateWindow((LPSTR)"GetSystemMenu",
      (LPSTR)"GetSystemMenu()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

/*** retrieve the system menu as it currently exists ***/
    hMenu = GetSystemMenu(hWnd, FALSE);

/*   Insert "Get....." into system menu   */
    ChangeMenu(hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
    ChangeMenu(hMenu, 0, (LPSTR)"Get.....", IDS_MY_OPTION, MF_APPEND | MF_STR

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
  case IDS_MY_OPTION:
      MessageBox(NULL,
           (LPSTR)"'Get.....' option chosen",
           (LPSTR)"System Menu:",
           MB_OK);
      break;
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
  BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
  TextOut(ps.hdc,
    5,
    5,
    (LPSTR)"The system menu has had an option added to it ('Get.....')",
    (long)58);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GSYSMODE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MODAL\GSYSMODE.C

/*
 *
 *
 *   This program demonstrates the use of the GetSysModalWindow() function.
 *   GetSysModalWindow(). GetSysModalWindow() returns a handle to a system
 *   modal window if one exists.
 *
 *   Windows Version 2.0 function demonstration application
 *
 */

#include "windows.h"

HWND hSysModalWnd;

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName  = (LPSTR)"min";
    pHelloClass->lpszClassName  = (LPSTR)"SetSysModalWindow";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"SetSysModalWindow",
      (LPSTR)"SetSysModalWindow()",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    MessageBox(NULL,
         (LPSTR)"I'm a system modal message box",
         (LPSTR)"HI!",
         MB_SYSTEMMODAL);

    hSysModalWnd = GetSysModalWindow();

    if (hSysModalWnd)
  DestroyWindow(hSysModalWnd);
    else
  MessageBox(NULL,
       (LPSTR)"not found",
       (LPSTR)"system modal window...",
       MB_OK);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
  return DefWindowProc( hWnd, message, wParam, lParam );
        break;

    case WM_COMMAND:

/*** make "hWnd" system modal ***/
  SetSysModalWindow(hWnd);

  break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
  BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
  TextOut(ps.hdc,
    5,
    5,
    (LPSTR)"To make this window system modal, click on the menu",
    (long)51);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


GSYSMTRX.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MOUSE\GSYSMTRX.C

/*
 *
 * GetSystemMetrics
 *
 * This program demonstrates the use of the GetSystemMetrics function
 *  by checking to see if the debugging version of Windows is installed.
 *  If the user couble clicks the right mouse button, a message box
 *  is displayed telling if the debugging version of Windows has been
 *  installed.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gsysmtrx";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;       /* Add double click capabilities. */
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gsysmtrx",
           (LPSTR) "GetSystemMetrics",     /* Create a window.         */
           WS_OVERLAPPEDWINDOW,            /* Make it overlapped.      */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{

   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button To Conduct Test.",
                48, (LPRECT)&rRect, DT_SINGLELINE);  /* Place text to    */
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);          /* prompt for test. */

    }
      break;

     case WM_RBUTTONDBLCLK:                    /* If the user double   */
       {                                       /* clicks on the right  */
       char szbuf[40];   /* Output buffer       | mouse button, then   */
       int iValue;   /* 0 if no debug, !0 if so | establish needed     */
                                               /* variables and call   */
       iValue = GetSystemMetrics(SM_DEBUG);    /* the GetSystemMetrics */
       if (iValue == 0)                        /* function.  Capture   */
          sprintf(szbuf, "%s%s%s\0",           /* debug information    */
                  "The Debugging Version ",     /* in a zero terminated */
                  "of Windows is NOT ",         /* buffer.              */
            "installed.");
       else
          sprintf(szbuf, "%s%s%s\0",
                  "The Debugging Version ",
                  "of Windows is ",
                  "installed.");

      MessageBox(hWnd,                   /* Output the buffer in */
                  (LPSTR)szbuf,                /* a message box format */
                  (LPSTR)"GetSystemMetrics",   /* so that the user can */
                 MB_OK);                 /* have a readable and  */
       }                                       /* useful format.       */
       break;

     case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


GTEMPDRV.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\I_O\GTEMPDRV.C

/*
 *
 * GetTempDrive
 *
 *  This program demonstrates the use of the GetTempDrive function
 *  by returning the drive letter of the drive which can provide the
 *  best access time during disk operations involving a temporary file.
 *
 */

#include "windows.h"

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
   char chBestDrive;                /* Drive Letter of the best           */
                                    /*  performance drive in system.      */
   char szbuf[80];                  /* Output buffer.                     */

   MessageBox(NULL,
        (LPSTR)"Hit OK to return the highest \
performance drive in the system \
for temp files.",
              (LPSTR)"Drive Test",
              MB_OK);

   chBestDrive = GetTempDrive('A'); /* Get the temp drive.                */

   sprintf(szbuf, "%s%c%s\0",       /* Set up report in output buffer.    */
           "Drive ", chBestDrive,
     ": is the best performance drive in the system \
for temporary files.");

   MessageBox(NULL,                 /* Show the user which drive is best. */
              szbuf,
              (LPSTR)"GetTempDrive",
              MB_OK);

} /* WinMain */


GTICKCNT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MOUSE\GTICKCNT.C

/*
 *
 * GetTickCount
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  If the user couble clicks the right mouse button, the
 *  GetTickCount function is executed.  The time since system startup
 *  is returned and displayed in a message box.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gtickcnt";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;       /* Add double click capabilities. */
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gtickcnt",
           (LPSTR) "GetTickCount",         /* Create a window.         */
           WS_OVERLAPPEDWINDOW,            /* Make it overlapped.      */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{

   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button To Conduct Test.",
                48, (LPRECT)&rRect, DT_SINGLELINE);  /* Place text to    */
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);          /* prompt for test. */

    }
      break;

     case WM_RBUTTONDBLCLK:                    /* If the user double   */
       {                                       /* clicks on the right  */
       char szbuf[80];   /* Output buffer       | mouse button, then   */
       DWORD dwCnt;  /* No. of ms since startup | establish needed     */
                                               /* variables and call   */
       dwCnt = GetTickCount();                 /* the GetTickCount     */
                                               /* function.  Capture   */
      sprintf(szbuf,                          /* the time information */
          "%s%s%lu%s\0",                        /* in a zero terminated */
          "The No. of Milliseconds since",     /* buffer.              */
         " system startup is ", dwCnt, ".");

       MessageBox(hWnd,                        /* Output the buffer in */
                  (LPSTR)szbuf,                /* a message box format */
                  (LPSTR)"GetTickCount",       /* so that the user can */
                 MB_OK);                      /* have a readable and  */
       }                                       /* useful format.       */
       break;

     case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


GTMPFNAM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\GTMPFNAM.C

/*
 *
 * GetTempFileName
 *
 * This program demonstrates the use of the GetTempFileName function
 *  by creating a filename called "temp####" in the directory pointed
 *  to by the TEMP environment varible.  The #### stands for a four
 *  digit number based upon the current system time (Windows generates
 *  this number).  The file is created and then closes the file.
 *
 */

#include "windows.h"

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
   char szTmpFle[80];                  /* Buffer for Temp file name.      */
   char szOutBufr[80];                 /* Output Buffer.                  */
   int iFNumb;                         /* Unique number Windows provides. */

   MessageBox(NULL,                    /* Prep the user with a message.   */
              (LPSTR)"About to create Temporary File.",
              (LPSTR)"GetTempFileName Test",
              MB_OK);

    /* Get the new Temporary File Name, create, then close the file. */

   iFNumb = GetTempFileName((BYTE)'D',
                            (LPSTR)"TMP",
                            (WORD)0,
                            (LPSTR)szTmpFle);

    /* Place the unique number (last four characters of filename)    */
    /* into an output buffer for display in a message box.           */

   sprintf(szOutBufr,
           "%s%4i\0",
           "The file number is: ",
           iFNumb);

    /* Output the unique file number in a message box for clarity.   */

   MessageBox(NULL,
              (LPSTR)szOutBufr,
              (LPSTR)"Allocated File Number.",
              MB_OK);

    /* Put the complete path and file name into an output buffer.    */

   sprintf(szOutBufr, "%s%s%s\0",
           "The temporary filename is ",
           szTmpFle, ".");

    /* Output the complete file name in a message box for clarity.   */

   MessageBox(NULL, (LPSTR)szOutBufr,
              (LPSTR)"GetTempFileName",
              MB_OK);

} /* WinMain */


GTXTCHX.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\FONTS\GTXTCHX.C

/*
 *
 * GetTextCharacterExtra
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  If the user couble clicks the right mouse button, the
 *  GetTextCharacterExtra function is executed.  The intercharacter
 *  spacing is returned and displayed in a message box.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gtxtchx";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;       /* Add double click capabilities. */
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gtxtchx",
           (LPSTR) "GetTextCharacterExtra", /* Create a window.         */
           WS_OVERLAPPEDWINDOW,             /* Make it overlapped.      */
           CW_USEDEFAULT,                   /* Use default coordinates. */
           CW_USEDEFAULT,                   /* Use default coordinates. */
           CW_USEDEFAULT,                   /* Use default coordinates. */
           CW_USEDEFAULT,                   /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{

   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button To Show Intercharacte
                63, (LPRECT)&rRect, DT_SINGLELINE);  /* Place text to    */
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);          /* prompt for test. */

    }
      break;

     case WM_RBUTTONDBLCLK:                    /* If the user double    */
       {                                       /* clicks on the right   */
       char szbuf[80];   /* Output buffer       | mouse button, then    */
       short sIntSpacing;                      /* variables and call    */
       HDC hDC; /* Handle to display Context. */

       hDC = GetDC(hWnd);                      /* (after getting DC)    */
       sIntSpacing = GetTextCharacterExtra(hDC); /* GetTextCharacterExtra */
                                               /* (with the display     */
                                               /* context of the top    */
                                               /* level window.         */
      sprintf(szbuf,                          /* Capture the interchar */
          "%s%i%s\0",                          /* spacing information   */
          "Current Intercharacter Spacing = ", /* in a zero terminated  */
         (int)sIntSpacing, ".");              /* buffer.               */
      MessageBox(hWnd,                        /* Output the buffer in  */
                  (LPSTR)szbuf,                /* a message box format  */
                  (LPSTR)"GetTextCharacterExtra", /* so that the user   */
                 MB_OK);                      /* can have a readable   */
                                               /* and useful format.    */

       SetTextCharacterExtra(hDC, 10);

       MessageBox(hWnd, (LPSTR)"Set the Intercharacter Spacing to 10.",
                  (LPSTR)"Setting = 10",
                  MB_OK);

       sIntSpacing = GetTextCharacterExtra(hDC);

       sprintf(szbuf,
          "%s%i%s\0",
          "New Intercharacter Spacing = ",
         (int)sIntSpacing, ".");
      MessageBox(hWnd,
                  (LPSTR)szbuf,
                  (LPSTR)"GetTextCharacterExtra",
                 MB_OK);
       }
       break;

     case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


GTXTCOLR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\FONTS\GTXTCOLR.C

/*
 *
 * GetTextColor
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  If the user couble clicks the right mouse button, the
 *  GetTextColor function is executed with the HDC of the top level window.
 *  The RGB color is returned and displayed in a message box.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gtxtcolr";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;       /* Add double click capabilities. */
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gtxtcolr",
           (LPSTR) "GetTextColor",         /* Create a window.         */
           WS_OVERLAPPEDWINDOW,            /* Make it overlapped.      */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{

   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button To Conduct Test.",
                48, (LPRECT)&rRect, DT_SINGLELINE);  /* Place text to    */
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);          /* prompt for test. */

    }
      break;

     case WM_RBUTTONDBLCLK:                    /* If the user double   */
       {                                       /* clicks on the right  */
       char szbuf[40];   /* Output buffer       | mouse button, then   */
       DWORD dwclr;  /* RGB color of text       | establish needed     */
       unsigned short bRed, bGreen, bBlue;     /* variables and call   */
       HDC hDC; /* Display Context Handle. */

       hDC = GetDC(hWnd);                      /* (after getting DC)   */
       dwclr = GetTextColor(hDC);              /* the GetSysColor      */
       bRed = GetRValue(dwclr);                /* (with the individual */
       bGreen = GetGValue(dwclr);              /* colors separated to  */
       bBlue = GetBValue(dwclr);               /* different variables) */
      sprintf(szbuf,                          /* function.  Capture   */
          "%s%u%s%u%s%u%s\0",                  /* the RGB information  */
          "The Text Color is RGB(",            /* in a zero terminated */
         bRed, ",", bGreen, ",", bBlue, ")."); /* buffer.             */
      MessageBox(hWnd,                        /* Output the buffer in */
                  (LPSTR)szbuf,                /* a message box format */
                  (LPSTR)"GetTextColor",       /* so that the user can */
                 MB_OK);                      /* have a readable and  */
       }                                       /* useful format.       */
       break;

     case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


GTXTEXT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\FONTS\GTXTEXT.C

/*
 *
 * GetTextExtent
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  If the user couble clicks the right mouse button, the
 *  GetTextExtent function is executed with the HDC of the top level
 *  window and the text "Test Text.".  The extents are returned in a
 *  message box.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;         /* Handle to the Instance.            */
static HWND hWnd;            /* Handle to the Window.              */
static LPSTR lpTesttxt;      /* Long Pointer to Test Text String.  */

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  lpTesttxt = (LPSTR)"Test Text.";

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gtxtext";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;       /* Add double click capabilities. */
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gtxtext",
           (LPSTR) "GetTextExtent",        /* Create a window.         */
           WS_OVERLAPPEDWINDOW,            /* Make it overlapped.      */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{
   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button To Conduct Test.",
                48, (LPRECT)&rRect, DT_SINGLELINE);  /* Prompt text.    */
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 275, 75);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC, lpTesttxt, 10,
                 (LPRECT)&rRect, DT_SINGLELINE);     /* Test Text.      */
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);

    }
      break;

     case WM_RBUTTONDBLCLK:                    /* If the user double   */
       {                                       /* clicks on the right  */
       char szbuf[80];   /* Output buffer.      | mouse button, then   */
       DWORD dwTxtExts;  /* Extents - test text.| establish needed     */
                                               /* variables and call   */
       HDC hDC; /* Display Context Handle. */

       hDC = GetDC(hWnd);                      /* (after getting DC)   */
       dwTxtExts = GetTextExtent(hDC,
                                 lpTesttxt, 10); /* the GetTextExtent  */
      sprintf(szbuf,                          /* function.  Capture   */
          "%s%i%s%i%s\0",                      /* the Ext information  */
          "The Text Extents are (",            /* in a zero terminated */
         (int)HIWORD(dwTxtExts), ",",         /* buffer.             */
          (int)LOWORD(dwTxtExts), ").");
      MessageBox(hWnd,                        /* Output the buffer in */
                  (LPSTR)szbuf,                /* a message box format */
                  (LPSTR)"GetTextExtent",      /* so that the user can */
                 MB_OK);                      /* have a readable and  */
       }                                       /* useful format.       */
       break;

     case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


GTXTFACE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\FONTS\GTXTFACE.C

/*
 *
 * GetTextFace
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  If the user couble clicks the right mouse button, the
 *  GetTextFace function is executed with the HDC of the top level
 *  window and default font.  The facename is returned in a message
 *  box.  If an error occurs, a message box is also returned.
 *
 */

#include "windows.h"

#define BUF_SIZE 80

/* Global Variables */
static HANDLE hInst;         /* Handle to the Instance.            */
static HWND hWnd;            /* Handle to the Window.              */

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gtxtface";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;       /* Add double click capabilities. */
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gtxtface",
           (LPSTR) "GetTextFace",          /* Create a window.         */
           WS_OVERLAPPEDWINDOW,            /* Make it overlapped.      */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{
   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button To Conduct Test.",
                48, (LPRECT)&rRect, DT_SINGLELINE);  /* Prompt text.    */
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);

    }
      break;

     case WM_RBUTTONDBLCLK:                    /* If the user double   */
       {                                       /* clicks on the right  */
       char szbuf[BUF_SIZE]; /* Output buffer.  | mouse button, then   */
                             /*                 | establish needed     */
       char szFacename[BUF_SIZE]; /* Facename Buffer.                  */
       short sBytesCopied; /* Bytes copied.     | variables and call   */
       HDC hDC; /* Display Context Handle. */

       hDC = GetDC(hWnd);                      /* (after getting DC)   */
       sBytesCopied = GetTextFace(hDC, BUF_SIZE,
                           (LPSTR)szFacename); /* the GetTextFace fn.  */

       if (sBytesCopied == 0)                  /* If error, issue a    */
          {                                    /* message box.         */
             MessageBox(hWnd,
                        (LPSTR)"No Bytes Copied!!!",
                        (LPSTR)"GetTextFace",
                        MB_OK | MB_ICONEXCLAMATION);
             break;
          }
       else
          {
         sprintf(szbuf,                       /* Now its OK; capture  */
             "%s%s%s\0",                       /* the Face information */
             "The Facename is '",               /* in a zero terminated */
            szFacename, "'.");                 /* buffer.              */

          MessageBox(hWnd,                     /* Output the buffer in */
                     (LPSTR)szbuf,             /* a message box format */
                     (LPSTR)"GetTextFace",     /* so that the user can */
                    MB_OK);                   /* have a readable and  */
           };                                  /* useful format.       */
       }
       break;

     case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


GTXTMTRX.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\FONTS\GTXTMTRX.C

/*
 *
 * GetTextMetrics
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  If the user couble clicks the right mouse button, the
 *  GetTextMetrics function is executed with the HDC of the top level
 *  window and the current font.  The width and height are returned in a
 *  message box.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;         /* Handle to the Instance.            */
static HWND hWnd;            /* Handle to the Window.              */

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"gtxtmtrx";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;       /* Add double click capabilities. */
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "gtxtmtrx",
           (LPSTR) "GetTextMetrics",        /* Create a window.         */
           WS_OVERLAPPEDWINDOW,            /* Make it overlapped.      */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           CW_USEDEFAULT,                  /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{
   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button To Conduct Test.",
                48, (LPRECT)&rRect, DT_SINGLELINE);  /* Prompt text.    */
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);

    }
      break;

     case WM_RBUTTONDBLCLK:                    /* If the user double   */
       {                                       /* clicks on the right  */
       char szbuf[80];   /* Output buffer.      | mouse button, then   */
       TEXTMETRIC *strTM; /* Extents - test text.| establish needed    */
       BOOL bGotem;      /* Boolean success flg | variables and call   */
       HDC hDC;      /* Display Context Handle. | the GetTextMetrics   */
       HANDLE hLMem;     /* Local Memory for the Text Metrics.         */

          /* Allocate the local memory for the Text Metrics. */

       hLMem = LocalAlloc(LMEM_DISCARDABLE | LMEM_MOVEABLE,
                          sizeof(TEXTMETRIC));
       if (hLMem == NULL)   /* If error, then complain. */
          {
          MessageBox(hWnd, (LPSTR)"Could Not allocate Local Memory!!!",
                     (LPSTR)"ERROR!!!", MB_OK | MB_ICONEXCLAMATION);
          break;
          };

          /* Lock the local memory. */

       strTM = (TEXTMETRIC *)LocalLock(hLMem);

       if (strTM == NULL)   /* If error, then complain. */
          {
          MessageBox(hWnd, (LPSTR)"Could Not lock Local Memory!!!",
                     (LPSTR)"ERROR!!!", MB_OK | MB_ICONEXCLAMATION);
          break;
          };

       hDC = GetDC(hWnd);                      /* (after getting DC)   */

          /* Get the Text Metrics of the current Font. */

       bGotem = GetTextMetrics(hDC, (LPTEXTMETRIC)strTM);

       if (bGotem == NULL)   /* If the GetTextMetrics fails, then complain. *
          {
          MessageBox(hWnd,
             (LPSTR)"Did Not Get The Text Metrics!!!",
             (LPSTR)"ERROR!!!", MB_OK | MB_ICONEXCLAMATION);
          break;
          }
       else
          {
         sprintf(szbuf,                       /* Otherwise, capture   */
                  "%s%s%i%s%i%s\0",            /* the Ext information  */
                  "The Text Metrics ",         /* in a zero terminated */
                  "<height,weight> are (",     /* buffer.             */
                 (int)strTM->tmHeight, ",",
                  (int)strTM->tmWeight, ").");

         MessageBox(hWnd,                     /* Output the buffer in */
                     (LPSTR)szbuf,             /* a message box format */
                     (LPSTR)"GetTextMetrics",  /* so that the user can */
                    MB_OK);                   /* have a readable and  */
          };                                   /* useful format.       */
       LocalUnlock(hLMem);  /* Unlock the local memory. */
       LocalFree(hLMem);    /* Free the local memory.   */
       };
       break;

     case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


GUPDRECT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\GUPDRECT.C

/*
Date: 7/11/88
Function(s) demonstrated in this program: GetUpdateRect
Compiler version: C 5.1
Description: This program paints the client area red, make the window a icon,
             and then restores the window to it original size. By doing this
             it creates a update region. With the update region, the function
             GetUpdateRect is used to find the smallest rectangle around the
             update region. Then the program display the coordinates of the
             update rectangle.
*/

#include <windows.h>
#include <stdio.h>
#include "gupdrect.h"

static char szFuncName [] = "GetUpdateRect";
static char szAppName [] = "GUPDRECT";

int PASCAL WinMain ( hInstance, hPrevInstance, lpszCmdLine, nCmdShow )
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int         nCmdShow;
{
     HWND        hWnd;
     WNDCLASS    wndclass;
     MSG         msg;
     HMENU       hMenu;

     if (!hPrevInstance) {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc   = WndProc;
          wndclass.cbClsExtra    = 0;
          wndclass.cbWndExtra    = 0;
          wndclass.hInstance     = hInstance;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
          wndclass.lpszMenuName  = "GUDR";
          wndclass.lpszClassName = szFuncName;

          if (!RegisterClass (&wndclass))
               return FALSE;
          }

     hMenu = LoadMenu ( hInstance, "GUDR" );


     hWnd = CreateWindow (szFuncName,           /* window class name       */
                    szAppName,                  /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    hMenu,                      /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL);                      /* create parameters       */

     ShowWindow (hWnd, nCmdShow);
     UpdateWindow (hWnd);

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
{
   HDC         hDC;
   PAINTSTRUCT ps;
   RECT        rectUpdateRect;
   RECT        rectClientRect;
   HBRUSH      hSolidBrush;
   BOOL        bfGotUpdateRect;
   int         nIndex;
   char        szBuffer [100];

   switch(iMessage)
   {
   case WM_INITMENU:
      InvalidateRect ( hWnd, (LPRECT)NULL, TRUE );
      break;
    case WM_COMMAND:
       switch ( wParam )
          {
          case IDM_BOX:
             GetClientRect ( hWnd, (LPRECT)&rectClientRect );

             hDC = GetDC ( hWnd );
             hSolidBrush = CreateSolidBrush ( 0xFF0000 );
             FillRect ( hDC, (LPRECT)&rectClientRect, hSolidBrush );

             ShowWindow ( hWnd, SW_SHOWMINIMIZED );
             ShowWindow ( hWnd, SW_SHOWNORMAL );

             bfGotUpdateRect = GetUpdateRect ( hWnd, (LPRECT)&rectUpdateRect,
                FALSE );

             if ( bfGotUpdateRect == TRUE )
                {
                sprintf ( szBuffer, "%s %d%s %d%s %d%s %d%s",
                   "Update rectangle .top is", rectUpdateRect.top,
                   ",\nupdate rectangle .bottom is", rectUpdateRect.bottom,
                   ",\nupdate rectangle .left is", rectUpdateRect.left,
                   ",\nand update rectangle .right is", rectUpdateRect.right,
                   "." );
                MessageBox ( hWnd, (LPSTR)szBuffer, (LPSTR)szFuncName,
                   MB_OK );
                }
             else
                MessageBox ( hWnd, (LPSTR)"Update rectangle is empty.",
                   (LPSTR)szFuncName, MB_OK );

             ReleaseDC ( hWnd, hDC );
             break;
          default :
             return DefWindowProc (hWnd, iMessage, wParam, lParam);
             break;
          }
       break;
     case WM_DESTROY:
       PostQuitMessage(0);
       break;
     default:
       return DefWindowProc (hWnd, iMessage, wParam, lParam);
     return (0L);
   }
}


HELLO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\STACK\HELLO.C

/*  Hello.c
    Hello Application
    Windows Toolkit Version 2.03
    Copyright (c) Microsoft 1985,1986,1987,1988 */

#include "windows.h"
#include "hello.h"

char szAppName[10];
char szAbout[10];
char szMessage[15];
int  MessageLength;

static HANDLE hInst;
FARPROC lpprocAbout;

void PASCAL InitStackUsed();
int  PASCAL ReportStackUsed();

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

BOOL FAR PASCAL About( hDlg, message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:
            break;
        case WM_COMMAND:
            EndDialog(hDlg, TRUE);
            break;
        default:
            return FALSE;
            break;
        }
    return(TRUE);
}


void HelloPaint( hDC )
HDC hDC;
{
  TextOut( hDC, 10, 10, "Determines stack size.", 22 );
}


/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    /* Load strings from resource */
    LoadString( hInstance, IDSNAME, (LPSTR)szAppName, 10 );
    LoadString( hInstance, IDSABOUT, (LPSTR)szAbout, 10 );
    MessageLength = LoadString( hInstance, IDSTITLE, (LPSTR)szMessage, 15 );

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon          = LoadIcon( hInstance, MAKEINTRESOURCE(HELLOI
    pHelloClass->lpszMenuName   = (LPSTR)szAppName;
    pHelloClass->lpszClassName  = (LPSTR)szAppName;
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    InitStackUsed();

    if (!hPrevInstance) {
        /* Call initialization procedure if this is the first instance */
        if (!HelloInit( hInstance ))
            return FALSE;
        }
    else {
        /* Copy data from previous instance */
        GetInstanceData( hPrevInstance, (PSTR)szAppName, 10 );
        GetInstanceData( hPrevInstance, (PSTR)szAbout, 10 );
        GetInstanceData( hPrevInstance, (PSTR)szMessage, 15 );
        GetInstanceData( hPrevInstance, (PSTR)&MessageLength, sizeof(int) );
        }

    hWnd = CreateWindow((LPSTR)szAppName,
                        (LPSTR)szMessage,
                         WS_OVERLAPPEDWINDOW,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                         CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Save instance handle for DialogBox */
    hInst = hInstance;

    /* Bind callback function with module instance */
    lpprocAbout = MakeProcInstance( (FARPROC)About, hInstance );

    /* Insert "About..." into system menu */
    hMenu = GetSystemMenu(hWnd, FALSE);
    ChangeMenu(hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
    ChangeMenu(hMenu, 0, (LPSTR)szAbout, IDSABOUT, MF_APPEND | MF_STRING);

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;
    char  buf[20];
    int   iStack;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        case IDSABOUT:
            DialogBox( hInst, MAKEINTRESOURCE(ABOUTBOX), hWnd, lpprocAbout );
            break;
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_COMMAND:
        switch (wParam)
        {
        case IDMCHECK:
               iStack = ReportStackUsed();
               itoa ( iStack, buf, 10);
               MessageBox (hWnd, buf,"Stack =", MB_OK );
            break;

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

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        HelloPaint( ps.hdc );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


HELLO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MODELESS\HELLO.C

/*  Hello.c
    Hello Application
    Windows Version 1.01
    Copyright (c) Microsoft 1985

This application has been  revised  to  demonstrate  the  coding
differences between the two Dialog boxes:
   MODAL, created  using DialogBox and
   MODELESS, created using CreateDialog.
The  application  starts  out by having the user select the "GO"
menu item which creates the "First Dialog"  and  then  the  DEMO
button  then  creates  the "Second Dialog".  The "Second Dialog"
then allows you to push some buttons and process them.

To point out the differences in coding,  there are  "#ifdef"  to
allow  you  to  compile using the desired method and to visually
see what needs to be done when using one method over the  other.
This  information  is  an  expanded implementation of the sample
code on pages 169-173 of the Programming Guide.  The default  is
set to compile using MODAL dialog boxes.  If you want to compile
using the MODELESS dialog boxes, change "MODAL" to "XMODAL".*/

 XMODAL /* default */

#include "windows.h"
#include "hello.h"

char szAppName[10];
char szAbout[10];
char szMessage[15];
int  MessageLength;

#ifdef MODAL
#else
HWND  hDlgWnd1;
HWND  hDlgWnd2;
#endif
static  HANDLE hInst;
FARPROC lpprocAbout;
FARPROC lpprocFirstDlg;
FARPROC lpprocSecondDlg;

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL     FirstDlg(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL    SecondDlg(HWND, unsigned, WORD, LONG);

BOOL FAR PASCAL About( hDlg, message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    if (message == WM_COMMAND) {
        EndDialog( hDlg, TRUE );
        return TRUE;
        }
    else if (message == WM_INITDIALOG)
        return TRUE;
    else return FALSE;
}


void HelloPaint( hDC )
HDC hDC;
{
    TextOut( hDC, (short)10, (short)10,
#ifdef MODAL
           (LPSTR)"DialogBox = Modal",(short)17 );
#else
           (LPSTR)"CreateDialog = Modeless",(short)23 );
#endif
}

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    /* Load strings from resource */
    LoadString( hInstance, IDSNAME, (LPSTR)szAppName, 10 );
    LoadString( hInstance, IDSABOUT, (LPSTR)szAbout, 10 );
    MessageLength = LoadString( hInstance, IDSTITLE, (LPSTR)szMessage, 15 );

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon          = LoadIcon( hInstance, (LPSTR)szAppName );
    pHelloClass->lpszMenuName   = (LPSTR)szAppName;
    pHelloClass->lpszClassName  = (LPSTR)szAppName;
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    BOOL  bResult;
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    if (!hPrevInstance) {
        /* Call initialization procedure if this is the first instance */
        if (!HelloInit( hInstance ))
            return FALSE;
        }
    else {
        /* Copy data from previous instance */
        GetInstanceData( hPrevInstance, (PSTR)szAppName, 10 );
        GetInstanceData( hPrevInstance, (PSTR)szAbout, 10 );
        GetInstanceData( hPrevInstance, (PSTR)szMessage, 15 );
        GetInstanceData( hPrevInstance, (PSTR)&MessageLength, sizeof(int) );
        }

    hWnd = CreateWindow((LPSTR)szAppName,
                        (LPSTR)szMessage,
                        WS_TILEDWINDOW,
                        0,    /*  x - ignored for tiled windows */
                        0,    /*  y - ignored for tiled windows */
                        0,    /* cx - ignored for tiled windows */
                        0,    /* cy - ignored for tiled windows */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Save instance handle for DialogBox */
    hInst = hInstance;

    /* Bind callback function with module instance */
        lpprocAbout = MakeProcInstance( (FARPROC)About,     hInstance );
     lpprocFirstDlg = MakeProcInstance( (FARPROC)FirstDlg,  hInstance );
    lpprocSecondDlg = MakeProcInstance( (FARPROC)SecondDlg, hInstance );

    /* Insert "About..." into system menu */
    hMenu = GetSystemMenu(hWnd, FALSE);
    ChangeMenu(hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
    ChangeMenu(hMenu, 0, (LPSTR)szAbout, IDSABOUT, MF_APPEND | MF_STRING);

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
#ifdef MODAL
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }
#else
    /* The following can be rewritten in many ways, but was made
       for clairity and for easy modification.
       Since this program does not use an Accelerator Table the
       code has been commented out.  I thought I should put it
       in for completness.  */

    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        bResult = NULL; /* default is that the message has not been processed
        if (hDlgWnd1 != NULL)
           bResult = IsDialogMessage(hDlgWnd1, (LPMSG)&msg);
        if (hDlgWnd2 != NULL)
           bResult = IsDialogMessage(hDlgWnd2, (LPMSG)&msg);
     /* if (!bResult)  /* message not processed by above dialog(s) */
     /*    bResult = TranslateAccelerator(hWnd, hAccelTable, (LPMSG)&msg );
     */
        if (!bResult) {  /* the parent will get the message */
             TranslateMessage((LPMSG)&msg);
             DispatchMessage((LPMSG)&msg);
        } /* end if */
    } /* end while */
#endif
    return (int)msg.wParam;
}


long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        case IDSABOUT:
            DialogBox( hInst, MAKEINTRESOURCE(ABOUTBOX), hWnd, lpprocAbout );
            break;
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_CREATE:
#ifdef MODAL
#else
    hDlgWnd1 = NULL;  /* initialize the first time through */
    hDlgWnd2 = NULL;  /* initialize the first time through */
#endif
        break;

    case WM_COMMAND:
#ifdef MODAL
        DialogBox( hInst, MAKEINTRESOURCE(FIRSTDIALOG),
                   hWnd, lpprocFirstDlg);
#else
        hDlgWnd1 = CreateDialog( hInst, MAKEINTRESOURCE(FIRSTDIALOG),
                                 hWnd, lpprocFirstDlg);
#endif
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        HelloPaint( ps.hdc );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}

/**********************************************************
                  First  Dialog
***********************************************************/
BOOL FAR PASCAL FirstDlg(hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned   message;
WORD       wParam;
LONG       lParam;
{
    switch (message){
    case WM_INITDIALOG:
        return TRUE;

    case WM_COMMAND:
        switch (wParam)
        {
        case IDDINSERT:
#ifdef MODAL
             DialogBox(hInst, MAKEINTRESOURCE(SECONDDIALOG),
           hDlg, lpprocSecondDlg);
             /* please note that the Dialog in the RC file does
                NOT have the WS_VISIBLE attribute set which will
                allow for keyboard processing BEFORE the dialog
                is displayed.                                   */
#else
       hDlgWnd2 = CreateDialog(hInst, MAKEINTRESOURCE(SECONDDIALOG),
             hDlg, lpprocSecondDlg);
             /* ShowWindow is needed here because the dialog
                style doesn't have WM_VISIBLE bit set.  */
             ShowWindow(hDlgWnd2,SHOW_OPENWINDOW);
#endif
            break;
        case IDDCANCEL:
#ifdef MODAL
      EndDialog(hDlg, TRUE);
#else
      DestroyWindow(hDlg);
      hDlgWnd1 = NULL; /* clear because this is used in the input loop */
#endif
      break;

        default:
            return FALSE;
        }
        break;

    default:
        return FALSE;
    }
    return TRUE;
}


/**********************************************************
                  Second Dialog
***********************************************************/
BOOL FAR PASCAL SecondDlg(hDlg, message, wParam, lParam)
HWND     hDlg;
unsigned   message;
WORD       wParam;
LONG       lParam;
{

  switch (message){
     case WM_INITDIALOG:
      /* Modify the text strings. */
   SetDlgItemText( hDlg, IDDTXT1,
             (LPSTR)"Use the 'TAB' key to move around.");
   SetDlgItemText( hDlg, IDDTXT2,
             (LPSTR)"Select the button desired.");

      /* Modify the button text. */
   SetDlgItemText( hDlg, IDDABORT, (LPSTR)"ONE");
   SetDlgItemText( hDlg, IDDRETRY, (LPSTR)"TWO");
   SetDlgItemText( hDlg, IDDIGNORE,(LPSTR)"THREE");
   SetDlgItemText( hDlg, IDDOK,   (LPSTR)"FOUR");

      /* Disable the 2nd button */
   EnableWindow( GetDlgItem(hDlg, IDDRETRY), FALSE );

         break;

     case WM_COMMAND:
         switch (wParam)
         {
           case IDDABORT:
       MessageBox( hDlg,(LPSTR)"One",(LPSTR)"Button Selected",MB_OK);
             break;
           case IDDRETRY:
       MessageBox( hDlg,(LPSTR)"Two",(LPSTR)"Button Selected",MB_OK);
             break;
           case IDDIGNORE:
       MessageBox( hDlg,(LPSTR)"Three",(LPSTR)"Button Selected",MB_OK);
             break;
           case IDDOK:
       MessageBox( hDlg,(LPSTR)"Four",(LPSTR)"Button Selected",MB_OK);
             break;
     default: ;  /* nothing */
    break;
   }  /* end switch */

    case WM_CLOSE:

#ifdef MODAL
   EndDialog(hDlg, TRUE);
#else
   DestroyWindow(hDlg);
   hDlgWnd2 = NULL; /* clear because this is used in the input loop */
#endif

  break;

     default:
         return FALSE;
   }
   return TRUE;
}


HIDE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CARET\HIDE.C

/*
 *
 *  HideCaret
 *
 *  This program demonstrates the use of the HideCaret function. The
 *  HideCaret function removes the caret from the specified window.
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit (hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pClass;

  pClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));
  pClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pClass->lpszMenuName   = (LPSTR)NULL;
  pClass->lpszClassName  = (LPSTR)"Window";
  pClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pClass->hInstance      = hInstance;
  pClass->style          = CS_HREDRAW | CS_VREDRAW;
  pClass->lpfnWndProc    = DefWindowProc;

  if (!RegisterClass ( (LPWNDCLASS)pClass))
    return FALSE;

  LocalFree ( (HANDLE) pClass);
  return TRUE;        /* Initialization succeeded */
  }

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  HWND         hWnd;                /* Handle to the parent window    */

  WinInit (hInstance);

  hWnd = CreateWindow ( (LPSTR)"Window",
      (LPSTR)"Sample Window",
      WS_OVERLAPPEDWINDOW,
      20, 20, 400, 200,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
 );

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  CreateCaret (hWnd, NULL, 8, 12);
  SetCaretPos (50, 50);
  ShowCaret (hWnd);
  MessageBox (hWnd, (LPSTR)"Here is the caret",
      (LPSTR)" ", MB_OK);
  MessageBox (hWnd, (LPSTR)"The caret is going to be hid",
      (LPSTR)"WARNING", MB_OK);
/** hide the caret **/
  HideCaret (hWnd);
/** output message box so application does not end before user **/
/** can see that the caret is gone                             **/
  MessageBox (hWnd, (LPSTR)"It's gone!", (LPSTR)" ", MB_OK);

  return 0;
  }


HILITE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\HILITE.C

/*
 *   HiliteMenuItem
 *
 *   This program demonstrates the use of the HiliteMenuItem function. The
 *   HiliteMenuItem function hilites or removes hiliting from an item in a
 *   menu. In this program, the 4th item in the system menu was hilited in
 *   the WinMain procedure.
 */

#include "windows.h"

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit (hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));

  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon             = LoadIcon (hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName     = (LPSTR)"Sample Application";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree ( (HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
  }

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  HelloInit (hInstance);
  hWnd = CreateWindow ( (LPSTR)"Sample Application",
      (LPSTR)"Sample Application",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
 );

/*** get the handle to the system menu *********************************/
  hMenu = GetSystemMenu (hWnd, FALSE);

/*** hilite the 4th item in the system menu *****************************/
  HiliteMenuItem (hWnd, hMenu, 3, MF_BYPOSITION | MF_HILITE);

/* Make window visible according to the way the app is activated */
  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  MessageBox (hWnd, (LPSTR)" ...the fourth menu-item will be hilited.",
      (LPSTR)"  Click on the System Menu and...  ", MB_OK);

/* Polling messages from event queue */
  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }

  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }


ICLIPREC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\ICLIPREC.C

/*
 *
 *  IntersectClipRect
 *
 *  This program demonstrates the use of the IntersectClipRect function.
 *  IntersectClipRect creates a new clipping region for the specified DC
 *  by taking the intersection of the current clipping region and the
 *  rectangle represented by the four values sent it. IntersectClipRect
 *  is called from FunctionDemonstrated in this sample application.
 */

#include <windows.h>
HWND hWnd;

BOOL FAR PASCAL InitMaster (HANDLE, HANDLE, int);
long FAR PASCAL MasterWindowProc (HANDLE, unsigned, WORD, LONG);
void FAR PASCAL FunctionDemonstrated ();

/***********************   main procedure   *******************************/

int     PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  MSG  msg;

  InitMaster (hInstance, hPrevInstance, cmdShow);

  FunctionDemonstrated ();

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  exit (msg.wParam);
  }


/*******************************   initialization   ***********************/

BOOL FAR PASCAL InitMaster (hInstance, hPrevInstance, cmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
int  cmdShow;
  {
  WNDCLASS  wcMasterClass;
  HMENU     hMenu;

  wcMasterClass.lpszClassName = (LPSTR) "Master";
  wcMasterClass.hInstance     = hInstance;
  wcMasterClass.lpfnWndProc   = MasterWindowProc;
  wcMasterClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcMasterClass.hIcon         = NULL;
  wcMasterClass.lpszMenuName  = (LPSTR) NULL;
  wcMasterClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcMasterClass.style         = CS_HREDRAW | CS_VREDRAW;
  wcMasterClass.cbClsExtra    = 0;
  wcMasterClass.cbWndExtra    = 0;

  RegisterClass ( (LPWNDCLASS) & wcMasterClass);

  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, "Execute Function", 100, MF_APPEND);

  hWnd = CreateWindow ( (LPSTR) "Master", (LPSTR) "IntersectClipRect",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0,
                      NULL,hMenu , hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
  }

/*********************   window procedure - process messages   *************/
long    FAR PASCAL MasterWindowProc (hWnd, message, wParam, lParam)
HWND        hWnd;
unsigned    message;
WORD      wParam;
LONG        lParam;
  {
  switch (message)
    {
    case WM_COMMAND:
      if (wParam == 100)
        FunctionDemonstrated ();
      else
        return (DefWindowProc (hWnd, message, wParam, lParam));
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
      break;
    }
  return (0L);
  }

/****************************   function demonstrated   ********************/

void FAR PASCAL FunctionDemonstrated ()
  {
  HDC hDC = GetDC (hWnd);
  HRGN hRgn;     /* handle to first clipping region    */
  RECT ClientRect;
  POINT RectPoint[2];
  short  nNewClipRect;   /* return value from IntersectClipRect */

  GetClientRect (hWnd, (LPRECT) & ClientRect); /* load device coordinates */

  SetMapMode (hDC, MM_ANISOTROPIC);
  SetWindowOrg (hDC, 0, 0);
  SetWindowExt (hDC, 120, 120);
  SetViewportOrg (hDC, 0, 0);
  SetViewportExt (hDC, (short) ClientRect.right, (short) ClientRect.bottom);

  RectPoint[0].x = 0;
  RectPoint[0].y = 0;
  RectPoint[1].x = 100;
  RectPoint[1].y = 100;

  LPtoDP (hDC, (LPPOINT) & RectPoint[0].x, 2);

  hRgn = CreateRectRgn ( (short) RectPoint[0].x,
      (short) RectPoint[0].y,
      (short) RectPoint[1].x,
      (short) RectPoint[1].y);

  SelectClipRgn (hDC, hRgn);

  MessageBox (GetFocus (), (LPSTR)"into the first clipping region",
      (LPSTR)"I am about to do a TextOut and InvertRect...",
      MB_OK);

  TextOut (hDC, 0, 5,
      "THIS LINE HERE IS VERY LONG . WILL IT ALL BE SHOWN IN THE CLIPPING REG
      (short)75);
  InvertRect (hDC, (LPRECT) & ClientRect);

/*** call IntersectClipRect with first clipping region and new coordinates **

  RectPoint[0].x = 5;
  RectPoint[0].y = 5;
  RectPoint[1].x = 20;
  RectPoint[1].y = 20;

  LPtoDP (hDC, (LPPOINT) & RectPoint[0].x, 2);

  nNewClipRect = IntersectClipRect (hDC,
      (short)RectPoint[0].x,
      (short)RectPoint[0].y,
      (short)RectPoint[1].x,
      (short)RectPoint[1].y);

  if (nNewClipRect == ERROR)
    MessageBox (GetFocus (), (LPSTR)"The DC sent IntersectClipRect is not val
        (LPSTR)NULL,
        MB_OK);

  MessageBox (GetFocus (), (LPSTR)"into the intersected clipping region",
      (LPSTR)"I am about to do a TextOut and InvertRect...",
      MB_OK);

  TextOut (hDC, 0, 15,
      "THIS LINE HERE IS VERY LONG . WILL IT ALL BE SHOWN IN THE CLIPPING REG
      (short)75);
  InvertRect (hDC, (LPRECT) & ClientRect);

  ReleaseDC (hWnd, hDC);
  DeleteObject (hRgn);

  return;
  }


ICONTEST.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\ICON\ICONTEST.C

/*
Date: 7/19/88
Function(s) demonstrated in this program: SetResourceHandler
Compiler version: 5.1
Description: This example is taken from Application Note 12 (Windows "Icon"
             utility). The SetResourceHandler should only be used with
             user defined resources. In this example a generic bitmap is
             read through ICONLIB.LIB and ICONLIB.EXE (both of this files are
             need) and displayed in ICONTEST as an icon. The function
             SetResourceHandler is used to have the user defined function
             ResourceHandler setup the bitmap as an icon when the bitmap
             is loaded.
*/

#include <windows.h>
#include <stdio.h>
#include "icontest.h"

typedef struct {
    short   csHotX;
    short   csHotY;
    short   csWidth;
    short   csHeight;
    short   csWidthBytes;
    short   csColor;
    char    csBits[ 1 ];
    } CURSORSHAPE;

typedef struct {
    short magic;
    CURSORSHAPE info;
    } CURSORFILEHEADER;

typedef CURSORFILEHEADER FAR *LPCURSOR;

static char szAppName [] = "ICONTEST" ;
static char szFuncName [] = "SetResourceHandler" ;
WORD hInst;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
    MSG        msg;
    WNDCLASS   wndclass;
    HWND       hWnd;
    HMENU      hMenu;

    if ( !hPrevInstance )
       {
       wndclass.style          = CS_HREDRAW | CS_VREDRAW;
       wndclass.lpfnWndProc    = WndProc;
       wndclass.cbWndExtra     = 0;
       wndclass.cbClsExtra     = 0;
       wndclass.hInstance      = hInstance;
       wndclass.hCursor        = LoadCursor( NULL, IDC_ARROW );
       wndclass.hIcon          = LoadIcon (NULL, IDI_APPLICATION);
       wndclass.hbrBackground  = GetStockObject( WHITE_BRUSH );
       wndclass.lpszMenuName   = "icontest";
       wndclass.lpszClassName  = szAppName;

      if ( !RegisterClass( &wndclass ) )
           return FALSE;
       }

    hMenu = LoadMenu( hInstance, (LPSTR)"icontest" );
    hInst = hInstance;

    hWnd = CreateWindow( szAppName,     /* window class name       */
            szFuncName,                 /* window caption          */
            WS_OVERLAPPEDWINDOW,        /* window style            */
            CW_USEDEFAULT,              /* initial x position      */
            0,                          /* initial y position      */
            CW_USEDEFAULT,              /* initial x size          */
            0,                          /* initial y size          */
            NULL,                       /* parent window handle    */
            hMenu,                      /* window menu handle      */
            hInstance,                  /* program instance handle */
            NULL );                     /* create parameters       */

    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    while ( GetMessage( ( LPMSG )&msg, NULL, 0, 0 ) )
       {
       TranslateMessage( ( LPMSG )&msg );
       DispatchMessage( ( LPMSG )&msg );
       }
    return( msg.wParam );
}

long FAR PASCAL WndProc( hWnd, iMessage, wParam, lParam )
HWND       hWnd;
unsigned   iMessage;
WORD       wParam;
LONG       lParam;
{
    HDC          hDC;

    switch ( iMessage )
    {
    case WM_INITMENU:
       InvalidateRect ( hWnd, NULL, TRUE );
       break;

    case WM_CLOSE:
       DestroyWindow ( hWnd );
       break;

    case WM_DESTROY:
       PostQuitMessage( 0 );
       break;

    case WM_COMMAND:
       IconTestCommand ( hWnd, wParam );
       break;

    default:
        return ( DefWindowProc( hWnd, iMessage, wParam, lParam ) );
    }
    return( 0L );
}

/*
**  ResourceHandler - routine to service "calculated" resources.
**  In this case, Icons.
**
**  A resource handler can be installed for each resource TYPE.
*/

HANDLE FAR PASCAL ResourceHandler( hRes, hResFile, hResIndex )
HANDLE hRes;
HANDLE hResFile;
HANDLE hResIndex;
{
    WORD       wSize;
    BYTE FAR   *lpIcon;
    int        nIndex;

    /* Process machine dependent ICON and CURSOR resources. */
    wSize = ( WORD )SizeofResource( hResFile, hResIndex );
    nIndex = 0;

    if ( !hRes )
       {
       if ( !( hRes = AllocResource( hResFile, hResIndex, 0L ) ) )
           return NULL;
       nIndex = -1;
       }

    while ( !( lpIcon = ( BYTE FAR * )GlobalLock( hRes ) ) )
    if ( !GlobalReAlloc( hRes, ( DWORD )wSize, 0 ) )
        return NULL;
    else
        nIndex = -1;

    if ( nIndex )
    if ( ( nIndex = AccessResource( hResFile, hResIndex ) ) != -1 &&
        _lread( nIndex, lpIcon, wSize ) != -1 )
        _lclose( nIndex );
    else
        {
        if ( nIndex != -1 )
        _lclose( nIndex );
        GlobalUnlock( hRes );
        return NULL;
        }

    /* Remove magic word. */
    wSize -= 2;
    while ( wSize-- )
       {
       *lpIcon = *( lpIcon+2 );
       lpIcon++;
       }

    GlobalUnlock( hRes );
    GlobalReAlloc( hRes, ( DWORD )wSize, 0 );

    return ( hRes );
}

void IconTestCommand ( hWnd, wCommand )
HWND hWnd;
WORD wCommand;
{
    FARPROC lpResourceHandler;
    FARPROC lpOld;
    HDC     hDC;
    HICON   hIcon;
    HANDLE  hAppDLL;
    HANDLE  hModule;
    int     nDrawn;


    switch ( wCommand )
       {
       case CMD_GETICON:
          DummyEntry (  );
          hDC = GetDC ( hWnd );
          TextOut ( hDC, 10, 10, ( LPSTR ) "LibIcon", 7 );

          hAppDLL = LoadLibrary ( (LPSTR)"ICONLIB.LIB" );

          if ( hAppDLL < 32 )
             MessageBox ( hWnd, (LPSTR)"Loading DLL failed!",
                (LPSTR)szFuncName, MB_OK );
          else
             {
             hModule = GetModuleHandle ( ( LPSTR )"ICONLIB" );
             if ( hModule != NULL )
                {
                lpResourceHandler = MakeProcInstance (
                   (FARPROC)ResourceHandler, hInst );
                                                    /* Install own handler. *
                lpOld = SetResourceHandler( hModule, RT_ICON,
                   lpResourceHandler );

                hIcon = LoadIcon ( hModule, ( LPSTR ) "LibIcon" );
                nDrawn = DrawIcon ( hDC, 10, 25, hIcon );

                FreeProcInstance( SetResourceHandler( hModule, RT_ICON,
                   ( FARPROC )lpOld ) );
                }
             else
                MessageBox ( hWnd, (LPSTR)"Resource Handlers not initialized"
                   (LPSTR)szFuncName, MB_OK );

             FreeLibrary ( hAppDLL );
             }
          ReleaseDC ( hWnd, hDC );
          break;

       default:
          return;
       }
}



INFLATE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\INFLATE.C

/*
 *   InflateRect
 *
 *   This program demonstrates the use of the InflateRect function. The
 *   InflateRect function increase or decreases the values in the given
 *   LPRECT structure according to the x and y parameters in the function
 *   call. To demonstrate the increase in size of the rectangle described
 *   by lpRect in this application, after InflateRect was called, the
 *   rectangle was inverted using InvertRect.
 */

#include "windows.h"

long  FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

  pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
  pHelloClass->hIcon          = LoadIcon( hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  LocalFree( (HANDLE)pHelloClass );
  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;
  HDC hDC;        /** handle to display context    **/
  RECT lpRect;    /** rectangle coordinates structure  **/

  HelloInit( hInstance );
  hWnd = CreateWindow((LPSTR)"Sample", (LPSTR)"Sample Application",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

/* Make window visible according to the way the app is activated */
  ShowWindow( hWnd, cmdShow );
  UpdateWindow( hWnd );

/** get handle to display context **/
  hDC = GetDC(hWnd);

/** fill lpRect with coordinate info for rectangle **/
  lpRect.left = 50;
  lpRect.top  = 50;
  lpRect.right = 150;
  lpRect.bottom = 150;

  MessageBox(GetFocus(), (LPSTR)"a small rectangle",
      (LPSTR)"I am about to InvertRect...", MB_OK);

/** invert pixels in lpRect **/
  InvertRect (hDC, (LPRECT) & lpRect);

  MessageBox(GetFocus(), (LPSTR)"the rectangle",
      (LPSTR)"I am about to InflateRect...", MB_OK);

/** inflate rect by 10 in x direction and 10 in y direction **/
  InflateRect((LPRECT) & lpRect, 10, 10);

  MessageBox(GetFocus(), (LPSTR)"the inflated rectangle",
      (LPSTR)"I am about to InvertRect...", MB_OK);

/** invert the inflated rect to show it is now bigger **/
  InvertRect (hDC, (LPRECT) & lpRect);

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }

  return msg.wParam;
}


/* Procedures which make up the window class. */
long  FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  switch (message)
  {
  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}




INTERSEC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\INTERSEC.C

/*
 *   IntersectRect
 *
 *   This example application demonstrates the use of the IntersectRect
 *   function. The IntersectRect function finds the largest area common
 *   to two RECT structures and puts the representation of the intersection
 *   in the RECT structure defined by the first parameter in the call to
 *   IntersectRect. IntersectRect is called twice in this application. The
 *   first time it is called, there is no area common to the two rectangles,
 *   the second time it is called, there is a common area.
 */

#include "windows.h"

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon          = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    HDC hDC;       /** handle to display context   **/
    RECT lpRect1;     /** rectangle coordinates structure   **/
    RECT lpRect2;     /** rectangle coordinates structure   **/
    RECT lpRect3;     /** rectangle coordinates structure   **/
    RECT destRect;     /** target rectangle coord structure  **/

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"Sample Application",
                        (LPSTR)"Sample Application",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,     /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

/** get handle to display context **/
   hDC = GetDC(hWnd);

/** fill lpRect1 with coordinate info for rectangle **/
   lpRect1.left = 10;
   lpRect1.top  = 10;
   lpRect1.right= 150;
   lpRect1.bottom=150;

/** fill lpRect2 with coordinate info for rectangle **/
   lpRect2.left = 160;
   lpRect2.top  = 10;
   lpRect2.right= 210;
   lpRect2.bottom=50;

/** fill lpRect3 with coordinate info for rectangle **/
   lpRect3.left = 30;
   lpRect3.top  = 30;
   lpRect3.right= 200;
   lpRect3.bottom=200;

   MessageBox(hWnd,(LPSTR)"three rectangles",
        (LPSTR)"I am about to InvertRect...",MB_OK);

/** invert pixels in lpRect1 **/
   InvertRect (hDC,(LPRECT)&lpRect1);

/** invert pixels in lpRect2 **/
   InvertRect (hDC,(LPRECT)&lpRect2);

/** invert pixels in lpRect3 **/
   InvertRect (hDC,(LPRECT)&lpRect3);

   TextOut(hDC,60,0,(LPSTR)"RECT 1",(int)6);
   TextOut(hDC,160,0,(LPSTR)"RECT 2",(int)6);
   TextOut(hDC,90,210,(LPSTR)"RECT 3",(int)6);

   MessageBox(hWnd,(LPSTR)"the intersection of rects 1 and 2",
        (LPSTR)"I am about to InvertRect...",MB_OK);

/** find intersection of lpRect1 and lpRect2 and place in destRect  **/
   IntersectRect((LPRECT)&destRect,(LPRECT)&lpRect1,(LPRECT)&lpRect2);

/** invert the intersection of lpRect1 and lpRect2 (should be empty) **/
   InvertRect (hDC,(LPRECT)&destRect);

   MessageBox(hWnd,(LPSTR)"the intersection of rects 1 and 3",
        (LPSTR)"I am about to InvertRect...",MB_OK);

/** find intersection of lpRect1 and lpRect3 and place in destRect  **/
   IntersectRect((LPRECT)&destRect,(LPRECT)&lpRect1,(LPRECT)&lpRect3);

/** invert the intersection of lpRect1 and lpRect2        **/
   InvertRect (hDC,(LPRECT)&destRect);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
  return DefWindowProc( hWnd, message, wParam, lParam );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


INVAL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\INVAL.C

/*
 *   InvalidateRect
 *
 *   This program demonstrates the use of the InvalidateRect function. The
 *   InvalidateRect function adds the given rectangle to the update region,
 *   which marks that rectangle for painting. InvalidateRect is called
 *   twice in this program: once with a specified rectangle identified by
 *   the lpRect parameter, and once with NULL sent as the parameter
 *   representing the rectangle to invalidate, which causes the whole
 *   client area to be invalidated. Both times the "bErase" paramter is
 *   TRUE which causes the given rectangles to be erased. Also, both times
 *   InvalidateRect is called, UpdateWindow is called immediately after to
 *   ensure that the rectangle is immediately redrawn.
 */

#include "windows.h"

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  DWORD rectcolor = RGB (0x22, 0x22, 0x22); /* color for the brush   */
  HDC hDC;     /* handle to display context        */
  HBRUSH hMyBrush;   /* handle to brush          */
  RECT lpRect;       /* structure to hold rectangle coordinates */

  if (!hPrevInstance)
    {
    WNDCLASS   HelloClass;

    HelloClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    HelloClass.hIcon          = LoadIcon (hInstance, NULL);
    HelloClass.lpszMenuName   = (LPSTR)NULL;
    HelloClass.lpszClassName  = (LPSTR)"Sample Application";
    HelloClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    HelloClass.hInstance      = hInstance;
    HelloClass.style          = CS_HREDRAW | CS_VREDRAW;
    HelloClass.lpfnWndProc    = HelloWndProc;

    if (!RegisterClass ( (LPWNDCLASS)&HelloClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"Sample Application", (LPSTR)"Sample Applicati
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

/* create brush to fill rectangle with */
  hMyBrush = CreateSolidBrush (rectcolor);

/* get handle to display context */
  hDC = GetDC (hWnd);

/* select brush into display context */
  SelectObject (hDC, hMyBrush);

/* draw a rectangle so we can see InvalidateRect's effects */
  Rectangle (hDC, 5, 5, 650, 250);

/* fill lpRect with coordinate information */
  lpRect.left = 10;
  lpRect.top  = 10;
  lpRect.right = 50;
  lpRect.bottom = 50;

/* notify user call to InvalidateRect about to occur */
  MessageBox (GetFocus (), (LPSTR)"a small rectangle",
      (LPSTR)"I am about to InvalidateRect...", MB_OK);

/* invalidate the rect.identified by lpRect (TRUE param. causes erase) */
  InvalidateRect (hWnd, (LPRECT) & lpRect, (BOOL)TRUE);

/* call UpdateWindow so that draw will take place immediately */
  UpdateWindow (hWnd);

/* notify user call to InvalidateRect about to occur */
  MessageBox (GetFocus (), (LPSTR)"the whole client area",
      (LPSTR)"I am about to InvalidateRect...", MB_OK);

/* invalidate the client area (TRUE param. causes erase) */
  InvalidateRect (hWnd, (LPRECT)NULL, (BOOL)TRUE);

/* call UpdateWindow so that draw will take place immediately */
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


INVALRGN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\INVALRGN.C

/*
 *   InvalidateRgn
 *
 *   This program demonstrates the use of the InvalidateRgn function.
 *   InvalidateRgn marks the given region for painting during the next
 *   "paint session." The next paint session starts after the next WM_PAINT
 *   message is received by the window. InvalidateRgn is called from WinMain
 *   in this sample application. UpdateWindow is called directly after
 *   InvalidateRgn to send a WM_PAINT message.
 */

#include "windows.h"

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;
  HRGN hRegion;
  HDC  hDC;
  RECT ClearRect;

  if (!hPrevInstance)
    {
    WNDCLASS   HelloClass;

    HelloClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    HelloClass.hIcon          = LoadIcon (hInstance, NULL);
    HelloClass.lpszMenuName   = (LPSTR)NULL;
    HelloClass.lpszClassName  = (LPSTR)"Sample Application";
    HelloClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    HelloClass.hInstance      = hInstance;
    HelloClass.style          = CS_HREDRAW | CS_VREDRAW;
    HelloClass.lpfnWndProc    = HelloWndProc;

    if (!RegisterClass ( (LPWNDCLASS)&HelloClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"Sample Application", (LPSTR)"Sample Applicati
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  hDC = GetDC (hWnd);
  hRegion = CreateEllipticRgn (5, 5, 220, 110);

  GetClientRect (hWnd, (LPRECT) & ClearRect);
  InvertRect (hDC, (LPRECT) & ClearRect);

  MessageBox (GetFocus (), (LPSTR)"Call InvalidateRgn",
      (LPSTR)"I am about to...", MB_OK);

  InvalidateRgn (hWnd, hRegion, TRUE);   /*  mark the region for painting
/*  TRUE parameter says erase first */
  UpdateWindow (hWnd);  /* force a paint */

  ReleaseDC (hWnd, hDC);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }


/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


INVERT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\INVERT.C

/*
 *   InvertRect
 *
 *   This program demonstrates the use of the InvertRect function. The
 *   InvertRect function inverts the contents of the given rectangle.
 *   In this application, two calls are made to InvertRect. The first
 *   inverts the pixels in a rectangle specified by lpRect. The second
 *   call inverts the whole client area.
 */

#include "windows.h"

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    WNDCLASS   HelloClass;

    HelloClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    HelloClass.hIcon          = LoadIcon (hInstance, NULL);
    HelloClass.lpszMenuName   = (LPSTR)NULL;
    HelloClass.lpszClassName  = (LPSTR)"Sample Application";
    HelloClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    HelloClass.hInstance      = hInstance;
    HelloClass.style          = CS_HREDRAW | CS_VREDRAW;
    HelloClass.lpfnWndProc    = HelloWndProc;

    if (!RegisterClass ( (LPWNDCLASS)&HelloClass))
      return FALSE;
    }

  hMenu = CreateMenu ();
  ChangeMenu (hMenu, NULL, "Invert!", 100, MF_APPEND);

  hWnd = CreateWindow ( (LPSTR)"Sample Application", (LPSTR)"InvertRect",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0,
                      NULL, hMenu, hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  HDC hDC;
  RECT rRect;

  switch (message)
    {
    case WM_COMMAND:
      if (wParam == 100)
        {
        hDC = GetDC (hWnd);

        rRect.left = 10; /* fill lpRect with coordinate info for rectangle */
        rRect.top  = 10;
        rRect.right = 150;
        rRect.bottom = 20;

        InvertRect (hDC, (LPRECT) &rRect);    /** invert pixels in lpRect **/
        ReleaseDC (hWnd, hDC);
        }
      else
        return DefWindowProc (hWnd, message, wParam, lParam);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


INVERTRG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\INVERTRG.C

/*
 *   InvertRgn
 *
 *   This program demonstrates the use of the InvertRgn function. InvertRgn
 *   inverts the pixels in the given region. InvertRgn is called from
 *   WinMain in this sample application.
 */

#include "windows.h"

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;
  HRGN hRegion;
  HDC  hDC;

  if (!hPrevInstance)
    {
    WNDCLASS   HelloClass;

    HelloClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    HelloClass.hIcon          = LoadIcon (hInstance, NULL);
    HelloClass.lpszMenuName   = (LPSTR)NULL;
    HelloClass.lpszClassName  = (LPSTR)"Sample Application";
    HelloClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    HelloClass.hInstance      = hInstance;
    HelloClass.style          = CS_HREDRAW | CS_VREDRAW;
    HelloClass.lpfnWndProc    = HelloWndProc;

    if (!RegisterClass ( (LPWNDCLASS)&HelloClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"Sample Application", (LPSTR)"InvertRgn Applic
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  hDC = GetDC (hWnd);
  hRegion = CreateEllipticRgn (5, 5, 220, 100);

/*******    invert the region "hRegion"    *******/
  if (!InvertRgn (hDC, hRegion))
    MessageBox (GetFocus (), (LPSTR)"InvertRgn failed",
        (LPSTR)" ", MB_OK);
  ReleaseDC (hWnd, hDC);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


ISCHILD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CHILD\ISCHILD.C

/*
 *
 *   IsChild
 *
 *   This program demonstrates the use of the IsChild function. IsChild
 *   determines if one window is a child of another. IsChild is called from
 *   WinMain in this sample application.
 */

#include "windows.h"

long  FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);
/* parent's window procedure */

long  FAR PASCAL ChildAProc(HWND, unsigned, WORD, LONG);
/* child A's window procedure */

long  FAR PASCAL ChildBProc(HWND, unsigned, WORD, LONG);
/* child B's window procedure */

HWND hChAWnd = NULL;  /* handle to Child A's window */
HWND hChBWnd = NULL;  /* handle to Child B's window */

/* Procedure called when the application is loaded for the first time */

BOOL HelloInit( hInstance )
HANDLE hInstance;
{
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

  pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
  pHelloClass->hIcon     = LoadIcon( hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName   = (LPSTR)"Sample Application";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc   = HelloWndProc;

  if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
  pHelloClass->hIcon     = LoadIcon( hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName   = (LPSTR)"CHILD A";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc   = ChildAProc;

  if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
  pHelloClass->hIcon     = LoadIcon( hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName   = (LPSTR)"CHILD B";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc   = ChildBProc;

  if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  LocalFree( (HANDLE)pHelloClass );
  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;
  BOOL  bChild;   /* return value from IsChild */

  HelloInit( hInstance );

  hWnd = CreateWindow((LPSTR)"Sample Application", (LPSTR)"IsChild (PARENT)",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

/* Make window visible according to the way the app is activated */
  ShowWindow( hWnd, cmdShow );
  UpdateWindow( hWnd );

  hChAWnd = CreateWindow((LPSTR)"CHILD A", (LPSTR)"Child A",
      WS_CHILD | WS_SIZEBOX | WS_VISIBLE | WS_CAPTION | WS_CLIPSIBLINGS,
      5, 5,
      150, 150,
      hWnd, 1,   hInstance, NULL);

  hChBWnd = CreateWindow((LPSTR)"CHILD B",   (LPSTR)"Child B",
      WS_CHILD | WS_SIZEBOX | WS_VISIBLE | WS_CAPTION | WS_CLIPSIBLINGS,
      270, 5,
      150, 150,
      hWnd,   2,   hInstance, NULL);

/***************************************************************************/

  MessageBox(GetFocus(), (LPSTR)"Child A is a Child of the Parent Window",
      (LPSTR)"Checking to see if...",
      MB_OK);

  bChild = IsChild(hWnd, hChAWnd);

  if (bChild)
    MessageBox(GetFocus(), (LPSTR)"IS a child of the Parent Window",
        (LPSTR)"'IsChild' says that Child A...",
        MB_OK);
  else
    MessageBox(GetFocus(), (LPSTR)"is NOT a child of the Parent Window",
        (LPSTR)"'IsChild' says that Child A...",
        MB_OK);


  MessageBox(GetFocus(), (LPSTR)"Child A is a child of Child B",
      (LPSTR)"Checking to see if...",
      MB_OK);

  bChild = IsChild(hChBWnd, hChAWnd); /* is Child A a child of Child B? */

  if (bChild)
    MessageBox(GetFocus(), (LPSTR)"IS a child of Child B",
        (LPSTR)"'IsChild' says that Child A...",
        MB_OK);
  else
    MessageBox(GetFocus(), (LPSTR)"is NOT a child of Child B",
        (LPSTR)"'IsChild' says that Child A...",
        MB_OK);

/***************************************************************************/

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }

  return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long  FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {
  case WM_LBUTTONDOWN:
    MessageBox(GetFocus(), (LPSTR)"Left Button Click", (LPSTR)"PARENT WINDOW"
        MB_OK);
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}


long  FAR PASCAL ChildAProc( hChAWnd, message, wParam, lParam )
HWND hChAWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {

  case WM_LBUTTONDOWN:
    MessageBox(hChAWnd, (LPSTR)"Left Button Click",
        (LPSTR)"CHILD A",
        MB_OK);
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hChAWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}


long  FAR PASCAL ChildBProc( hChBWnd, message, wParam, lParam )
HWND hChBWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {

  case WM_LBUTTONDOWN:
    MessageBox(hChBWnd, (LPSTR)"Left Button Click",
        (LPSTR)"CHILD B",
        MB_OK);
    break;

  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hChBWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}




ISDLGMSG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\ISDLGMSG.C

/*
 *   IsDialogMessage
 *
 *   This program demonstrates the use of the IsDialogMessage function.
 *   The IsDialogMessage function is usually used in a window's message
 *   loop to determine if messages are intended for modeless dialog boxes.
 *   If a message it intended for the given dialog box, IsDialogMessage
 *   processes the mesage for the dialog box. IsDialogMessage is called
 *   from WinMain in this sample application
 */

#include "windows.h"
#include "isdlgmsg.h"

HANDLE hInst;
HWND hToTheDialog = NULL;     /*** handle to the modeless dialog box ***/

FARPROC lpprocDialog;
long  FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);


BOOL FAR PASCAL DialogBoxProc (hDlg, message, wParam, lParam)
HWND hDlg;
unsigned  message;
WORD wParam;
LONG lParam;
{
  switch (message)
  {
  case WM_INITDIALOG:
    return TRUE;
    break;

  case WM_COMMAND:
    switch (wParam)
    {
    case TOP_CONTROL:
      MessageBox (NULL, (LPSTR)"The message was processed",
          (LPSTR)" ", MB_OK);
      break;

    case ID_OK:
      EndDialog (hDlg, TRUE);
      break;
    }
    break;

  case WM_DESTROY:
    hToTheDialog = NULL;
    return TRUE;
    break;

  default:
    return FALSE;
    break;
  }
}


/* Procedure called when the application is loaded for the first time */
BOOL HelloInit (hInstance)
HANDLE hInstance;
{
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));

  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon          = LoadIcon (hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree ( (HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  HelloInit (hInstance);
  hMenu = LoadMenu (hInstance, "isdlgmsg");

  hWnd = CreateWindow ( (LPSTR)"Sample Application", (LPSTR)"IsDialogMessage"
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, hMenu, hInstance, NULL);
  hInst = hInstance;

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
  {
    if (hToTheDialog == NULL || !IsDialogMessage (hToTheDialog, &msg))
    {/*  Make sure the message is meant for this window...  */

      TranslateMessage ( (LPMSG) & msg);
      DispatchMessage ( (LPMSG) & msg);
    }
  }
  return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long  FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {
  case WM_COMMAND:
    if (wParam == 80)
    {
      lpprocDialog = MakeProcInstance ( (FARPROC)DialogBoxProc, hInst);
      hToTheDialog = CreateDialog (hInst, MAKEINTRESOURCE (2), hWnd,
          lpprocDialog);
    }
    break;

  case WM_DESTROY:
    FreeProcInstance ( (FARPROC)lpprocDialog);
    PostQuitMessage (0);
    break;

  default:
    return DefWindowProc (hWnd, message, wParam, lParam);
    break;
  }
  return (0L);
}




ISICONIC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\ICON\ISICONIC.C

/*
 *   IsIconic
 *
 *   This program demonstrates the use of the IsIconic function. The
 *   IsIconic function returns a boolean telling whether the  specified
 *   window is iconic. Choosing the "Iconic?" option in the system menu
 *   enacts the call to IsIconic in this sample application.
 */

#include "windows.h"
#define IDSABOUT 200

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);


int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));

  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon             = LoadIcon (hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName     = (LPSTR)"Sample Application";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree ( (HANDLE)pHelloClass);

  hWnd = CreateWindow ( (LPSTR)"Sample Application", (LPSTR)"Sample Applicati
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0,
                      NULL,     NULL, hInstance, NULL);

/* Insert "Iconic?" into system menu */
  hMenu = GetSystemMenu (hWnd, FALSE);
  ChangeMenu (hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
  ChangeMenu (hMenu, 0, (LPSTR)"Iconic?", IDSABOUT, MF_APPEND | MF_STRING);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
  {
  BOOL icon;   /** holds return value from call to IsIconic **/

  switch (message)
    {
    case WM_SYSCOMMAND:
      switch (wParam)
        {
        case IDSABOUT:
          icon = IsIconic (hWnd);    /**  is window iconic ?     **/
          if (icon)       /**  if yes, say so         **/
            MessageBox (hWnd, (LPSTR)"This window is iconic",
                (LPSTR)"ICONIC INFO", MB_OK);
          else /**  if window not iconic, say so  **/
            MessageBox (hWnd, (LPSTR)"This window is NOT iconic",
                (LPSTR)"ICONIC INFO", MB_OK);
          break;
        default:
          return DefWindowProc (hWnd, message, wParam, lParam);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


ISRECEMP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\ISRECEMP.C

/*
 *   IsRectEmpty
 *
 *   This example application demonstrates the use of the IsRectEmpty
 *   function. IsRectEmpty returns a boolean specifying whether or not
 *   the given rectangle is empty. A rectangle is empty if either the
 *   height or width is 0. IsRectEmpty is called twice in WinMain in this
 *   sample application. In the first call, IsRectEmpty is passed a non-
 *   empty rectangle. In the second call, it is passed an empty rectangle.
 */

#include "windows.h"

long  FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

  pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
  pHelloClass->hIcon          = LoadIcon( hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  LocalFree( (HANDLE)pHelloClass );
  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  HDC hDC;       /** handle to display context     **/
  RECT lpRect1;     /** rectangle coordinates structure     **/
  RECT lpRect2;     /** rectangle coordinates structure     **/
  BOOL EMPTY;      /** return value from IsRectEmpty calls **/

  HelloInit( hInstance );
  hWnd = CreateWindow((LPSTR)"Sample Application", (LPSTR)"Sample Application
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL,   NULL, hInstance, NULL);

/* Make window visible according to the way the app is activated */
  ShowWindow( hWnd, cmdShow );
  UpdateWindow( hWnd );

/** get handle to display context **/
  hDC = GetDC(hWnd);

/** fill lpRect1 with coordinate info for non-empty rectangle **/
  lpRect1.left = 10;
  lpRect1.top   = 10;
  lpRect1.right = 150;
  lpRect1.bottom = 150;

/** fill lpRect2 with coordinate info for  empty rectangle **/
  lpRect2.left = 260;
  lpRect2.top   = 10;
  lpRect2.right = 260;
  lpRect2.bottom = 200;

  MessageBox(GetFocus(), (LPSTR)"the non-empty rectangle",
      (LPSTR)"I am about to InvertRect...", MB_OK);

/** invert pixels in lpRect1  (the non-empty rectangle) **/
  InvertRect (hDC, (LPRECT) & lpRect1);

  MessageBox(GetFocus(), (LPSTR)"with this non-empty rectangle",
      (LPSTR)"I am about to call IsRectEmpty...", MB_OK);

/** see is lpRect1 is empty **/
  EMPTY = IsRectEmpty((LPRECT) & lpRect1);
  if (EMPTY)
    MessageBox(GetFocus(), (LPSTR)"meaning the rectangle IS empty",
        (LPSTR)"IsRectEmpty returned TRUE...", MB_OK);
  else
    MessageBox(GetFocus(), (LPSTR)"meaning the rectangle is NOT empty",
        (LPSTR)"IsRectEmpty returned FALSE...", MB_OK);

  InvalidateRect(hWnd, NULL, TRUE);

  MessageBox(GetFocus(), (LPSTR)"the EMPTY rectangle",
      (LPSTR)"I am about to InvertRect...", MB_OK);

/** invert pixels in lpRect2 (the empty rectangle) **/
  InvertRect (hDC, (LPRECT) & lpRect2);

  MessageBox(GetFocus(), (LPSTR)"with this empty rectangle",
      (LPSTR)"I am about to call IsRectEmpty...", MB_OK);

/** see is lpRect2 is empty **/
  EMPTY = IsRectEmpty((LPRECT) & lpRect2);
  if (EMPTY)
    MessageBox(GetFocus(), (LPSTR)"meaning the rectangle IS empty",
        (LPSTR)"IsRectEmpty returned TRUE...", MB_OK);
  else
    MessageBox(GetFocus(), (LPSTR)"meaning the rectangle is NOT empty",
        (LPSTR)"IsRectEmpty returned FALSE...", MB_OK);

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }

  return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long  FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  switch (message)
  {
  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}




ISWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\ISWIN.C

/*
 *   IsWindow
 *
 *   This program demonstrates the use of the IsWindow function. The IsWindow
 *   function checks to see if the given handle is indeed a handle to a valid
 *   window.
 */

#include "windows.h"

long  FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

  pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
  pHelloClass->hIcon     = LoadIcon( hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName   = (LPSTR)"Sample Application";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return FALSE;

  LocalFree( (HANDLE)pHelloClass );
  return TRUE;        /* Initialization succeeded */
}


int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  MSG   msg;
  HWND  hWnd;       /** VALID HANDLE TO VALID WINDOW  **/
  HWND invalWnd;     /** INVALID HANDLE TO PHONY WINDOW **/
  HMENU hMenu;
  BOOL isvalid;     /** BOOLEAN TO HOLD RETURN VALUE FROM IsWindow **/

/** INVALID ASSIGNMENT TO A HANDLE TO A WINDOW **/
  invalWnd = 44;

  HelloInit( hInstance );

/** VALID ASSIGNMENT TO A HANDLE TO A WINDOW   **/
  hWnd = CreateWindow((LPSTR)"Sample Application", (LPSTR)"Sample Application
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL,   NULL, hInstance, NULL);

/* Make window visible according to the way the app is activated */
  ShowWindow( hWnd, cmdShow );
  UpdateWindow( hWnd );
  MessageBox(GetFocus(), (LPSTR)"Checking if this window valid", (LPSTR)" ",
      MB_OK);

/** is hWnd a valid handle to a window? **/
  isvalid = IsWindow(hWnd);

/** if yes  **/
  if (isvalid)
/** say so **/
    MessageBox(GetFocus(), (LPSTR)"this window is valid", (LPSTR)"WINDOW INFO
        MB_OK);
  else /** if not valid, say so **/
    MessageBox(GetFocus(), (LPSTR)"this window is NOT valid", (LPSTR)"WINDOW
        MB_OK);

  MessageBox(GetFocus(), (LPSTR)"Checking if phoney window valid", (LPSTR)" "
      MB_OK);

/** is invalWnd a valid handle to a window? **/
  isvalid = IsWindow(invalWnd);
/** if yes, say so **/
  if (isvalid)
    MessageBox(GetFocus(), (LPSTR)"the phony window is valid", (LPSTR)"WINDOW
        MB_OK);
  else /** if not valid, say so **/
    MessageBox(GetFocus(), (LPSTR)"the phony window is NOT valid", (LPSTR)"WI
        MB_OK);

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }

  return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long  FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {
  case WM_DESTROY:
    PostQuitMessage( 0 );
    break;

  default:
    return DefWindowProc( hWnd, message, wParam, lParam );
    break;
  }
  return(0L);
}




ISZOOMED.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\ISZOOMED.C

/*
 *   IsZoomed
 *
 *   This program demonstrates the use of the IsZoomed function. The IsZoomed
 *   function returns a boolean telling whether or not the given window is
 *   zoomed (maximized). Choosing the "Zoomed?" option in the system menu
 *   enacts the call to IsZoomed in this sample application.
 */

#include "windows.h"
#define IDSABOUT 200

char  szAbout[10];

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc (LPTR, sizeof (WNDCLASS));

  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon             = LoadIcon (hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName     = (LPSTR)"Sample Application";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree ( (HANDLE)pHelloClass);

  hWnd = CreateWindow ( (LPSTR)"Sample Application", (LPSTR)"Sample Applicati
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0,
                      NULL, NULL, hInstance, NULL);

/* Insert "Zoomed?" into system menu */
  hMenu = GetSystemMenu (hWnd, FALSE);
  ChangeMenu (hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
  ChangeMenu (hMenu, 0, (LPSTR)"Zoomed?", IDSABOUT, MF_APPEND | MF_STRING);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
  {
  PAINTSTRUCT ps;
  BOOL Zoomed;

  switch (message)
    {
    case WM_SYSCOMMAND:
      switch (wParam)
        {
        case IDSABOUT:
/***********************************************************************/
          Zoomed = IsZoomed (hWnd);
          if (Zoomed)
            MessageBox (hWnd, (LPSTR)"This window is zoomed",
                       (LPSTR)"ZOOM INFO", MB_OK);
          else
            MessageBox (hWnd, (LPSTR)"This window is NOT zoomed",
                       (LPSTR)"ZOOM INFO", MB_OK);
/************************************************************************/
        break;

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

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


JOURNAL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\HOOKS\JOURNAL\JOURNAL.C

/*  Journal - Dynamic Link Library Demonstrating Windows 2.0 Journal Hooks.
*
*   Programmer:
*       Eric Fogelin
*       Microsoft Technical Support
*
*   Purpose:
*       DLL entry points and hook function call-backs.
*
*   Functions:
*       StartRecord() - Entry point for initiating message recording to file.
*       StopRecord()  - Entry point for halting recording.
*       StartPlay()   - Entry point for initiating message playback from file
*       StopPlay()    - Entry point to halt message playback.
*       Record()      - Call-back for WH_JOURNALRECORD hook function.
*       Play()        - Call-back for WH_JOURNALPLAYBACK hook function.
*       LIBINIT.ASM   - MASM initialization code.  Used to get library
*                       instance handle.
*
*   Description:
*       Windows 2.0 introduces new hook functions, WH_JOURNALRECORD and
*       WH_JOURNALPLAYBACK, which hook into the system message queue
*       allowing keyboard and mouse messages to be recorded for later
*       playback.  A natural use of these functions is for creating
*       demos and test suites, though other imaginative uses must also
*       exist.  This DLL could be easily referenced by any application
*       to quickly add a demo mode.  Note: Use extreme care when developing
*       a demo file.  Window position may change, overlapped window
*       ordering may be different, and display device may vary.  This
*       will impact on demos using the mouse to open windows, move
*       windows, manipulate dialog boxes, etc.  Note:  Journal hooks
*       are disabled by system modal dialog/message boxes.  This is a
*       design feature that must be taken into consideration.
*
*   Limits:
*       Very little error checking is used.  This should be added to any
*       "real" app.  I have indicated areas that require error checking.
*       The hook functions read and write directly to disk via low-level
*       functions, read() and write().  This impacts on performance.
*       Using a 512 or 1024 byte buffer is recommended.  Remember, do
*       not use C run-time buffered stream I/O functions.
*
*   History:
*       2/15/87    - Initial version
*       2/22/87    - Cleaned up
*       2/22/87    - Documentation
*/

#include "windows.h"
#include "memory.h"
#include "dos.h"

/* File used to record/play messages */
#define FILENAME "DIARY.BIN"

/* System queue message structure */
typedef struct sysmsg {
    unsigned message;
    WORD wParam1;
    WORD wParam2;
    DWORD lParam;
} SYSMSG;
typedef SYSMSG FAR *LPSYSMSG;

/* Static definitions for hooks and chains */
FARPROC lpprocRecord;
FARPROC lplpfnNextRecord;
FARPROC lpprocPlay;
FARPROC lplpfnNextPlay;

/* Global variables (Defined in DLL's DGROUP) */
HANDLE          hFile;
OFSTRUCT        of;
SYSMSG          bufMsg;
char far        *lpTmp;
int             nNumMsg, nMsgCtr;
BOOL            bRecord, bPlay;
DWORD           dwBaseTime;

/* Handle to the DLL instance from Libinit.asm */
extern HANDLE   LIBINST;

/* Function proto-types */
DWORD   FAR PASCAL Record( int, WORD, LPSYSMSG );
DWORD   FAR PASCAL Play( int, WORD, LPSYSMSG );
void    FAR PASCAL StartRecord();
void    FAR PASCAL StopRecord();
void    FAR PASCAL StartPlay();
void    FAR PASCAL StopPlay();

/* Undocumented Kernel Function proto-types.  See C run-time doc for
   description of related functions and their parameters. */
int     FAR PASCAL _lclose( int );
int     FAR PASCAL _llseek( int, long, int );
int     FAR PASCAL _lread( int, LPSTR, int );
int     FAR PASCAL _lwrite( int, LPSTR, int );

/*  StartRecord() - Set WH_JOURNALRECORD Hook.
*
*   Programmer:
*       Eric Fogelin
*       Microsoft Technical Support
*
*   Purpose:
*       Initialize for and set WN_JOURNALRECORD Hook.
*
*   Arguments:
*       none
*
*   Return Value:
*       void
*
*   Globals (modified):
*       hFile            - Handle to write-only file.
*       bRecord          - Boolean indicating state of Record hook.
*       dwBaseTime       - Reference system time when recording started.
*       lpprocRecord     - Procedure-instance address of call-back fcn.
*       lplpfnNextRecord - Procudure-instance address of any previous
*                          Record hook.  Note: Chaining may not be
*                          applicable.
*
*   Globals (referenced):
*       LIBINST       - Handle to instance for LIBINIT.ASM init. code.
*
*   Description:
*       Isolates the application from the actual hooking and unhooking
*       details.  Allows the application to call high-level routines
*       which take care of the dirty work.
*
*   Limits:
*       Insufficient error checking.  See code for comments.
*
*   History:
*       2/15/87    - Initial version
*       2/22/87    - Cleaned up
*       2/22/87    - Documentation
*/
void FAR PASCAL StartRecord()
{
    /* Do not allow recording while playing! DONE! */
    if (bPlay) {
       MessageBox( GetFocus(), (LPSTR)"Currently Playing!", (LPSTR)NULL, MB_O
       return;
    }

    /* Create write-only file, initialize OFSTRUCT, close. Add error checking
    hFile = OpenFile( (LPSTR)FILENAME, &of, OF_CREATE | OF_WRITE | OF_EXIST )

    /* Initialize: Record on, and Base Time. */
    bRecord = TRUE;
    dwBaseTime = GetTickCount();

    /* Set the Journal Record hook.  Add error checking! */
    lpprocRecord = MakeProcInstance( (FARPROC)Record, LIBINST);
    lplpfnNextRecord = SetWindowsHook( WH_JOURNALRECORD, lpprocRecord );

    return;
}
/*
*/

/*  StopRecord() - Unhook WH_JOURNALRECORD Hook.
*
*   Programmer:
*       Eric Fogelin
*       Microsoft Technical Support
*
*   Purpose:
*       Stop further recording by unhooking recording call-back fcn.
*
*   Arguments:
*       none
*
*   Return Value:
*       void
*
*   Globals (modified):
*       bRecord          - Boolean indicating state of Record hook.
*
*   Globals (referenced):
*       lpprocRecord     - Procedure-instance address of call-back fcn.
*
*   Description:
*       Isolates the application from the actual hooking and unhooking
*       details.  Allows the application to call high-level routines
*       which take care of the dirty work.
*
*   Limits:
*       What to do if UnhookWindowsHook fails?  Add error checking!
*
*   History:
*       2/15/87    - Initial version
*       2/22/87    - Cleaned up
*       2/22/87    - Documentation
*/
void FAR PASCAL StopRecord()
{
    /* Only unhook if currently hooked. */
    if (bRecord)
       UnhookWindowsHook( WH_JOURNALRECORD, lpprocRecord );
    /* Let the world know that hook is off */
    bRecord = FALSE;
    return;
}
/*
*/

/*  StartPlay() - Set WH_JOURNALPLAYBACK Hook.
*
*   Programmer:
*       Eric Fogelin
*       Microsoft Technical Support
*
*   Purpose:
*       Initialize for and set WN_JOURNALPLAYBACK Hook.
*
*   Arguments:
*       none
*
*   Return Value:
*       void
*
*   Globals (modified):
*       hFile          - Handle to read-only file.
*       nNumMsg        - Number of messages recorded (in file).
*       nMsgCtr        - Initialize message counter to zero.
*       bPlay          - Boolean indicating state of Play hook.
*       dwBaseTime     - Reference system time when playing started.
*       lpprocPlay     - Procedure-instance address of call-back fcn.
*       lplpfnNextPlay - Procudure-instance address of any previous
*                        Play hook.  Note: Chaining may not be
*                        applicable.
*
*   Globals (referenced):
*       bRecord       - Boolean indicating state of Record hook (modified
*                       if StopRecord() called).  See code.
*       LIBINST       - Handle to instance for LIBINIT.ASM init. code.
*
*   Description:
*       Isolates the application from the actual hooking and unhooking
*       details.  Allows the application to call high-level routines
*       which take care of the dirty work.
*
*   Limits:
*       Insufficient error checking.  See code for comments.
*
*   History:
*       2/15/87    - Initial version
*       2/22/87    - Cleaned up
*       2/22/87    - Documentation
*/
void FAR PASCAL StartPlay()
{
    /* Open file so the OFSTRUCT is initialized.  Add error checking! */
    hFile = OpenFile( (LPSTR)FILENAME, &of, OF_READ );
    /* Read the first message into buffer.  Required if HC_GETNEXT is
       first call to Playback hook function.  Must have message ready! */
    _llseek( hFile, 0L, 0 );
    _lread( hFile, (LPSTR)&bufMsg, sizeof(SYSMSG) );
    /* How many messages are stored? */
    nNumMsg = _llseek( hFile, 0L, 2 ) / sizeof(SYSMSG);
    /* Don't leave files open long */
    _lclose( hFile );

    /* If no messages were recorded, none to play back. DONE! */
    if (!nNumMsg) {
       MessageBox( GetFocus(), (LPSTR)"Nothing Recorded!", (LPSTR)NULL, MB_OK
       return;
    }

    /* Trick: Allows infinite loop to be set!  One can record the steps
       required to start playing.  This code turns off further recording. */
    if (bRecord)
       StopRecord();

    /* Initialize: First Message, Play on, and Base Time. */
    nMsgCtr = 0;
    bPlay = TRUE;
    dwBaseTime = GetTickCount();

    /* Set the Journal Playback hook.  Add error checking! */
    lpprocPlay = MakeProcInstance( (FARPROC)Play, LIBINST);
    lplpfnNextPlay = SetWindowsHook( WH_JOURNALPLAYBACK, lpprocPlay );

    return;
}
/*
*/

/*  StopPlay() - Unhook WH_JOURNALPLAYBACK Hook.
*
*   Programmer:
*       Eric Fogelin
*       Microsoft Technical Support
*
*   Purpose:
*       Stop further calls to playback function, Play(), by unhooking.
*
*   Arguments:
*       none
*
*   Return Value:
*       void
*
*   Globals (modified):
*       bPlay          - Boolean indicating state of Play hook.
*
*   Globals (referenced):
*       lpprocPlay     - Procedure-instance address of call-back fcn.
*
*   Description:
*       Isolates the application from the actual hooking and unhooking
*       details.  Allows the application to call high-level routines
*       which take care of the dirty work.
*
*   Limits:
*       What to do if UnhookWindowsHook fails?  Add error checking!
*
*   History:
*       2/15/87    - Initial version
*       2/22/87    - Cleaned up
*       2/22/87    - Documentation
*/
void FAR PASCAL StopPlay()
{
    /* Only unhook if currently hooked */
    if (bPlay)
       UnhookWindowsHook( WH_JOURNALPLAYBACK, lpprocPlay );
    /* Let the world know that hook is off */
    bPlay = FALSE;
    return;
}
/*
*/

/*  Record() - Copy system event messages to a file for later playback.
*
*   Programmer:
*       Eric Fogelin
*       Microsoft Technical Support
*
*   Purpose:
*       WH_JOURNALRECORD call-back hook function used to record messages.
*
*   Arguments:
*       nCode  - Hook code
*       wParam - Not used
*       lParam - Long pointer to a system message, LPSYSMSG.
*
*   Return Value:
*       DWORD value depends on Hook Code.
*
*   Globals (modified):
*       lpTmp            - Far pointer used to get DS for movedata().
*       bufMsg           - Temporary message storage.
*       hFile            - Handle to write-only file.
*
*   Globals (referenced):
*       dwBaseTime       - Reference system time when recording started.
*                          Used to compute elapsed time for later playback.
*                          Elapsed time is placed in bufMsg.lParam.
*
*   Description:
*       From hook function memo (modified):
*       "The hook code of interest is HC_ACTION.
*       wParam is unused.
*       lParam is a long pointer to a SYSMSG structure (LPSYSMSG)
*           with the current message.
*
*       The SYSMSG structure is identical to that used by the
*       WH_JOURNALPLAYBACK structure.  (see below).
*
*       I use this hook to record a sequence of user-initiated
*       events which I later playback, but there are other
*       uses I imagine.  Since the system time when one records
*       and when one plays back the recording will, in general,
*       be different, I keep a global variable (dwBaseTime) around
*       containing the time at the start of the sequence, and store
*       elapsed times in the lParam of the SYSMSG.  When I playback the
*       sequence, I convert those elapsed times into current
*       times by the inverse operation.
*
*       The return value from HC_ACTION is ignored.  Return 0L."
*
*   Limits:
*       Insufficient file error checking.  See code for comments.
*
*   History:
*       2/15/87    - Initial version
*       2/22/87    - Cleaned up
*       2/22/87    - Documentation
*/
DWORD FAR PASCAL Record( nCode, wParam, lParam )
int nCode;
WORD wParam;
LPSYSMSG lParam;
{
    /* If it ain't HC_ACTION, pass it along */
    if (nCode != HC_ACTION )
       return DefHookProc( nCode, wParam, (LONG)lParam, (FARPROC FAR *)&lplpf

    /* Need a long pointer for FP_SEG */
    lpTmp = (char far *)&bufMsg;
    /* Get a local copy of the message */
    movedata( FP_SEG( lParam ), FP_OFF( lParam ),
              FP_SEG( lpTmp ), FP_OFF( lpTmp ),
              sizeof(SYSMSG) );
    /* Compute a delta time from beginning recording.  Message time is
       in milliseconds from system power-on.  WARNING: Wrap not handled.
       Wrapping only a problem if system on continuously for ~50 days. */
    bufMsg.lParam -= dwBaseTime;

    /* Reopen write-only file using OFSTRUCT.  Add error checking. */
    hFile = OpenFile( (LPSTR)FILENAME, &of, OF_REOPEN | OF_WRITE );
    /* Seek to the end of the file */
    _llseek( hFile, 0L, 2 );
    /* Write the message to disk */
    _lwrite( hFile, (LPSTR)&bufMsg, sizeof(SYSMSG) );
    /* Don't leave files open long */
    _lclose( hFile );

    return 0L;
}
/*
*/

/*  Play() - Copy system event messages from file to system message queue.
*
*   Programmer:
*       Eric Fogelin
*       Microsoft Technical Support
*
*   Purpose:
*       WH_JOURNALPLAYBACK call-back hook function used to replay messages.
*
*   Arguments:
*       nCode  - Hook code
*       wParam - Not used
*       lParam - See Description section.
*
*   Return Value:
*       DWORD value depends on Hook Code.
*
*   Globals (modified):
*       lpTmp            - Far pointer used to get DS for movedata().
*       bufMsg           - Temporary message storage.
*       hFile            - Handle to read-only file.
*       nMsgCtr          - Message counter specifies current message.
*
*   Globals (referenced):
*       dwBaseTime       - Reference system time when playing started.
*                          Used to compute playback time from elapsed time.
*                          Elapsed time is in bufMsg.lParam.
*       nNumMsg          - Number of total messages to playback.
*
*   Description:
*       From hook function memo (modified):
*       "There are two hook codes of interest:
*
*       HC_GETNEXT
*       wParam is unused.
*       lParam is a long pointer to a SYSMSG structure (LPSYSMSG)
*           where the hook is to put the current messsage to playback.
*
*       HC_SKIP
*       wParam is unused.
*       lParam is unused.
*
*       The SYSMSG (System Queue Event) is like a MSG structure:
*       typedef struct {
*           unsigned message;
*           WORD wParam1;
*           WORD wParam2;
*           DWORD lParam;
*       } SYSMSG;
*       The message is a regular Window message (WM_*), the wParam1
*       is pretty much the same as the wParam for a  regular window
*       message, (e.g. a VK_* for a message of WM_KEYDOWN), and the
*       lParam is the current time (expressed as the number of
*       timer ticks since system generation--see GetTickCount()).
*
*       The hook is used as follows.  Windows, after this hook
*       is installed, disables hardware input.  It will call this
*       hook in lieu of using the system queue until the hook is removed
*       via UnhookWindowsHook.  Whenever the hook gets a HC_GETNEXT,
*       it should poke a SYSMSG through the long pointer given in the
*       lParam and return the time in timer ticks that needs to
*       elapse before the event is ready to be played.  The lParam
*       field of the SYSMSG should also contain the time (not delta
*       time) to play the event.  If the time to play the event is
*       now, or has passed, this hook should return 0L.  Whenever
*       the hook gets a HC_SKIP, it should fetch the next event to
*       poke through the lParam when it next gets a HC_GETNEXT,
*       i.e. it should prepare, but not do it.
*
*       NOTES:
*       - The hook may be called mutiple times with HC_GETNEXT
*           before getting a HC_SKIP.  The hook should keep returning
*           the same event through the lParam (with the same
*           time-to-be-played in the lParam of the SYSMSG), and a
*           decreasing elpased-time-until-event until it becomes
*           0L, whereafter it returns 0L.
*       - The first message the hook gets (of these two) can be either
*           HC_SKIP or HC_GETNEXT.  Your initialization  code should
*           be invariant.  (I do my initialization when I set the hook.)
*       - If you want to turn the hook off from within the hook, call
*           UnhookWindowsHook from the HC_SKIP case only.
*       - If you want to play events as fast as possible, you'll find
*           that simply returning 0L for every HC_GETNEXT and setting
*           the play time to the current time won't work.  (You hang).
*           I've had success using the mouse double-click speed +1 as
*           the minimum time delay between events (except where the
*           actual event times are less)."
*
*   Limits:
*       Insufficient file error checking.  See code for comments.
*
*   History:
*       2/15/87    - Initial version
*       2/22/87    - Cleaned up
*       2/22/87    - Documentation
*/
DWORD FAR PASCAL Play( nCode, wParam, lParam )
int nCode;
WORD wParam;
LPSYSMSG lParam;
{
    long delta;

    switch ( nCode ) {
        case HC_SKIP:
            /* Bump up the message counter */
            nMsgCtr++;
            /* Have all messages been played?  Stop playing, if yes */
            if (nMsgCtr >= nNumMsg)
               StopPlay();

            /* Get message ready for next HC_GETNEXT */
            /* Reopen read-only file using OFSTRUCT.  Add error checking. */
            hFile = OpenFile( (LPSTR)FILENAME, &of, OF_REOPEN | OF_READ );
            /* Seek to the next message */
            _llseek( hFile, (long)nMsgCtr*sizeof(SYSMSG), 0 );
            /* Get a copy of the message in a local buffer */
            _lread( hFile, (LPSTR)&bufMsg, sizeof(SYSMSG) );
            /* Don't leave files open long */
            _lclose( hFile );

            return 0L;
            break;

        case HC_GETNEXT:
            /* Need a long pointer for FP_SEG */
            lpTmp = (char far *)&bufMsg;
            /* Put the local copy of the message into queue.  Note: Do
               not modify local message copy; may be asked repeatedly
               for message before next message is requested! */
            movedata( FP_SEG( lpTmp ), FP_OFF( lpTmp ),
                      FP_SEG( lParam ), FP_OFF( lParam ),
                      sizeof(SYSMSG) );

            /* Compute a delta time from beginning playback.  Message time is
               in milliseconds from system power-on.  WARNING: Wrap not
               handled.  Wrapping only a problem if system on continuously
               for ~50 days. */
            lParam->lParam = bufMsg.lParam + dwBaseTime;

            /* How long from current time must message be played? */
            delta = lParam->lParam - GetTickCount();

            /* Return time in milliseconds unless it has already passed
               (delta less than 0).  If passed, return 0. */
            if (delta > 0)
                return delta;
            else
                return 0L;
            break;

        default:
            /* If it ain't HC_SKIP or HC_GETNEXT, pass it along */
            return DefHookProc( nCode, wParam, (LONG)lParam, (FARPROC FAR *)&
            break;
    }
}
/*
*/


KILLTIME.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TIME\KILLTIME.C

/*
 * Function demonstrated in this program: KillTimer
 * Compiler version: C 5.1
 *
 * Description:
 *   This program demonstrates the use of the KillTimer function. KillTimer
 *   kills the timer event associated with "hWnd" and having the same
 *   event identifier.
 */

#include "windows.h"

long   FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;
  WNDCLASS   HelloClass;

  if (!hPrevInstance)
    {
    HelloClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    HelloClass.hIcon          = LoadIcon (hInstance, NULL);
    HelloClass.lpszMenuName   = (LPSTR)NULL;
    HelloClass.lpszClassName  = (LPSTR)"Hello";
    HelloClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    HelloClass.hInstance      = hInstance;
    HelloClass.style          = CS_HREDRAW | CS_VREDRAW;
    HelloClass.lpfnWndProc    = HelloWndProc;

    if (!RegisterClass ( (LPWNDCLASS)&HelloClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"Hello",
                     (LPSTR)"KillTimer",
                     WS_OVERLAPPEDWINDOW,
                     CW_USEDEFAULT,
                     CW_USEDEFAULT,
                     CW_USEDEFAULT,
                     CW_USEDEFAULT,
                     (HWND)NULL,        /* no parent */
                     (HMENU)NULL,       /* use class menu */
                     (HANDLE)hInstance, /* handle to window instance */
                     (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  SetTimer (hWnd, 100, 500, (FARPROC)NULL);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  KillTimer (hWnd, 100);      /* Kill The Timer */
  return (int)msg.wParam;
  }

/*************************************************************************/
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_TIMER:
      MessageBeep(0);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


LIB.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\BIFFLIB\LIB.C

#include "string.h"
#include <stdio.h>
#include "io.h"
#include "fcntl.h"
#include "malloc.h"

#define CONVERT(x,y) (x=y,(char*)&x)
/* The SHUFFLE macros move the buffer pointer x to a specified
position y, convert the value there to the proper format, and then
put the buffer pointer back at its original position */

#define SHUFFLE(x,y) ((char*)x+y)
#define ISHUFFLE(x,y) *((int*)((char*)x+y))
#define DSHUFFLE(x,y) *((double*)((char*)x+y))


int BIFF_fp;    /* file handle */

typedef struct {
  unsigned long a:24;
} ATTR;
typedef char BYTE;



int create_BIFF(char *filename)

/* Creates a new BIFF file, replacing any files by the same name.  The
entire filename is required (basename + suffix) */

{
  int i;
  if ((BIFF_fp = open(filename, O_RDWR | O_TRUNC | O_BINARY | O_CREAT, 000040

    /* This section writes the BOF record */
    write(BIFF_fp, CONVERT(i,9), (unsigned)2);
    write(BIFF_fp, CONVERT(i,4), (unsigned)2);
    write(BIFF_fp, CONVERT(i,2), (unsigned)2);
    write(BIFF_fp, CONVERT(i,0x10), 2);
  }
  return(BIFF_fp);
}

int open_BIFF(char *filename)
/* Opens an existing BIFF file in readonly mode */
{
  return(BIFF_fp = open(filename, O_RDONLY | O_BINARY));
}

void dimension_BIFF(int frow, int lrow, int fcol, int lcol)
/* sets the dimension record in the BIFF file */
{
  int i;

    /* This section writes the dimension record */
  write(BIFF_fp, CONVERT(i,0), 2);
  write(BIFF_fp, CONVERT(i,8), 2);
  write(BIFF_fp, CONVERT(i,frow), 2);
  write(BIFF_fp, CONVERT(i,lrow+1), 2);
  write(BIFF_fp, CONVERT(i,fcol), 2);
  write(BIFF_fp, CONVERT(i,lcol+1), 2);
}

void save_BIFF(int type, int row, int col, char *data)
/* saves data to a previously created BIFF file */
{
  unsigned int i;
  static ATTR attribute = {0x000000};

  switch(type) {
    case 1:
      /* Writes a blank cell */
      write(BIFF_fp, CONVERT(i,1), 2);
            write(BIFF_fp, CONVERT(i,7), 2);
      write(BIFF_fp, CONVERT(i,row), 2);
      write(BIFF_fp, CONVERT(i,col), 2);
      write(BIFF_fp, (char *) &attribute, 3);
      break;
    case 2:
      /* Writes integer data */
      write(BIFF_fp, CONVERT(i,2), 2);
            write(BIFF_fp, CONVERT(i,9), 2);
      write(BIFF_fp, CONVERT(i,row), 2);
      write(BIFF_fp, CONVERT(i,col), 2);
      write(BIFF_fp, (char *) &attribute, 3);
      write(BIFF_fp, data, 2);
      break;
    case 4:
      /* Writes data of number type */
      write(BIFF_fp, CONVERT(i,3), 2);
            write(BIFF_fp, CONVERT(i,15), 2);
      write(BIFF_fp, CONVERT(i,row), 2);
      write(BIFF_fp, CONVERT(i,col), 2);
      write(BIFF_fp, (char *) &attribute, 3);
      write(BIFF_fp, data, 8);
      break;
    case 8:
      /* Writes a label */
      write(BIFF_fp, CONVERT(i,4), 2);
            write(BIFF_fp, CONVERT(i,8+strlen(data)), 2);
      write(BIFF_fp, CONVERT(i,row), 2);
      write(BIFF_fp, CONVERT(i,col), 2);
      write(BIFF_fp, (char *) &attribute, 3);
/* this next write depends on low byte order */
      write(BIFF_fp, CONVERT(i,strlen(data)), 1);
      write(BIFF_fp, data, i);
      break;
    case 16:
      /* Writes boolean type data */
      write(BIFF_fp, CONVERT(i,5), 2);
            write(BIFF_fp, CONVERT(i,9), 2);
      write(BIFF_fp, CONVERT(i,row), 2);
      write(BIFF_fp, CONVERT(i,col), 2);
      write(BIFF_fp, (char *) &attribute, 3);
      write(BIFF_fp, CONVERT(i,(*data?1:0)), 1);
      write(BIFF_fp, CONVERT(i,0), i);
      break;
  }
}

int close_BIFF()
/* Writes an EOF record, and closes the file */
{
  unsigned long int i = 0x000000a;

  write(BIFF_fp, (char *) &i, 4);
  return(close(BIFF_fp));
}

void read_BIFF(int gettype, int (*handler)(int, char *, int))
/* Reads all data records of a certain type */
{

  int type;   /* the BIFF type of the currently read record */
  int length;   /* the length of the current record */
  int intype;  /* the Library type of the current record */
  static BYTE buff[2080]; /* buffer containing the current record */
  static int map[7] = {0,1,2,4,8,16,32};
  int typeflag;
  BYTE boolflag;

  /* the map array serves to map the BIFF record types (e.g.
    label = record type 4) to the Library record type
    (where label = type 8)
  */

  do {
    read(BIFF_fp, (char *)&type, 2);
    read(BIFF_fp, (char *)&length, 2);
    intype = map[(type<7&&type>0) ? type : 0];
    switch((gettype & intype) | (intype & 32)) {
      case 1: case 2: case 4: case 8: case 16:
        read(BIFF_fp, (char *) buff, length);
        (*handler)(intype, (char *) buff, length);
        break;
      case 32:
        read(BIFF_fp, (char *) buff, length);
        typeflag = ISHUFFLE(buff, 13);
        boolflag = *SHUFFLE(buff, 7);
        if (typeflag == 0xFFFF) {
            if ((boolflag == 1) && (gettype & 16))
                (*handler)(16, (char *) buff, length);
        } else if (gettype & 4)
          (*handler)(4, (char *) buff, length);
        break;
      default:
        lseek(BIFF_fp, (long) length, SEEK_CUR);
      }
  } while(type != 0x0A);
}


int find_BIFF(int gettype, int row, int col, int (*handler)(int, char *, int)
{

  int type;     /* the BIFF record type of the current record */
  int intype;      /* the Library record type of the current record */
  int length;     /* the length of the current record */
  int rw, cl;     /* the row and column of the current record */
  int flag = 0;     /* used to determine if this is the first row
        record in a certain block */
  int rwMic, rwMac;  /* the first and last(+1) row in a document */
  int colMic, colMac; /*the first and last(+1) column in a certain row*/
  int dbRtcell;     /* the offset of the current row records */
  long int offset;   /* the cumulative offset for the row record */
  static BYTE buff[2080]; /* buffer containing the record contents */
  static long blockbuff[100];
        /* contains row block indices, size is arbitrary */
  static int map[7] = {0,1,2,4,8,16,32};
        /* Maps BIFF record types to Library record types */
  int typeflag;
  BYTE boolflag;

  /* Read the index record */
  lseek(BIFF_fp, 8L, SEEK_SET);
  read(BIFF_fp, (char *)&type, 2);
  if (type != 0x0B)
    return(1);
  read(BIFF_fp, (char *)&length, 2);
  lseek(BIFF_fp, 4L, SEEK_CUR);
  read(BIFF_fp, (char *)&rwMic, 2);
  read(BIFF_fp, (char *)&rwMac, 2);
  if(col < rwMic || col > rwMac-1)
    return(2);
  read(BIFF_fp, (char *)blockbuff, (rwMac-1-rwMic));

  /* move to the proper row block */
  lseek(BIFF_fp, blockbuff[(row-rwMic)/32] , SEEK_SET);
  do {
    /* Read the current Row record */
    read(BIFF_fp, (char *)&type, 2);
    if (type != 0x08)
      return(3);
    read(BIFF_fp, (char *)&length, 2);
    read(BIFF_fp, (char *)&rw, 2);
    read(BIFF_fp, (char *)&colMic, 2);
    read(BIFF_fp, (char *)&colMac, 2);

    lseek(BIFF_fp, 5L, SEEK_CUR);
    read(BIFF_fp, (char *)&dbRtcell, 2);

    /* If rgbAttr field is present, move over it */
    if (length == 20)
      lseek(BIFF_fp, 3L, SEEK_CUR);

    /* update offset (see BIFF document section
    "Finding Cell Values" for more information */
    if (flag == 0) {
      offset = tell(BIFF_fp) + dbRtcell;
      flag = 1;
    } else
      offset += dbRtcell;
  } while (rw < row);

  if (rw == row) {
    if (col < colMic || col > colMac)
      return(4);
    lseek(BIFF_fp, offset, SEEK_SET);

    /* Read the row's records until the proper column is reached*/
    do {
      read(BIFF_fp, (char *)&type, 2);
      read(BIFF_fp, (char *)&length, 2);
      read(BIFF_fp, (char *)&rw, 2);
      read(BIFF_fp, (char *)&cl, 2);
      lseek(BIFF_fp, (long)(length-4), SEEK_CUR);
    }  while (cl < col);

    if (cl == col) {
      /* Proper record is found.  Call handler routine */
      intype = map[(type<7&&type>0) ? type : 0];
      switch((gettype & intype) | (intype & 32)) {
          case 1: case 2: case 4: case 8: case 16:
        lseek(BIFF_fp, (long)(-length), SEEK_CUR);
        read(BIFF_fp, (char *) buff, length);
        (*handler)(intype, (char *) buff, length);
        return(0);
          case 32:
        lseek(BIFF_fp, (long)(-length), SEEK_CUR);
        read(BIFF_fp, (char *) buff, length);
        typeflag = ISHUFFLE(buff, 13);
        boolflag = *SHUFFLE(buff, 7);
        if (typeflag == 0xFFFF) {
            if ((boolflag == 1) && (gettype & 16))
                (*handler)(16, (char *) buff, length);
        } else if (gettype & 4)
          (*handler)(4, (char *) buff, length);
        return(0);

      }
    }
  }
  return(5);
}




void get_blank(char *data, int *row, int *col)
{

  *row = ISHUFFLE(data,0);
  *col = ISHUFFLE(data,2);
}

void get_integer(char *data, int *row, int *col, unsigned int *value)
{
  int *ptr;

  *row = ISHUFFLE(data,0);
  *col = ISHUFFLE(data,2);
  *value = ISHUFFLE(data,7);

}

void get_number(char *data, int *row, int *col, double *value)
{
  /* We do not have to check for the formula record case because the
     number value begins at the seventh byte in both cases. */

  *row = ISHUFFLE(data,0);
  *col = ISHUFFLE(data,2);
  *value = DSHUFFLE(data,7);
}

void get_label(char *data, int *row, int *col, char **string)
{
  int length;

  *row = ISHUFFLE(data,0);
  *col = ISHUFFLE(data,2);
  length = *SHUFFLE(data,7);
  *string = (char *) malloc((length+1) * sizeof(char));
  strncpy(*string, SHUFFLE(data,8), length);
  strncpy((char*)*string+length, '\0', 1);
}

void get_bool(char *data, int *row, int *col, int *value)
{
  int typeflag;

  *row = ISHUFFLE(data,0);
  *col = ISHUFFLE(data,2);
  typeflag = ISHUFFLE(data, 13);
  if (typeflag == 0xFFFF)
    *value = *SHUFFLE(data, 9);
  else
    *value = *SHUFFLE(data,7);
}


LINEDDA.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\LINEDDA.C

/*
 *   LineDDA
 *
 *   This program demonstrates the use of the LineDDA function. LineDDA
 *   performs a function for every point on the line from X1,X2 to Y1,Y2.
 *   LineDDA is called from Winmain in this sample application.
 */

#include "windows.h"

HDC hDC;

long FAR PASCAL HelloWndProc(HWND, unsigned, WORD, LONG);

void FAR PASCAL DrawLine(int,int,LPSTR);


/****************** procedure that LineDDA "calls" *********************/

void FAR PASCAL DrawLine(X,Y,lpData)
int X;
int Y;
LPSTR lpData;

{
switch (X % 3)
    {
    case 0:
       MoveTo(hDC,X+30,Y-1);
       LineTo(hDC,X-1,Y+11);
       break;

    default:
       break;
    }
return;
}

/***********************************************************************/


/* Procedure called when the application is loaded for the first time */
BOOL HelloInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pHelloClass;

    pHelloClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pHelloClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pHelloClass->hIcon    = LoadIcon( hInstance,NULL);
    pHelloClass->lpszMenuName   = (LPSTR)NULL;
    pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
    pHelloClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pHelloClass->hInstance      = hInstance;
    pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
    pHelloClass->lpfnWndProc    = HelloWndProc;

    if (!RegisterClass( (LPWNDCLASS)pHelloClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pHelloClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    HelloInit( hInstance );
    hWnd = CreateWindow((LPSTR)"Sample Application",
      (LPSTR)"LineDDA",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    hDC = GetDC(hWnd);

/************************    call LineDDA    **************************/

    LineDDA(0,0,200,200,(FARPROC)DrawLine,(LPSTR)NULL);

/**********************************************************************/

    ReleaseDC(hWnd,hDC);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL HelloWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
  return DefWindowProc( hWnd, message, wParam, lParam );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


LINETO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\LINETO.C

/*
 * Function demonstrated in this program: LineTo
 *
 * Description:
 *   This program demonstrates the use of the LineTo () function.
 *   LineTo () draws a line from the current position up to, but not includin
 *   the point specified by X, Y. It also updates the current position to X,
 *   In this program, LineTo () is called in response to a WM_PAINT message
 *   in HelloWndProc ().
 *
 */

#include "windows.h"

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG       msg;
  HWND      hWnd;
  HMENU     hMenu;
  WNDCLASS  HelloClass;

  if (!hPrevInstance)
    {
    HelloClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    HelloClass.hIcon          = LoadIcon (hInstance, NULL);
    HelloClass.lpszMenuName   = (LPSTR)NULL;
    HelloClass.lpszClassName  = (LPSTR)"LineTo";
    HelloClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    HelloClass.hInstance      = hInstance;
    HelloClass.style          = CS_HREDRAW | CS_VREDRAW;
    HelloClass.lpfnWndProc    = HelloWndProc;

    if (!RegisterClass ( (LPWNDCLASS)&HelloClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"LineTo",
                      (LPSTR)"LineTo ()",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      (HWND)NULL,           /* no parent */
                      (HMENU)NULL,          /* use class menu */
                      (HANDLE)hInstance,    /* handle to window instance */
                      (LPSTR)NULL);         /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }


/* Procedures which make up the window class. */
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  PAINTSTRUCT ps;

  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);

      MoveTo (ps.hdc, 100, 10);    /*  move current position to 100, 10 */
      LineTo (ps.hdc, 100, 200);   /*  draw from 100, 10 to 10, 200      */
      MoveTo (ps.hdc, 200, 10);    /*  move current position to 200, 10 */
      LineTo (ps.hdc, 200, 200);   /*  draw from 200, 10 to 200, 200     */
      LineTo (ps.hdc, 300, 10);    /* draw to 300, 10                      */

      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


LNOTIFY.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\LNOTIFY.C

/**************************************************************************
 * LNOTIFY.C - Demo Program for LocalNotify.
 *
 *
 * Compiled with MS C 5.1 & Windows SDK 2.03
 * Compiled on IBM-AT with 640K RAM.
 *
 **************************************************************************/

#include <windows.h>

/* PROTOTYPES */
int  PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
BOOL FAR PASCAL NotifyProc(WORD, HANDLE, WORD);

FARPROC  lpNotifyProc;
FARPROC  oldNotifyProc;

/***************************************************************************/

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE  hInstance;
HANDLE  hPrevInstance;
LPSTR    lpszCmdLine;
int  cmdShow;
{
  HANDLE   hMem;

  MessageBox(GetFocus(),
      (LPSTR)"This is a program to demonstrate LocalNotify. About to swap Not
      (LPSTR)"LocalNotify",
      MB_OK);

/* Get a relocatable procedure address. */
  lpNotifyProc = MakeProcInstance((FARPROC)NotifyProc, hInstance);

/* Replace the local-heap notification handler */
  oldNotifyProc = LocalNotify(lpNotifyProc);

  MessageBox(GetFocus(),
      (LPSTR)"About to send a message to the new Notify Procedure.",
      (LPSTR)"LocalNotify",
      MB_OK);

  hMem = LocalAlloc(LMEM_DISCARDABLE | LHND, 1024);  /* Request a 1K buffer.

  FreeProcInstance(LocalNotify(oldNotifyProc));                 /* Clean up.

  MessageBox(GetFocus(), (LPSTR)"Finished", (LPSTR)"LocalNotify", MB_OK);

  return (0);
} /* WINMAIN */


/***************************************************************************/
/*  NOTIFYPROC:  Local memory discarding notification procedure. */

BOOL FAR PASCAL NotifyProc(function, arg1, arg2)
WORD   function;
HANDLE arg1;
WORD   arg2;
{
  switch (function)
  {

  case LNOTIFY_OUTOFMEM:

    MessageBox(GetFocus(),
        (LPSTR)"Out of memory message received by new Notify Procedure.",
        (LPSTR)"LocalNotify",
        MB_OK);
    return(0);
    break;

  default:
    break;
  }
  return(arg2);
}





LOADACC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\ACCELL\LOADACC.C

/*
 *   LoadAccelerators
 *
 *   This program demonstrates the use of the LoadAccelerators function.
 *   The LoadAccelerators function loads an accelerator table. In this
 *   program, LoadAccelerators in called in LoadAccWindProc. The two
 *   accelerators that are loaded are ^A and ^B, which are accelerators
 *   for the menu choices "CHOICE1" and "CHOICE2."
 */

#include <windows.h>
#include "loadacc.h"

long    FAR PASCAL LoadAccWndProc (HWND, unsigned, WORD, LONG);

static HANDLE hAccelTable;        /*  handle to accelerator table  */

/**************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    WNDCLASS   LoadAccClass;

    LoadAccClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    LoadAccClass.hIcon          = LoadIcon (hInstance, NULL);
  /*---------------------- important for adding menu ------------------------
    LoadAccClass.lpszMenuName   = (LPSTR)"example";
  /*-------------------------------------------------------------------------
    LoadAccClass.lpszClassName  = (LPSTR)"Sample Application";
    LoadAccClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    LoadAccClass.hInstance      = hInstance;
    LoadAccClass.style          = CS_HREDRAW | CS_VREDRAW;
    LoadAccClass.lpfnWndProc    = LoadAccWndProc;

    if (!RegisterClass ( (LPWNDCLASS)&LoadAccClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"Sample Application",
      (LPSTR)"Sample Application",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
      (HMENU)NULL,       /* use class menu */
      (HANDLE)hInstance, /* handle to window instance */
      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
/* if translation of accelerator succesful */
    if (TranslateAccelerator (msg.hwnd, hAccelTable, (LPMSG) & msg) == 0)
      {
      TranslateMessage ( (LPMSG) & msg);
      DispatchMessage ( (LPMSG) & msg);
      }
    }
  return (int)msg.wParam;
  }

/* Procedures which make up the window class. */
long    FAR PASCAL LoadAccWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  PAINTSTRUCT    ps;
  TEXTMETRIC     tm;
  static short   Xchar, Ychar;
  HDC            hDC;
  HANDLE         hInstance;

  switch (message)
    {
    case WM_CREATE:
      hDC = GetDC (hWnd);
      GetTextMetrics (hDC, &tm);
      Xchar = tm.tmAveCharWidth;
      Ychar = tm.tmHeight + tm.tmExternalLeading;
      ReleaseDC (hWnd, hDC);
      hInstance = GetWindowWord (hWnd, GWW_HINSTANCE);
  /**** Load the accelerator table ***/
      hAccelTable = LoadAccelerators (hInstance, (LPSTR)"example");
      if (!hAccelTable)      /* if accelerator table not properly loaded */
        return FALSE;
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case CHOICE1:   /** can be chosen with accelerator ^A **/
          MessageBox (hWnd, (LPSTR)"CHOICE1 has been chosen",
              (LPSTR)"MENU INFO", MB_OK);
          break;

        case CHOICE2:   /** can be chosen with accelerator ^B **/
          MessageBox (hWnd, (LPSTR)"CHOICE2 has been chosen",
              (LPSTR)"MENU INFO", MB_OK);
          break;

        default:
          break;
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    case WM_PAINT:
      BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      TextOut (ps.hdc, Xchar, Ychar,
          (LPSTR)"To test accelerators press ^A or ^B", 35);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


LOADCURS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CURSOR\LOADCURS.C

/*
 *   LoadCursor
 *
 *   This program demonstrates the use of the LoadCursor function. The
 *   LoadCursor function loads either a standard windows cursor or a user
 *   defined cursor created with the Icon Editor. LoadCursor is called in
 *   LoadCursInit in this sample application.
 */

#include "windows.h"

long    FAR PASCAL LoadCursWndProc (HWND, unsigned, WORD, LONG);
int     PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
BOOL FAR PASCAL About (HWND, unsigned, WORD, LONG);

/***************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    WNDCLASS   LoadCursClass;

  /*----------------------- Invoke LoadCursor -------------------------------
    LoadCursClass.hCursor        = LoadCursor (hInstance, "mycursor");
  /*-------------------------------------------------------------------------
    LoadCursClass.hIcon          = LoadIcon (hInstance, NULL);
    LoadCursClass.lpszMenuName   = (LPSTR)NULL;
    LoadCursClass.lpszClassName  = (LPSTR)"Sample Application";
    LoadCursClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    LoadCursClass.hInstance      = hInstance;
    LoadCursClass.style          = CS_HREDRAW | CS_VREDRAW;
    LoadCursClass.lpfnWndProc    = LoadCursWndProc;

    if (!RegisterClass ( (LPWNDCLASS)&LoadCursClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"Sample Application",
      (LPSTR)"LoadCursor Application",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
      (HMENU)NULL,       /* use class menu */
      (HANDLE)hInstance, /* handle to window instance */
      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }


/***************************************************************************/
long    FAR PASCAL LoadCursWndProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
  /* Remove the cursor bitmap from memory or decrement the
           * reference count if it is greater than 1.
           */
      FreeResource (GetClassWord (hWnd, GCW_HCURSOR));
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


LOADICON.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\ICON\LOADICON.C

/*
Function(s) demonstrated in this program: LoadIcon
Description:  This function loads an icon.
*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "LoadIcon.h"

HWND     hWndParent1;
HANDLE   hInstMain;

char  szOutputBuffer1 [70];
char  szOutputBuffer2 [500];

struct {
  char  *szMessage;
} Messages [] = {
  "About\0",
  "     This is a sample application to demonstrate the\
use of the LoadIcon Windows function.",

  "Help Message",
  "     This program uses the LoadIcon Windows function\
to load the icon for this window.  Iconize this window\
to see if the function worked",

};


/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
HWND     hWnd;
int  MessageNumber;
{
  sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
  sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
  MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}


/****************************************************************************

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance ;
LPSTR       lpszCmdLine ;
int  nCmdShow ;
{
  static char  szAppName [] = "LoadIcon" ;
  HWND        hWnd ;
  WNDCLASS    wndclass ;
  MSG msg;
  short  xScreen, yScreen ;

  if (!hPrevInstance)
  {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
    wndclass.lpfnWndProc   = WndProc ;
    wndclass.cbClsExtra    = 0 ;
    wndclass.cbWndExtra    = 0 ;
    wndclass.hInstance     = hInstance ;
    wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName  = szAppName ;
    wndclass.lpszClassName = szAppName ;

    if (!RegisterClass (&wndclass))
      return FALSE ;
  }

  xScreen = GetSystemMetrics (SM_CXSCREEN) ;
  yScreen = GetSystemMetrics (SM_CYSCREEN) ;

hWndParent1 = CreateWindow (szAppName,     /* window class name       */
"LoadIcon",                 /* window caption          */
WS_OVERLAPPEDWINDOW,        /* window style            */
CW_USEDEFAULT,              /* initial x position      */
0,                          /* initial y position      */
CW_USEDEFAULT,              /* initial x size          */
0,                          /* initial y size          */
NULL,                       /* parent window handle    */
NULL,                       /* window menu handle      */
hInstance,                  /* program instance handle */
  NULL) ;                     /* create parameters       */

  ShowWindow (hWndParent1, nCmdShow) ;
  UpdateWindow (hWndParent1) ;

  hInstMain = hInstance;

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


/****************************************************************************

long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned  iMessage ;
WORD     wParam ;
LONG     lParam ;
{
  HMENU       hMenu;
  HDC         hDC;
  PAINTSTRUCT ps;
  static int  xClient, yClient;
  switch (iMessage)
  {
  case WM_CREATE:
    hMenu = GetSystemMenu (hWnd, FALSE);

    ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
        MF_APPEND | MF_STRING);
    break;

  case WM_SYSCOMMAND:
    switch (wParam)
    {
    case IDM_ABOUT:
      ProcessMessage (hWnd, 0);
      break;
    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
    }
    break;

  case WM_COMMAND:
    switch (wParam)
    {
    case IDM_HELP:
      ProcessMessage (hWnd, 2);
      break;
    }
    break;

  case WM_PAINT:
    BeginPaint(hWnd, (LPPAINTSTRUCT) & ps);
    EndPaint(hWnd, (LPPAINTSTRUCT) & ps);
    break;

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    {
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
    }
  }
  return (0L);
}





LOADMENU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\LOADMENU.C

/*
 *   LoadMenu
 *
 *   This program demonstrates the use of the LoadMenu function.
 *   LoadMenu loads a menu resource into memory. To put the menu resource
 *   in a window, SetMenu must be called after LoadMenu.
 */

#include "windows.h"

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

/**************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;

  if (!hPrevInstance)
    {
    WNDCLASS   HelloClass;

    HelloClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    HelloClass.hIcon          = LoadIcon (hInstance, NULL);
    HelloClass.lpszMenuName   = (LPSTR)NULL;
    HelloClass.lpszClassName  = (LPSTR)"Sample Application";
    HelloClass.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
    HelloClass.hInstance      = hInstance;
    HelloClass.style          = CS_HREDRAW | CS_VREDRAW;
    HelloClass.lpfnWndProc    = HelloWndProc;

    if (!RegisterClass ( (LPWNDCLASS)&HelloClass))
      return FALSE;
    }

  hWnd = CreateWindow ( (LPSTR)"Sample Application",
      (LPSTR)"LoadMenu Application",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
      (HMENU)NULL,       /* use class menu */
      (HANDLE)hInstance, /* handle to window instance */
      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  MessageBox (hWnd, (LPSTR)"call LoadMenu", (LPSTR)"I am about to...", MB_OK)

  hMenu = LoadMenu (hInstance, "loadmenu");       /* Load menu into memory */

  if (!hMenu)
    MessageBox (hWnd, (LPSTR)"LoadMenu failed", (LPSTR)NULL, MB_OK);
  else
    SetMenu (hWnd, hMenu); /* put the menu in the window */

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/**************************************************************************/
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


LOADRES.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\RESOURCE\LOADRES.C

/*
 *
 *  LoadResource
 *
 *  This program demonstrates the use of the function LoadResource.
 *  This function removes a loaded resource from memory by freeing
 *  the allocated memory occupied by that resource.
 */

#include "windows.h"

int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
{
  HANDLE hResInfo;
  HANDLE hResData;
  HANDLE hLib;
  BOOL bFreed;
  LPSTR lpResInfo;

  hLib = LoadLibrary( (LPSTR)"lib.exe" );
  hResInfo = FindResource( hLib, MAKEINTRESOURCE(63), RT_STRING );

  MessageBox (NULL, (LPSTR)"Loading resource", (LPSTR)"ok", MB_OK);

  hResData = LoadResource ( hLib, hResInfo );

  if ( hResData != NULL )
    MessageBox (NULL, (LPSTR)"Resource loaded", (LPSTR)"ok", MB_OK);
  else
    MessageBox (NULL, (LPSTR)"Resource not loaded", (LPSTR)"ok", MB_OK);

  bFreed = FreeResource ( hResData );
  return 0;
}




LOADSTR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\LOADSTR.C

/*
 *   LoadString
 *
 *   This program demonstrates the use of the LoadString function. The
 *   LoadString Function loads string resources identified by the second
 *   parameter. In this sample application, the string resource identifiers
 *   are STRING1 and STRING2.
 *
 */

#include <windows.h>
#include "loadstr.h"

char  szBuffer[26];   /* buffer to hold strings loaded via LoadString  */

long    FAR PASCAL HelloWndProc (HWND, unsigned, WORD, LONG);

/***************************************************************************/
/* Procedure called when the application is loaded for the first time */

BOOL HelloInit (hInstance)
HANDLE hInstance;
  {
  PWNDCLASS   pHelloClass;

  pHelloClass = (PWNDCLASS)LocalAlloc (LMEM_FIXED, sizeof (WNDCLASS));

  pHelloClass->hCursor        = LoadCursor (NULL, IDC_ARROW);
  pHelloClass->hIcon                 = LoadIcon (hInstance, NULL);
  pHelloClass->lpszMenuName   = (LPSTR)NULL;
  pHelloClass->lpszClassName  = (LPSTR)"Sample Application";
  pHelloClass->hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  pHelloClass->hInstance      = hInstance;
  pHelloClass->style          = CS_HREDRAW | CS_VREDRAW;
  pHelloClass->lpfnWndProc    = HelloWndProc;

  if (!RegisterClass ( (LPWNDCLASS)pHelloClass))
    return FALSE;

  LocalFree ( (HANDLE)pHelloClass);
  return TRUE;        /* Initialization succeeded */
  }


/***************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  MSG   msg;
  HWND  hWnd;
  HMENU hMenu;
  int  sizeString;  /* holds return value from LoadString */

  if (!hPrevInstance)
    HelloInit (hInstance);

  hWnd = CreateWindow ( (LPSTR)"Sample Application",
      (LPSTR)"Sample Application",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,      /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
 );

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

/* attempt to load string with identifier STRING1 */
  sizeString = LoadString (hInstance, STRING1, (LPSTR)szBuffer, 25);

  if (sizeString > 0)  /* if string with STRING1 identifier exists */
    MessageBox (hWnd, (LPSTR)szBuffer,
        (LPSTR)"The following string came via LoadString", MB_OK);
  else
    MessageBox (hWnd, (LPSTR)"No such string resource exists",
        (LPSTR)"ERROR", MB_OK);

/* attempt to load string with identifier STRING2 */
  sizeString = LoadString (hInstance, STRING2, (LPSTR)szBuffer, 25);

  if (sizeString > 0) /* if string with STRING2 identifier exists */
    MessageBox (hWnd, (LPSTR)szBuffer,
        (LPSTR)"The following string came via LoadString", MB_OK);
  else
    MessageBox (hWnd, (LPSTR)"No such string resource exists",
        (LPSTR)"ERROR", MB_OK);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  return (int)msg.wParam;
  }

/***************************************************************************/
long    FAR PASCAL HelloWndProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
  {
  switch (message)
    {
    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


LOCALHAN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOCALHAN.C

/*
 *  Function (s) demonstrated in this program: LocalHandle
 *  Description:
 *     This program will demonstrate the use of the LocalHandle function.
 *  It will allocate memory using LocalAlloc, get a pointer to that
 *  memory, and then check to make sure that LocalHandle returns the
 *  same handle that LocalAlloc did.
 *
 */

#include <windows.h>

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

/***************************************************************************/
int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int         nCmdShow;
  {
  HANDLE      hLocalMem;          /*  Handle to Local Memory  */
  HANDLE      hLocalHandleMem;    /*  Will hold returned handle  */
  PSTR        pszLocalMem;       /*  Near Pointer to memory  */

  hLocalMem = LocalAlloc (LMEM_MOVEABLE, 40);         /* Allocate memory */
  pszLocalMem = (PSTR) LocalLock (hLocalMem);         /* Get a pointer   */
  hLocalHandleMem = LocalHandle ( (WORD) pszLocalMem);

/*  Get the handle to the memory  */
  if (hLocalHandleMem == hLocalMem)
    MessageBox (GetFocus (), (LPSTR)"The two handles match", (LPSTR)"", MB_OK
  else
    MessageBox (GetFocus (), (LPSTR)"The two handles don't match",
        (LPSTR)"", MB_OK);

  LocalUnlock (hLocalMem);                          /* Unlock the memory */
  LocalFree (hLocalMem);                            /* Free the memory   */

  return (0L);
  }


LOCFLAG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOCFLAG.C

/*
 *  LocalFlags
 *
 *  This program demonstrates the use of the LocalFlags function. The
 *  program will allocate some memory using LocalAlloc, and then tell
 *  the user if that memory block has been discarded or if it is marked
 *  as discarded.
 */

#include <windows.h>

/***************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE  hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  HANDLE  hMemBlock;         /*  The memory block */
  WORD    wFlags;          /*  Return Value from function */
  char  szBuffer[80];   /*  Temporary Buffer for a string */
  int   sprintf ();          /*  Tell the compiler what will
                         *  be returned.
                           */

/*  Allocate 40 bytes of moveable, discardable memory and initialize
  *  all of the bytes to 0.
  */
  hMemBlock = LocalAlloc (LMEM_ZEROINIT | LMEM_MOVEABLE | LMEM_DISCARDABLE,
      (WORD) 40);

  wFlags = LocalFlags (hMemBlock);   /*  Get the info from LocalFlags  */

  if (wFlags & LMEM_DISCARDED)
    MessageBox (NULL, (LPSTR)"The allocated memory has been discarded.",
        (LPSTR)"Ok", MB_OK);

  if (wFlags & LMEM_DISCARDABLE)
    MessageBox (NULL, (LPSTR)"The allocated memory is discardable.",
        (LPSTR)"Ok", MB_OK);

  sprintf (szBuffer, "The Reference Count is %d",
      wFlags & LMEM_LOCKCOUNT);
/*  Masking out the lock or reference count  */

  MessageBox (NULL, (LPSTR) szBuffer, (LPSTR) "Ok", MB_OK);
/*  Display the lock count via a message box  */

  return 0;
  }


LOCFREE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOCFREE.C

/*
 *  LocalFree
 *
 *  This program demonstrates the use of the function LocalFree.  It
 *  allocates a block of memory, using LocalAlloc, and then simply
 *  frees the block.
 */

#include <windows.h>

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)

HANDLE  hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  HANDLE  hMemBlock;    /*  The memory block  */
  WORD  Flags;        /*  Return Value from function  */

/*  Allocate 40 bytes of moveable, discardable memory and initialize
  *  all of the bytes to 0.
  */
  hMemBlock = LocalAlloc (LMEM_ZEROINIT | LMEM_MOVEABLE | LMEM_DISCARDABLE,
      (WORD) 40);

  hMemBlock = LocalFree (hMemBlock);  /* Free the block of memory
                                   * and put the return code into
                                    * hMemBlock.
                                     */

  if (hMemBlock == NULL)
    MessageBox (NULL, (LPSTR)"LocalFree function Successful",
        (LPSTR)"OK", MB_OK);
/*  Tells user if successful  */
  else
    MessageBox (NULL, (LPSTR)"LocalFree function Unsuccessful",
        (LPSTR)"OK", MB_OK);
/*  Tells user if not successful  */

  return 0;
  }


LOCINIT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOCINIT.C

/**************************************************************************
 *  LOCINIT  version 1.00
 *
 * This program tests the LocalInit function, which initializes the local
 * heap at the specified segment location with the specified amount of
 * memory for the heap.
 *
 **************************************************************************/

#include <windows.h>
#include <stdio.h>

#define  HEAPSIZE  1024
#define  HEAPSEG  0

char  szPurpose[80] = "This is a program to initialize the local heap";
HANDLE  hLocMem;

/**************************************************************************/

int     PASCAL  WinMain (HANDLE, HANDLE, LPSTR, int);
BOOL              LocInit (HANDLE);
long    FAR PASCAL      LocInitWndProc (HWND, unsigned, WORD, LONG);

/***************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE  hInstance;
HANDLE  hPrevInstance;
LPSTR   lpszCmdLine;
int  cmdShow;
  {
  MSG  msg;
  BOOL  Init;
  HANDLE  hInst;
  HWND  hWnd;
  char  MesBuf[80];
  WORD  wMemsize;

  MessageBox (GetFocus (), (LPSTR)szPurpose, (LPSTR)"LOCINIT", MB_OK);

  if (!hPrevInstance)
/* Ensure that windows knows where to find parts of this
     * task on disk by Registering a window class. Registering
                 * a class binds an executable name to an internal name,
     * known to Windows. */
    if (LocInit (hInstance) == FALSE)
      return FALSE;

  hInst = hInstance;

  hWnd = CreateWindow ( (LPSTR) "locinit", /* Window class name */
  (LPSTR) "locinit", /* Window title */
  WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,               /* No parent */
  (HMENU)NULL,       /* Use the class menu */
  (HANDLE)hInstance,  /* .EXE file for Class */
  (LPSTR)NULL           /* No Parameters */
 );

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);             /* Paint the client area */

  wMemsize = LocalSize (hLocMem);

  sprintf (MesBuf, "New size of local heap: %d\nLocated at Segment: %d",
      HEAPSIZE, HEAPSEG);

  MessageBox (hWnd, (LPSTR)MesBuf, (LPSTR)"LocalInit", MB_OK);

  MessageBox (hWnd, (LPSTR)"Initialized and Accessed Local Heap Succesfully",
      (LPSTR)"LocalInit", MB_OK);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return (msg.wParam);
  }


/* WINMAIN */
/***************************************************************************/

BOOL    LocInit (hInstance)
HANDLE  hInstance;
  {
  NPWNDCLASS  npLocInitClass;
  BOOL      bLocInit;

  bLocInit = LocalInit ( (WORD)HEAPSEG, (WORD)0, (char *)HEAPSIZE);

  if (!bLocInit)
    MessageBox (GetFocus (), (LPSTR)"Local Initialization of Heap failed",
        (LPSTR)"LOCINIT", MB_ICONHAND | MB_OK);
  return FALSE;

  hLocMem = LocalAlloc (LMEM_DISCARDABLE, sizeof (WNDCLASS));
  npLocInitClass = (NPWNDCLASS)LocalLock (hLocMem);

  npLocInitClass->hCursor       = LoadCursor (NULL, IDC_ARROW);
  npLocInitClass->hIcon         = NULL;
  npLocInitClass->lpszMenuName  = (LPSTR)NULL;
  npLocInitClass->lpszClassName = (LPSTR)"LocInit";
  npLocInitClass->hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);
  npLocInitClass->hInstance     = hInstance;
  npLocInitClass->style         = CS_HREDRAW | CS_VREDRAW;
  npLocInitClass->lpfnWndProc   = LocInitWndProc;
  npLocInitClass->cbClsExtra    = 0;
  npLocInitClass->cbWndExtra    = 0;

  if (!RegisterClass ( (NPWNDCLASS)npLocInitClass))
/* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
    return (FALSE);

  return (TRUE);

  }


/* END locinitINIT */

/***************************** WINDOWPROC *****************************/
/*  Every message dispatched to any window of type "locinit" will
 *  result in a call to this procedure.
 */
long    FAR PASCAL LocInitWndProc (hWnd, identifier, wParam, lParam)
HWND    hWnd;    /* Intended window */
unsigned  identifier;  /* Message Number */
WORD    wParam;    /* 16 bit param */
LONG    lParam;    /* 32 bit param */
  {
  switch (identifier)
    {
    default:
      return DefWindowProc (hWnd, identifier, wParam, lParam);
      break;
    }

  return (0L);
  } /* windowproc */


LOCKRES.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\RESOURCE\LOCKRES.C

/*
 * Function (s) demonstrated in this program: LockResource
 *
 * Description:
 * This program uses a text file to store text which is brought in at
 * run time.  The functions FindResource and LoadResource are used to
 * place this text into memory.  Once it is in memory the function
 * LockResource is used to create a long pointer to the text so it can
 * be accessed.  LockResource also locks the text into the current
 * memory block so the long pointer will not become invalid.  Then the
 * text is massaged and output via a messagebox.
 *
*/

#include <windows.h>
#include "lockres.h"

static char  szFuncName [] = "LockResource";
static char  szAppName  [] = "LOCKRES";
static HANDLE   hInst;

/***************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance;
HANDLE      hPrevInstance;
LPSTR       lpszCmdLine;
int  nCmdShow;
  {
  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG         msg;
  HMENU       hMenu;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = (LPSTR)"Lock";
    wndclass.lpszClassName = szFuncName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hInst = hInstance;
  hMenu = LoadMenu (hInstance, (LPSTR)"Lock");

hWnd = CreateWindow (szFuncName,           /* window class name       */
szAppName,                  /* window caption          */
WS_OVERLAPPEDWINDOW,        /* window style            */
CW_USEDEFAULT,              /* initial x position      */
0,                          /* initial y position      */
CW_USEDEFAULT,              /* initial x size          */
0,                          /* initial y size          */
NULL,                       /* parent window handle    */
hMenu,                      /* window menu handle      */
hInstance,                  /* program instance handle */
  NULL);                      /* create parameters       */

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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


/***************************************************************************/

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HDC         hDC;
  HANDLE      hResource;
  LPSTR       lpText;
  LPSTR       lpTextTrunc;
  int  nIndex1;
  int  nIndex2;

  switch (iMessage)
    {
    case WM_INITMENU:
      InvalidateRect (hWnd, NULL, TRUE);
      break;

    case WM_COMMAND:
      switch (wParam)
        {
        case IDM_RES:
          hDC = GetDC (hWnd);
    /* Move the text into memory */
          hResource = LoadResource (hInst, FindResource (hInst,"Sample", "TEX

    /* Locking the text and creating a long pointer to it */
          lpText = LockResource (hResource);

    /* Massaging the text */
          lpTextTrunc = lpText;
          while (*lpTextTrunc != '\0' && *lpTextTrunc++ != '~');
            if (*lpTextTrunc != '\0')
              {
              lpTextTrunc--;
              *lpTextTrunc = '\0';
              }

    /* Outputting the text */
          MessageBox (hWnd, lpText, (LPSTR)szFuncName, MB_OK);

          FreeResource (hResource);
          ReleaseDC (hWnd, hDC);
          break;

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

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


LOCLALLO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOCLALLO.C

/*
 *   LocalAlloc
 *
 *   This program demonstrates the use of the LocalAlloc function.
 *   The LocalAlloc function allocates space for use in the local heap.
 */

#include <windows.h>

int sprintf();

typedef struct {    /* structure we are going */
    int x;    /* to allocate and lock   */
    int y;
         } MYSTRUCT;

typedef MYSTRUCT *lpMyPtr;  /* far pointer to MYSTRUCT type */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE hMemBlock;    /* Handle to memory block       */
    lpMyPtr  ThisPtr;    /* Pointer to MYSTRUCT structure   */
    char szBuff[80];    /* buffer for message box       */

/* allocate space in global heap for a MYSTRUCT structure */
    hMemBlock = LocalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,
        (long)sizeof(MYSTRUCT));

/* if memory allocated properly */
    if (hMemBlock != NULL)
  {
  MessageBox(NULL,(LPSTR)"The memory was allocated properly",
      (LPSTR)" ",MB_OK);

  /* lock memory into current address */
  ThisPtr = (lpMyPtr)LocalLock(hMemBlock);

  /* if lock worked */
  if (ThisPtr != NULL)
      {
      /* use memory from global heap and output results*/
      ThisPtr->x = 4;
      ThisPtr->y = 4;
      ThisPtr->x = ThisPtr->x*ThisPtr->y;
      sprintf(szBuff,"ThisPtr->x * ThisPtr->y = %d",ThisPtr->x);
      MessageBox(NULL,(LPSTR)szBuff,
          (LPSTR)"Info from LocalAlloc'ed memory",
          MB_OK);
      LocalUnlock(hMemBlock);    /* unlock block */
      LocalFree(hMemBlock);      /* free block   */
      }
  else ;
  }
    else
  MessageBox(NULL,(LPSTR)"The memory was not allocated",
      (LPSTR)" ",MB_OK);
    return 0;
}


LOCLCMPC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOCLCMPC.C

/*
 *   LocalCompact
 *
 *   This program demonstrates the use of the LocalCompact function. The
 *   LocalCompact function compacts the global heap. LocalCompact was
 *   called from WinMain in this sample application.
 */

#include "windows.h"

int sprintf();

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HANDLE    hMemBlock1;    /* Handle to memory block */
    HANDLE    hMemBlock2;    /* Handle to memory block */
    char szBuff[90];
    WORD ContigFreeBytes;
    char NEAR *   Rasta1, Rasta2;

/* LocalCompact to ask for 4096 continguous bytes */
    ContigFreeBytes = (WORD)LocalCompact((WORD)4096);
    sprintf(szBuff,"Number of contiguous free bytes before allocation = %u",
                  ContigFreeBytes);
    MessageBox(NULL,(LPSTR)szBuff,(LPSTR)" ",MB_OK);

/* Allocate 2 bytes from global heap */
    hMemBlock1 = LocalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DISCARDABLE,
        (long)2);
/* if block allocated properly */
    if (hMemBlock1 != NULL)
  /* lock block into memory */
  Rasta1 = (char NEAR *)LocalLock(hMemBlock1);

/* ask for 4096 contiguous free bytes */
    ContigFreeBytes = (WORD)LocalCompact((WORD)4096);
    sprintf(szBuff,"Number of contiguous free bytes = %u",ContigFreeBytes);
    MessageBox(NULL,(LPSTR)szBuff,(LPSTR)"After allocating 2 bytes...",MB_OK)

/* Allocate 200 bytes from local heap */
    hMemBlock2 = LocalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE |GMEM_DISCARDABLE,
        (long)200);
/* if memory allocated properly */
    if (hMemBlock2 != NULL)
  /* lock block into memory */
  Rasta2 = (char NEAR *)LocalLock(hMemBlock2);

/* ask for 4096 contiguous free bytes */
    ContigFreeBytes = (WORD)LocalCompact((WORD)4096);
    sprintf(szBuff,"Number of contiguous free bytes = %u",ContigFreeBytes);
    MessageBox(NULL,(LPSTR)szBuff,(LPSTR)"After allocating 200 bytes...",MB_O

    LocalUnlock(hMemBlock1);
    LocalUnlock(hMemBlock2);

    LocalFree(hMemBlock1);
    LocalFree(hMemBlock2);

/* ask for FFFF contiguous free bytes */
    ContigFreeBytes = (WORD)LocalCompact((WORD)4096);

    sprintf(szBuff,"Number of contiguous free bytes = %u",ContigFreeBytes);
    MessageBox(NULL,(LPSTR)szBuff,(LPSTR)"After unlocking 200 bytes...",MB_OK

    return 0;
}


LOCLOCK.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOCLOCK.C

/*
 *  LocalLock
 *
 *  This program demonstrates the use of the function LocalLock.  It
 *  allocates a block of memory, using LocalAlloc, Locks it, copies a string
 *  into it and displays it in a message box.
 */

#include <windows.h>

int PASCAL WinMain ( hInstance , hPrevInstance, lpszCmdLine, cmdShow )

HANDLE  hInstance , hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  HANDLE  hMemBlock;    /*  The memory block  */
  WORD    wFlags;     /*  Return Value from function  */
  char NEAR *  pBuffer;    /*  Pointer to locked buffer  */
  char *  strcpy();    /*  Tell compiler that it returns
           *  a pointer to a char
           */

  hMemBlock = LocalAlloc( LMEM_ZEROINIT | LMEM_MOVEABLE ,
       (WORD) 80 );

       /*  Allocate 80 bytes of moveable memory and initialize
  *  all of the bytes to 0
  */

  pBuffer = LocalLock ( hMemBlock );
       /*  Lock it and return the pointer  */

  if ( pBuffer != NULL )
    {
    strcpy ( pBuffer , "LocalLock was Successfull" );
    MessageBox( NULL , (LPSTR) pBuffer , (LPSTR) "OK" , MB_OK );
       /*  Display the message that all is OK  */
    }
  else
    MessageBox( NULL , (LPSTR)"LocalLock was not Successfull" ,
    (LPSTR)"OK" , MB_OK );

  return 0;
  }


LOCREALL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOCREALL.C

/*
 *  LocalReAlloc
 *
 *  This program demonstrates the use of LocalReAlloc.  It will allocate
 *  a block of memory using LocalAlloc, copy a string to the block of
 *  memory, enlarge the block, and then display the string using the
 *  MessageBox function.
 */

#include <windows.h>

int PASCAL WinMain ( hInstance , hPrevInstance, lpszCmdLine, cmdShow )

HANDLE  hInstance , hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  HANDLE  hMemBlock;    /*  The memory block  */
  HANDLE  hNewBlock;    /*  A handle to the new memory block  */
  WORD    wFlags;     /*  Return Value from function  */
  char NEAR *  pBuffer;    /*  Pointer to locked buffer  */
  char *  strcpy();    /*  Tell compiler that it returns
           *  a pointer to a char
           */

  hMemBlock = LocalAlloc( LMEM_ZEROINIT | LMEM_MOVEABLE ,
       (WORD) 70 );
       /*  Allocate 70 bytes of moveable memory and initialize
  *  all of the bytes to 0
  */

  pBuffer = LocalLock ( hMemBlock );
  if ( pBuffer != NULL )
    {
    strcpy ( pBuffer , "Both LocalReAlloc and LocalLock were Successfull" );
    LocalUnlock( hMemBlock );
       /*  Place string into pBuffer and unlock the memory.
  *  When increasing the size of the block, we don't have to worry
  *  about the contents.  They will still be intact, but there will
  *  be more memory available
  */
    }

  hNewBlock = LocalReAlloc( hMemBlock , 80 ,
          LMEM_MOVEABLE | LMEM_ZEROINIT );
       /*  Resized the block to 80 bytes.  It makes the new block moveable
  *  and also initializes any new bytes to zero
  */

  if ( hNewBlock != NULL )      /*  Check to see if successful  */
    {
    pBuffer = LocalLock ( hNewBlock );
       /*  Lock it and return the pointer  */

    if ( pBuffer != NULL )
      MessageBox( NULL , (LPSTR) pBuffer , (LPSTR) "OK" , MB_OK );
   /*  Display the message that all is OK  */
    else
      MessageBox( NULL ,
     (LPSTR)"LocalLock was not Successfull, but LocalReAlloc was",
     (LPSTR)"OK" , MB_OK );
   /*  Tell user that things went half right  */
    }
  else
    MessageBox( NULL , (LPSTR)"LocalReAlloc was not Successful" ,
    (LPSTR) "OK" , MB_OK );
  /*  Tell user that it didn't work at all  */

  return 0;
  }


LOCSHRNK.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOCSHRNK.C

/**************************************************************************
 *  LOCSHRNK  version 1.00
 *
 * This program tests the LocalShrink function, which shrinks the size of
 * the local heap and returns the current size. If the shrinksize is larger
 * than the current size, it will only return the current size.
 *
 * Using NULL for the first parameter will default to the current data
 * segment.
 *
 * compiled on IBM AT w640K EGA running WINDOWS 2.03
 **************************************************************************/

#include <windows.h>
#include <stdio.h>

#define  MADMAX  45000
#define  MAXHEAP  20480
#define  HEAPSIZE  2048

int PASCAL      WinMain(HANDLE,HANDLE,LPSTR,int);

char  szPurpose[80] = "This is a program to initialize the local heap";

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE   hInstance;
HANDLE   hPrevInstance;
LPSTR    lpszCmdLine;
int      cmdShow;
{
    HANDLE   hMemBlock;
    char     MesBuf[250];
    DWORD     dwMemSize;

   MessageBox(GetFocus(),(LPSTR)szPurpose,(LPSTR)"LOCINIT",MB_OK);

  /* Get size of local heap by giving meaningless shrink value */
   dwMemSize = LocalShrink(NULL, MADMAX);

   sprintf(MesBuf,"%s%lu","Size of local heap: ",dwMemSize);
   MessageBox(GetFocus(),(LPSTR)MesBuf,(LPSTR)"LocolShrink",MB_OK);

  /* Increase the size of the local heap */
   hMemBlock = LocalAlloc(LMEM_ZEROINIT | LMEM_MOVEABLE,(WORD)MAXHEAP);

   /* Get new size */
   dwMemSize = LocalShrink(NULL, MADMAX);

   sprintf(MesBuf,"%s%lu","New size of local heap: ",dwMemSize);
   MessageBox(GetFocus(),(LPSTR)MesBuf,(LPSTR)"Shrink",MB_OK);

  LocalFree(hMemBlock);

   /* Shrink local heap down to original size */
   dwMemSize = LocalShrink(NULL, HEAPSIZE);

   sprintf(MesBuf,"Size of local heap after actually shrinking: %lu",
     dwMemSize);
   MessageBox(GetFocus(),(LPSTR)MesBuf,(LPSTR)"Shrink",MB_OK);

   MessageBox(GetFocus(),(LPSTR)"Initialized and Accessed Local Heap Succesfu
     (LPSTR)"LocalInit",MB_OK);

   return (0);
} /* WINMAIN */




LOCSIZE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOCSIZE.C

/*
 *  LocalSize
 *
 *  This program demonstrates the use of the function LocalSize.  It
 *  allocates a block of memory, using LocalAlloc, Locks it, copies a string
 *  into it, displays it in a message box along with the size of the
 *  memory block.  (Which is returned by LocalSize)
 */

#include <windows.h>

int PASCAL WinMain ( hInstance , hPrevInstance, lpszCmdLine, cmdShow )

HANDLE  hInstance , hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  HANDLE  hMemBlock;    /*  The memory block  */
  WORD    wFlags;     /*  Return Value from function  */
  char NEAR *  pBuffer;    /*  Pointer to locked buffer  */
  int           bytes;            /*  Number of bytes allocated  */

  hMemBlock = LocalAlloc( LMEM_ZEROINIT | LMEM_MOVEABLE ,
       (WORD) 80 );

       /*  Allocate 80 bytes of moveable memory and initialize
  *  all of the bytes to 0
  */

  bytes = LocalSize( hMemBlock );
                  /*  Find out the size of hMemBlock  */

  pBuffer = LocalLock ( hMemBlock );
       /*  Lock it and return the pointer  */

  if ( pBuffer != NULL )
    {
    sprintf( (char *) pBuffer , "LocalAlloc allocated %d bytes" , bytes );
    MessageBox( NULL , (LPSTR) pBuffer , (LPSTR) "OK" , MB_OK );
       /*  Display the message that all is OK  */
    }
  else
    MessageBox( NULL , (LPSTR)"LocalLock was not Successfull" ,
    (LPSTR)"OK" , MB_OK );

  return 0;
  }


LOUNLOCK.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\LOCAL\LOUNLOCK.C

/*
 *  LocalUnlock
 *
 *  This program demonstrates the use of the LocalUnlock function.  It
 *  will allocate a block of memory using LocalAlloc, lock the
 *  memory with LocalLock, copy a string to it and display it with
 *  the MessageBox function, and then unlock the memory block with the
 *  local Unlock function.
 */

#include <windows.h>

int PASCAL WinMain ( hInstance , hPrevInstance, lpszCmdLine, cmdShow )

HANDLE  hInstance , hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  HANDLE  hMemBlock;    /*  The memory block  */
  WORD    wFlags;     /*  Return Value from function  */
  char NEAR *  pBuffer;    /*  Pointer to locked buffer  */
  char *  strcpy();    /*  Tell compiler that it returns
           *  a pointer to a char
           */

  hMemBlock = LocalAlloc( LMEM_ZEROINIT | LMEM_MOVEABLE ,
       (WORD) 80 );

       /*  Allocate 80 bytes of moveable memory and initialize
  *  all of the bytes to 0
  */

  pBuffer = LocalLock ( hMemBlock );
       /*  Lock it and return the pointer to the locked block  */

  if ( pBuffer != NULL )  /*  Make sure that it was locked
         *  Returns NULL if it wasn't
         */
    {
    strcpy ( pBuffer , "LocalLock was Successfull" );
       /*  Place the string into the block  */

    MessageBox( NULL , (LPSTR) pBuffer , (LPSTR) "OK" , MB_OK );
       /*  Display the message that all is OK  */

    LocalUnlock( hMemBlock );
       /*  Unlock Memory Block  */
    }
  else
    MessageBox( NULL , (LPSTR)"LocalLock was not Successfull" ,
    (LPSTR)"ERROR!!!" , MB_OK );

  return 0;
  }


LPTODP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\LPTODP.C

/*
 *  Function Name:   CreatePolyRgn
 *  Program Name:    crpolyrg.c
 *
 *  SDK Version:         2.03
 *  Runtime Version:     2.03
 *  Microsoft C Version: 5.1
 *
 *  Description:
 *   The program below will set the map mode to MM_LOENGLISH, then
 *   assign a POINT data structure the logical coordinates for making
 *   a poloygon (triangle).  The POINT structure will then be converted
 *   to device coordinates and displayed in MM_TEXT (device
 *   coordinates) map mode.
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_LPtoDP(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  POINT Points[4];
  BOOL    bConverted;


  SetMapMode(hDC, MM_LOENGLISH);

  Points[0].x = 100;                        /* logical points */
  Points[0].y = -300;                     /* in MM_LOENGLISH mode */
  Points[1].x = 100;
  Points[1].y = -200;
  Points[2].x = 500;
  Points[2].y = -300;
  Points[3].x = 100;
  Points[3].y = -300;
                                          /* conversion to device points */
  bConverted = LPtoDP(hDC, (LPPOINT)Points, 4);

  if (bConverted == FALSE)                   /* Check for error */
    MessageBox(hWnd, (LPSTR)"LPtoDP failed.", (LPSTR)"ERROR", MB_ICONHAND);

  SetMapMode(hDC, MM_TEXT);    /* back to MM_TEXT - Points now in device  */
  Polyline (hDC, (LPPOINT)Points, 4);               /* coordinates.       */
  TextOut(hDC, 10, 10, (LPSTR)"Logical points converted in program", 35);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"LPtoDP";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"LPtoDP",
                        (LPSTR)"LPtoDP()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_LPtoDP(hWnd, ps.hdc);
        ValidateRect(hWnd, (LPRECT) NULL);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}



MAKEPROC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\MAKEPROC.C

/*
 *
 *  MakeProcInstance
 *
 *  This program demonstrates the use of the functions MakeProcInstance.
 *  MakeProcInstance binds the segment of the model instance to the
 *  function pointed to by lpProc.
 *
 *  Other references: DlgOpen.c, DlgSave.c, Print.c
 *
 */

#include <windows.h>

static char  szAppName[] = "makeproc";
static char  szFuncName[] = "MakeProcInstance";
HANDLE hInst;

long  FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);
long  FAR PASCAL TestFarFunc (HWND, unsigned, WORD, LONG);

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
{
  HWND     hWnd;
  WNDCLASS rClass;
  MSG      msg;

  if (!hPrevInstance)
  {
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = NULL;
    rClass.lpszClassName = szAppName;

    if (!RegisterClass (&rClass))
      return FALSE;
  }

  hInst = hInstance;

hWnd = CreateWindow (szAppName,            /* window class name       */
szFuncName,                 /* window caption          */
WS_OVERLAPPEDWINDOW,        /* window style            */
CW_USEDEFAULT,              /* initial x position      */
0,                          /* initial y position      */
CW_USEDEFAULT,              /* initial x size          */
0,                          /* initial y size          */
NULL,                       /* parent window handle    */
NULL,                       /* window menu handle      */
hInstance,                  /* program instance handle */
  NULL);                      /* create parameters       */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage ((LPMSG) & msg);
    DispatchMessage ((LPMSG) & msg);
  }
  return (msg.wParam);
}


long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned  iMessage;
WORD     wParam;
LONG     lParam;
{
  HMENU   hMenu;
  FARPROC lpProc;

  switch (iMessage)
  {
  case WM_CREATE:
    hMenu = CreateMenu ();
    ChangeMenu (hMenu, NULL, (LPSTR)"Make", 100, MF_APPEND);
    SetMenu (hWnd, hMenu);
    break;
  case WM_COMMAND:
    if (wParam == 100)
    {
      MessageBox (GetFocus(), (LPSTR)"Making instance proc.",
          (LPSTR)szFuncName, MB_OK);
      lpProc = MakeProcInstance ((FARPROC)TestFarFunc, hInst);
      if (lpProc != NULL)
  MessageBox (GetFocus(), (LPSTR)"Instance proc. made",
      (LPSTR)szFuncName, MB_OK);
      else
  MessageBox (GetFocus(), (LPSTR)"Instance proc. not made",
      (LPSTR)szFuncName, MB_OK);
      FreeProcInstance (lpProc);
    }
    break;
  case WM_DESTROY:
    PostQuitMessage (0);
    break;
  default:
    return (DefWindowProc (hWnd, iMessage, wParam, lParam));
  }
  return (0L);
}


long  FAR PASCAL TestFarFunc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned  iMessage;
WORD     wParam;
LONG     lParam;
{
  return TRUE;
}




MAPDLGR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\MAPDLGR.C

/*
 *  Function (s) demonstrated in this program: MapDialogRect
 *  Description:
 *     When the About dialog box is brought up, it has two buttons.  The OK
 *  button to end the dialog box, and the DRAW button which draws an
 *  ellipse in the upper left hand corner.  Coordinates for the ellipse
 *  are converted from dialog coordinates to screen coordinates using
 *  the MapDialogRect function.
 */

#include "windows.h"
#include "mapdlgr.h"

HANDLE hInst;

/**************************************************************************/

int     PASCAL WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE    hInstance;
HANDLE    hPrevInstance;
LPSTR     lpCmdLine;
int       nCmdShow;
  {
  HWND hWnd;
  MSG msg;
  WNDCLASS WndClass;

  WndClass.style = NULL;
  WndClass.lpfnWndProc = MapDlgRectWndProc;
  WndClass.hInstance = hInstance;
  WndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  WndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
  WndClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  WndClass.lpszMenuName = (LPSTR) NULL;
  WndClass.lpszClassName = (LPSTR) "MapDlgRect";

  if (!RegisterClass ((PWNDCLASS)&WndClass))
    return FALSE;

  hInst = hInstance;

  hWnd = CreateWindow ("MapDlgRect", (LPSTR)"MapDlgRect Sample Application",
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT, 0,
                       CW_USEDEFAULT, 0,
                       NULL, NULL, hInstance, NULL);
  if (!hWnd)
    return (NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

  while (GetMessage (&msg, NULL, NULL, NULL))
    {
    TranslateMessage (&msg);
    DispatchMessage (&msg);
    }
  return (msg.wParam);
  }

long    FAR PASCAL MapDlgRectWndProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
  {
  FARPROC lpProcAbout;
  HMENU hMenu;

  switch (message)
    {
    case WM_SYSCOMMAND:           /* message: command from system menu */
      if (wParam == ID_ABOUT)
        {
        lpProcAbout = MakeProcInstance (About, hInst);
        DialogBox (hInst, "AboutBox", hWnd,        lpProcAbout);
        FreeProcInstance (lpProcAbout);
        break;
        }
      else
        return (DefWindowProc (hWnd, message, wParam, lParam));

    case WM_CREATE:
      hMenu = GetSystemMenu (hWnd, FALSE);
      ChangeMenu (hMenu, NULL, NULL, NULL, MF_APPEND | MF_SEPARATOR);
      ChangeMenu (hMenu, NULL, "A&bout MapDlgRect...", ID_ABOUT,
                  MF_APPEND | MF_STRING);
      break;

    case WM_DESTROY:                /* message: window being destroyed */
      PostQuitMessage (0);
      break;

    default:                        /* Passes it on if unproccessed    */
      return (DefWindowProc (hWnd, message, wParam, lParam));
    }
  return (NULL);
  }

BOOL FAR PASCAL About (hDlg, message, wParam, lParam)
HWND       hDlg;
unsigned   message;
WORD       wParam;
LONG       lParam;
  {
  RECT      rRect;     /*  Rectangle to draw elipse onto Dialog box  */
  HDC       hDC;       /*  Handle to display context  */

  switch (message)
    {
    case WM_INITDIALOG:                /* message: initialize dialog box */
      return (TRUE);

    case WM_COMMAND:                    /* message: received a command */
      if (wParam == IDOK)
        {         /* "OK" box selected?          */
        EndDialog (hDlg, NULL);          /* Exits the dialog box        */
        return (TRUE);
        }
      if (wParam == ID_DRAW)  /*  If they hit the Draw button, draw
                               *  an ellipse in the dialog box  */
        {
        hDC = GetDC (hDlg);      /* get DC for the dialog box */
        rRect.left = 0;          /* These coordinates are in dialog
                                  * box units.  They will be converted
                                  * to screen coordinates by the
                                  * MapDialogRect function  */
        rRect.top = 0;
        rRect.right = 20;
        rRect.bottom = 10;
        MapDialogRect (hDlg, (LPRECT) & rRect);
        Ellipse (hDC, rRect.left, rRect.top, rRect.right, rRect.bottom);
        ReleaseDC (hDlg, hDC);
        return (TRUE);
        }
      break;
    }
  return (FALSE);
  }


MAPMODE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\MAPMODE.C

/*
 *  SetMapMode
 *
 *  This function demonstrates the use of the SetMapMode function.  It will
 *  create a window, and procede to draw a triangle in the window in
 *  the MM_ANISOTROPIC mapping mode.
 */

#include <windows.h>

BOOL FAR PASCAL InitSetMapMode (HANDLE, HANDLE, int);
long    FAR PASCAL SetMapModeWindowProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, cmdShow)

HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
  {
  MSG  msg;

  InitSetMapMode (hInstance, hPrevInstance, cmdShow);   /*  Init Routine  */

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  exit (msg.wParam);
  }

BOOL FAR PASCAL InitSetMapMode (hInstance, hPrevInstance, cmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
int  cmdShow;
  {
  WNDCLASS  wcSetMapModeClass;
  HWND  hWnd;

  wcSetMapModeClass.lpszClassName = (LPSTR) "SetMapMode";
  wcSetMapModeClass.hInstance     = hInstance;
  wcSetMapModeClass.lpfnWndProc   = SetMapModeWindowProc;
  wcSetMapModeClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcSetMapModeClass.hIcon         = NULL;
  wcSetMapModeClass.lpszMenuName  = (LPSTR) NULL;
  wcSetMapModeClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcSetMapModeClass.style         = CS_HREDRAW | CS_VREDRAW;
  wcSetMapModeClass.cbClsExtra    = 0;
  wcSetMapModeClass.cbWndExtra    = 0;

  RegisterClass ( (LPWNDCLASS) & wcSetMapModeClass);

  hWnd = CreateWindow ( (LPSTR) "SetMapMode", (LPSTR) "SetMapMode",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,    0,
                      CW_USEDEFAULT,    0,
                      NULL,     NULL,   hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
  }

long    FAR PASCAL SetMapModeWindowProc (hWnd, message, wParam, lParam)

HWND      hWnd;
unsigned    message;
WORD      wParam;
LONG      lParam;
  {
  switch (message)
    {
    case WM_PAINT:
      PaintSetMapModeWindow (hWnd);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
      break;
    }
  return (0L);
  }

PaintSetMapModeWindow (hWnd)
HWND  hWnd;
  {
  PAINTSTRUCT  ps;
  HDC    hDC;
  POINT   lpTriangle[4];
  HANDLE        hOldBrush, hBrush;
  RECT    rRect;

  BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
  hDC = ps.hdc;

  hBrush = GetStockObject (GRAY_BRUSH);
  hOldBrush = SelectObject (hDC, hBrush);

  lpTriangle[0].x = 150;
  lpTriangle[0].y = 100;
  lpTriangle[1].x = 100;
  lpTriangle[1].y = 200;
  lpTriangle[2].x = 200;
  lpTriangle[2].y = 200;

  SetMapMode (hDC, MM_ANISOTROPIC);     /*  Set the mapping mode

  SetWindowExt (hDC, 300, 300);        /*  Set the extent of the drawing
                                        *  area.  This is the area that
                                        *  holds graphics that you create
                                        *  with GDI functions.  Do not
                                        *  confuse this function with
                                        *  the actual window.  The
                                        *  SetViewportExt sets the
                                        *  extent of the area to be mapped
                                        *  to which is the actual window
                                        */
  GetClientRect (hWnd, (LPRECT) & rRect);
/*  Get the size of the client area
            *  so that we can set the viewport
            *  extent
            */

  SetViewportExt (hDC, rRect.right, rRect.bottom);

  Polygon (hDC, lpTriangle, 3);

  ValidateRect (hWnd, (LPRECT) NULL);
  EndPaint (hWnd, (LPPAINTSTRUCT) & ps);

  SelectObject (hDC, hOldBrush);
  return TRUE;
  }


MESSBEEP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\MESSBEEP.C

/*
 *  MessageBeep
 *
 *  This program demonstrates the use of the MessageBeep function.
 *
 */

#include <windows.h>

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  if (MessageBeep (MB_OK) == FALSE)
    MessageBox (NULL, (LPSTR)"MessageBeep Failed", (LPSTR)"ERROR!!!", MB_OK);
  return 0;
  }


MESSBOX.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\MESSBOX.C

/*
 *  MessageBox
 *
 *  This program demonstrates the use of the MessageBox function.  It
 *  will display a simple message.
 */

#include <windows.h>

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MessageBox (GetFocus(),  /*  Because we have no parent window we feed it
                            *  the current focus.
                            */
  (LPSTR) "This is a Message Box",   /*  The message  */
  (LPSTR) "OK",                      /*  Message Header  */
  MB_OK);                            /* Type of buttons      */
  return 0;
  }


MOVETO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\MOVETO.C

/*
 *  MoveTo
 *
 *  This program will demonstrate the use of the MoveTo function.  It will
 *  draw a triangle using MoveTo and LineTo.
 */

#include <windows.h>

BOOL FAR PASCAL InitMoveTo (HANDLE, HANDLE, int);
long    FAR PASCAL MoveToWindowProc (HANDLE, unsigned, WORD, LONG);

int     PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int      cmdShow;
  {
  MSG  msg;

  InitMoveTo (hInstance, hPrevInstance, cmdShow);  /*  Init Routine  */
  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    {
    TranslateMessage ( (LPMSG) & msg);
    DispatchMessage ( (LPMSG) & msg);
    }
  exit (msg.wParam);
  }

BOOL FAR PASCAL InitMoveTo (hInstance, hPrevInstance, cmdShow)
HANDLE   hInstance;
HANDLE   hPrevInstance;
int      cmdShow;
  {
  WNDCLASS  wcMoveToClass;
  HWND      hWnd;

  wcMoveToClass.lpszClassName = (LPSTR) "MoveTo";
  wcMoveToClass.hInstance     = hInstance;
  wcMoveToClass.lpfnWndProc   = MoveToWindowProc;
  wcMoveToClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcMoveToClass.hIcon        = NULL;
  wcMoveToClass.lpszMenuName  = (LPSTR) NULL;
  wcMoveToClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcMoveToClass.style        = CS_HREDRAW | CS_VREDRAW;
  wcMoveToClass.cbClsExtra    = 0;
  wcMoveToClass.cbWndExtra    = 0;

  RegisterClass ( (LPWNDCLASS) & wcMoveToClass);

  hWnd = CreateWindow ( (LPSTR) "MoveTo", (LPSTR) "MoveTo",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,    0,
                      CW_USEDEFAULT,    0,
                      NULL,     NULL,   hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
  }

long    FAR PASCAL MoveToWindowProc (hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned    message;
WORD      wParam;
LONG      lParam;
  {
  switch (message)
    {
    case WM_PAINT:
      PaintMoveToWindow (hWnd);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
      break;
    }
  return (0L);
  }

PaintMoveToWindow (hWnd)
HWND  hWnd;
  {
  int   cX1, cY1, cX2, cY2;
  int   xinc, yinc;

  PAINTSTRUCT  ps;
  HDC    hDC;
  RECT    rRect;

  BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);  /* Prepare the client area */
  hDC = ps.hdc;            /*  Get the Display Context  */

  GetClientRect (hWnd, (LPRECT) & rRect);
/*  Get the size of the client area  */

  cX1 = rRect.left;       /*  Get the left side of the client area  */
  cY1 = rRect.top;       /*  Get the top of the client area  */
  cX2 = rRect.right;       /*  Get the right side of the client area  */
  cY2 = rRect.bottom;       /*  Get the bottom of the client area  */

  xinc = (cX2 - cX1) / 25;   /*  Figure out how much to increment  */
  yinc = (cY2 - cY1) / 25;  /*  x and y, evenly  */

  while (cX1 < rRect.right)
    {
    MoveTo (hDC, cX1, rRect.top);
/*  Move the pen to the desired location  */
    LineTo (hDC, rRect.right, cY1);
/*  Draw the line to the other side of the client area  */
    MoveTo (hDC, cX2, rRect.bottom);
/*  Move the pen to the desired location  */
    LineTo (hDC, rRect.left, cY2);
/*  Draw the line to the other side of the client area  */

    MoveTo (hDC, rRect.right, cY1);
/*  Move the pen to the desired location  */
    LineTo (hDC, cX2, rRect.bottom);
/*  Draw the line to the other side of the client area  */
    MoveTo (hDC, rRect.left, cY2);
/*  Move the pen to the desired location  */
    LineTo (hDC, cX1, rRect.top);
/*  Draw the line to the other side of the client area  */

    cX1 += xinc;
    cY1 += yinc;
    cX2 -= xinc;
    cY2 -= yinc;
    }
  ValidateRect (hWnd, (LPRECT) NULL);   /*  Disable any more paint messages
  EndPaint (hWnd, (LPPAINTSTRUCT) & ps);

  return TRUE;
  }


MOVEWIND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\MOVEWIND.C

/*
 *  MoveWindow
 *
 *  This function demonstrates the use of the MoveWindow function.  It will
 *  create a window, draw a pie slice in it, display a message box, and then
 *  move the window.
 */

#include <windows.h>

/* Forward Declarations  */

BOOL FAR PASCAL InitPie ( HANDLE , HANDLE , int );
long  FAR PASCAL PieWindowProc ( HANDLE , unsigned , WORD , LONG );

/*
 *  MAIN PROCEDURE
 */

int  PASCAL WinMain  (hInstance , hPrevInstance , lpszCmdLine , cmdShow )

HANDLE hInstance , hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
{
  MSG  msg;

  InitPie (hInstance, hPrevInstance, cmdShow );  /*  Init Routine  */

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

  exit(msg.wParam);
}


BOOL FAR PASCAL InitPie (hInstance , hPrevInstance , cmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
int  cmdShow;

{
  WNDCLASS  wcPieClass;
  HWND  hWnd;

  wcPieClass.lpszClassName = (LPSTR) "Pie";
  wcPieClass.hInstance     = hInstance;
  wcPieClass.lpfnWndProc   = PieWindowProc;
  wcPieClass.hCursor     = LoadCursor ( NULL , IDC_ARROW );
  wcPieClass.hIcon     = NULL;
  wcPieClass.lpszMenuName  = (LPSTR) NULL;
  wcPieClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcPieClass.style     = CS_HREDRAW | CS_VREDRAW;
  wcPieClass.cbClsExtra    = 0;
  wcPieClass.cbWndExtra    = 0;

  RegisterClass ((LPWNDCLASS) & wcPieClass);

  hWnd = CreateWindow((LPSTR) "Pie", (LPSTR) "MoveWindow",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,   0,
      CW_USEDEFAULT,   0,
      NULL,   NULL,   hInstance, NULL);

  ShowWindow (hWnd , cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
}


/*
 *  THE WINDOW PROCEDURE - Process messages
 */

long  FAR PASCAL PieWindowProc (hWnd , message , wParam , lParam)

HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
{
  static BOOL bFlag = FALSE;      /*  Tell us whether or not  */
/*  we have moved the  */
/*  Window      */

  switch (message)
  {
  case WM_PAINT:
    PaintPieWindow (hWnd);
    if ( bFlag == FALSE )
    {
      bFlag = TRUE;
      MessageBox( GetFocus() , (LPSTR)"Press the OK Button to move the window
          (LPSTR)"MOVE", MB_OK );

      MoveWindow( hWnd , 0 , 0 , 400 , 300 , TRUE );
/*  Change the size as well as the position using the
         *  MoveWindow function.  We also tell the Window to
         *  re-paint the client area.  We use the bFlag variable
         *  to make sure we only call MoveWindow once.
         */
    }
    break;

  case WM_DESTROY:        /*  If close requested  */
    PostQuitMessage(0);      /*    send yourself a quit  */
    break;          /*    message    */

  default:
    return( DefWindowProc( hWnd , message , wParam , lParam ) );
    break;
  }
  return( 0L );
}


/*
 *  THE PAINT PROCEDURE
 */

PaintPieWindow (hWnd)

HWND  hWnd;          /*  Handle of the window  */
{
  PAINTSTRUCT  ps;
  HDC    hDC;

  BeginPaint (hWnd , (LPPAINTSTRUCT) & ps);  /*  Prepare the client area */
  hDC = ps.hdc;            /*  Get the Display Context  */

  Pie ( hDC , 100 , 100 , 300 , 300 , 300 , 200 , 200 , 100 );
/*  Draw the Pie
   *  Upper Left of box holding pie slice  = 100 , 100
   *  Lower Right of box holding pie slice = 300 , 300
   *  Start the arc at 300 , 300
   *  End the arc at 200 , 100
   *  The arc will be drawn in a counter clockwise direction
   */

  ValidateRect (hWnd , (LPRECT) NULL);   /*  Disable any more paint messages
  EndPaint (hWnd, (LPPAINTSTRUCT) & ps );

  return TRUE;
}


MUZIC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SOUND\MUZIC.C

#include <windows.h>

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{

  int     i, j, q;

  MessageBox( GetFocus(), (LPSTR)"orginal", (LPSTR)"Sound routine", MB_OK);

   OpenSound();
   q=SetVoiceQueueSize(1,192);
   for (i=0; i < 60 ; i++) {  /* change frequency */
      for (j=0; j < 6 ; j++) {  /* change duration */
         SetVoiceSound(q,(LONG)440+(i*2),j);
         StartSound();
         WaitSoundState(QUEUEEMPTY);
      }
   }
   CloseSound();

  MessageBox( GetFocus(), (LPSTR)"Excel macro", (LPSTR)"Sound from", MB_OK);
 /* excel music macro */
  OpenSound();
  SetVoiceAccent(1,(LONG)100,255,0,0);
  q=SetVoiceQueueSize(1,400);
  SetVoiceNote(q,45,16,0); /* G# */
  StartSound();
  WaitSoundState(QUEUEEMPTY);
  CloseSound();

  StopSound();
  return 0;
}



OFFCLIPR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\REGION\OFFCLIPR.C

/*
 * Function (s) demonstrated in this program: OffsetClipRgn
 * Compiler version: C 5.1
 * Description: This program creates a rectangle region, gets it location,
 *              frames the region, offsets the region, displays what kind
 *              of region it is, get it new loction of the region, frames
 *              the new location, and displays the difference of the offset.
 */

#include <windows.h>
#include <stdio.h>
#include "offclipr.h"

static char  szFuncName[] = "OffsetClipRgn";
static char  szAppName[] = "OFFCLIPR";

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        nCmdShow;
  {
  HWND        hWnd;
  WNDCLASS    wndclass;
  MSG         msg;
  HMENU       hMenu;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = (LPSTR)"OFFCLIP";
    wndclass.lpszClassName = szFuncName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hMenu = LoadMenu (hInstance, (LPSTR)"OFFCLIP");

  hWnd = CreateWindow (szFuncName, szAppName,
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, 0,
                      CW_USEDEFAULT, 0,
                      NULL, hMenu, hInstance, NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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

long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HDC         hDC;
  HRGN        hRgnBox;
  HBRUSH      hBlueBrush;
  HBRUSH      hRedBrush;
  RECT        rectBefore;
  RECT        rectAfter;
  short  nRgnType;
  int  nIndex;
  char  szBuffer [300];

  switch (iMessage)
    {
    case WM_INITMENU:
      InvalidateRect (hWnd, (LPRECT)NULL, TRUE);
      break;

    case WM_COMMAND:
      if (wParam == IDM_BOX)
        {
        hRgnBox = CreateRectRgn (50, 75, 125, 150);

        hBlueBrush = CreateSolidBrush (RGB (0, 0, 255));
        hRedBrush = CreateSolidBrush (RGB (255, 0, 0));
        if (hBlueBrush == NULL || hRedBrush == NULL)
          {
          MessageBox (GetFocus (), (LPSTR)"Error in Creating brushes.",
              (LPSTR)szFuncName, MB_OK | MB_ICONHAND);
          return (0L);
          }

        hDC = GetDC (hWnd);

        nRgnType = SelectClipRgn (hDC, hRgnBox);
        if (nRgnType == ERROR)
          {
          MessageBox (GetFocus (), (LPSTR)"Error in selecting clip region.",
              (LPSTR)szFuncName, MB_OK | MB_ICONHAND);
          return (0L);
          }

        nRgnType = GetClipBox (hDC, (LPRECT) & rectBefore);
        if (nRgnType == ERROR)
          {
          MessageBox (GetFocus (), (LPSTR)"Error in getting clip box.",
              (LPSTR)szFuncName, MB_OK | MB_ICONHAND);
          return (0L);
          }
        FrameRect (hDC, (LPRECT) & rectBefore, hBlueBrush);

        MessageBox (GetFocus (), (LPSTR)"Going to offset clip region.",
            (LPSTR)szFuncName, MB_OK);

        nRgnType = OffsetClipRgn (hDC, 200, 50);
        switch (nRgnType)
          {
          case COMPLEXREGION:
            MessageBox (GetFocus (), (LPSTR)"Offset clip region is complex.",
                (LPSTR)szFuncName, MB_OK);
            break;
          case SIMPLEREGION:
            MessageBox (GetFocus (), (LPSTR)"Offset clip region is simple.",
                (LPSTR)szFuncName, MB_OK);
            break;
          case NULLREGION:
            MessageBox (GetFocus (), (LPSTR)"There is no offset clip region."
                (LPSTR)szFuncName, MB_OK);
            break;
          case ERROR:
            MessageBox (GetFocus (), (LPSTR)"Error in offset clip region.",
                (LPSTR)szFuncName, MB_OK | MB_ICONHAND);
            break;
          default :
            MessageBox (GetFocus (), (LPSTR)"Error !!!!",
                (LPSTR)szFuncName, MB_OK | MB_ICONHAND);
            break;
          }

        nRgnType = GetClipBox (hDC, (LPRECT) & rectAfter);
        if (nRgnType == ERROR)
          {
          MessageBox (GetFocus (), (LPSTR)"Error in getting clip box.",
              (LPSTR)szFuncName, MB_OK | MB_ICONHAND);
          return (0L);
          }
        FrameRect (hDC, (LPRECT) & rectAfter, hRedBrush);

        nIndex = sprintf (szBuffer,
            "%s %d %s %d\n%s %d %s %d\n%s %d %s %d\n%s %d %s %d",
            "clip box .left moved from", rectBefore.left,
            "to", rectAfter.left,
            "clip box .right moved from", rectBefore.right,
            "to", rectAfter.right,
            "clip box .top moved from", rectBefore.top,
            "to", rectAfter.top,
            "clip box .bottom moved from", rectBefore.bottom,
            "to", rectAfter.bottom);
        MessageBox (GetFocus (), (LPSTR)szBuffer, (LPSTR)szFuncName, MB_OK);

        ReleaseDC (hWnd, hDC);  /*  Clean up Memory  */
        DeleteObject (hRgnBox);
        DeleteObject (hRedBrush);
        DeleteObject (hBlueBrush);
        }
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }


OFFSETRG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\OFFSETRG.C

/*
 * Function (s) demonstrated in this program: OffsetRgn,
 *           BeginPaint, CreateRectRgn, EndPaint, GetSystemMetrics,
 *           InvalidateRect, SelectObject, TextOut, PostQuitMessage
 *
 * This program demonstrates the use of the Windows function OffsetRgn.
 * A handle to a rectangular region is generated by CreateRectRgn.  The
 * contents of this region are filled with a solid backround.  The
 * rectangle is initially located on one side of the client area.  When
 * a button is pressed then the client area is erased and the rectangle
 * is placed on the other side of the client area by the offsetrgn
 * function.  This process can be repeated indefinitely.
 *
 */

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

#define LEFT    0
#define RIGHT   1

long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);
void WndPaint (HWND hWnd, HDC hDC, BOOL fPosition);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        nCmdShow;
  {
  static char  szAppName [] = "OffsetRgn";
  HWND          hWnd;
  WNDCLASS      wndclass;
  MSG           msg;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szAppName;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hWnd = CreateWindow (szAppName, (LPSTR) "OffsetRgn",
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT, 0,
                       CW_USEDEFAULT, 0,
                       NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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


long    FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HDC      hDC;                 /* For the paint routine */
  PAINTSTRUCT ps;
  RECT     Rect;
  POINT    Point;
  static BOOL fPosition = LEFT; /* The value determines the location of the
                                 * rectangular region.  When LEFT then the
                                 * the region is located toward the top of
                                 * the window.  Otherwise the region is
                                 * located toward the bottom of the window.
                                 */
  switch (iMessage)
    {
    case WM_PAINT:
      hDC = BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
      WndPaint (hWnd, hDC, fPosition);
      EndPaint (hWnd, (LPPAINTSTRUCT) & ps);
      break;

    case WM_KEYUP:
      if (fPosition == LEFT)
        fPosition = RIGHT;
      else
        fPosition = LEFT;

      GetWindowRect (hWnd, &Rect);

      /* Translate screen coordinates to client coordinates for the *
       * InvalidateRect function.                                   */
      Point.x = Rect.left;
      Point.y = Rect.top;
      ScreenToClient (hWnd, &Point);  /* Translate the upper left hand corner
      Rect.left = Point.x;
      Rect.top = Point.y;

      Point.x = Rect.right;
      Point.y = Rect.bottom;
      ScreenToClient (hWnd, &Point); /* Translate the upper right hand corner
      Rect.right = Point.x;
      Rect.bottom = Point.y;

      InvalidateRect (hWnd, &Rect, TRUE);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
    }
  return (0L);
  }

void WndPaint (hWnd, hDC, fPosition)
HWND hWnd;
HDC  hDC;
BOOL fPosition;
  {
  HRGN        hRgn;
  short X, Y;

  TextOut (hDC, 10, 10, "Pressing any key will cause the OffsetRgn function",
  TextOut (hDC, 10, 22, "to change the position of the rectangular region.",
  SelectObject (hDC, GetStockObject (GRAY_BRUSH));

  X = GetSystemMetrics (SM_CXSCREEN);
  Y = GetSystemMetrics (SM_CYSCREEN);

  hRgn = CreateRectRgn (X / 4, Y / 4 + 50, X / 2, Y / 2 + 50);

  if (fPosition == LEFT)
/* OffsetRgn moves the region identified by hRgn by the specified  *
     * offsets.  The function moves the region 150 units along the     *
     * x-axis and 0 units along the y-axis.                            */
    OffsetRgn (hRgn, 150, 0);          /* Move rectangle region to the right

  else
    OffsetRgn (hRgn, -150, 0);          /* Move rectangle region to the left

/* PaintRgn fills the region specified by hRgn with the brush selected *
   * into the display context.                                           */

  PaintRgn (hDC, hRgn);
  DeleteObject (hRgn);     /*  Delete region from memory  */
  return;
  }


OPENCOMM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\OPENCOMM.C

/*
 *  OpenComm
 *
 *  This program demonstrates the use of the function OpenComm.
 *  It opens a communication device and assign a handle to it. The
 *  communication device is initialized to a default configuration.
 *  Spaces are allocated for the "recieve" and "transmit" queues.
 *  The communication port must be close before it can be open again with
 *  OpenComm.
 *
 */

#include "windows.h"

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  short  nCid;            /* short integer identifying the opened
                          * communication device  */

  nCid = OpenComm ( (LPSTR)"COM1", 20, 20);

  if (nCid >= 0)
    MessageBox (GetFocus (), (LPSTR)"Com port opened!!", (LPSTR)"OK", MB_OK);
  else
    {
    MessageBox (GetFocus (), (LPSTR)"Com port not opened!!",
               (LPSTR)"FAIL!", MB_OK);
    return 0;
    }

  CloseComm (nCid);

  return 0;
  }


OPENFILE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\OPENFILE.C

/*   This program demonstrates the use of the function OpenFile
 *   This function creates, opens, reopens or deletes a file.  In
 *   this program, "OpenFile.txt" will be opened, and the contents
 *   displayed in a MessageBox.
 */

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

 Buf_Size 12                /* Buffer size to read with */
 Name_Size 13               /* Max length for name of external file */

int     read (int, char *, int);
int     close (int);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HANDLE hMem;

  OFSTRUCT ReOpenBuff;
  int   errchk;
  int   hFile;
  char  *szBuf;

/***************************************************************************/

  MessageBox (NULL, (LPSTR)"About to open and read OPENFILE.TXT.",
      (LPSTR)"Ready", MB_OK);

  hFile = OpenFile ( (LPSTR)"openfile.txt",   /* Open file.          */
  (LPOFSTRUCT) & ReOpenBuff, OF_READ);
  if (hFile == -1)
    {                                      /* If not successful, say so.  */
    MessageBox (NULL,
        (LPSTR) "Problem opening file - OpenFile.txt",
        (LPSTR) "Error",
        MB_OK);
    }
  else
    {
    hMem = LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, Buf_Size);
    szBuf = LocalLock (hMem);
    errchk = read (hFile, szBuf, Buf_Size - 1);
    szBuf[Buf_Size - 1] = '\0';

    if (errchk == -1)
      {                     /* If problem while reading,   */
                            /* say so.                     */
      MessageBox (NULL, (LPSTR) "Problem reading file.",
          (LPSTR) "ERROR", MB_OK);
      }
    errchk = close (hFile);
    if (errchk != -1)
      {                             /* If no error, print message box */
                                    /* with file contents.            */
      MessageBox (NULL, (LPSTR) szBuf, (LPSTR) "Success", MB_OK);
      }
    else
      {                             /* Error closing file.           */
      MessageBox (NULL, (LPSTR) "File not closed", (LPSTR) "ERROR", MB_OK);
      }
    }
  LocalUnlock (hMem);
  LocalFree (hMem);
  return TRUE;
  }


OPENFILE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\OPENFILE.C

/*   This program demonstrates the use of the function OpenFile
 *   This function creates, opens, reopens or deletes a file.  In
 *   this program, "OpenFile.txt" will be opened, and the contents
 *   displayed in a MessageBox.
 */

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

 Buf_Size 12                /* Buffer size to read with */
 Name_Size 13               /* Max length for name of external file */

int     read (int, char *, int);
int     close (int);

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HANDLE hMem;

  OFSTRUCT ReOpenBuff;
  int   errchk;
  int   hFile;
  char  *szBuf;

/***************************************************************************/

  MessageBox (NULL, (LPSTR)"About to open and read OPENFILE.TXT.",
      (LPSTR)"Ready", MB_OK);

  hFile = OpenFile ( (LPSTR)"openfile.txt",   /* Open file.          */
  (LPOFSTRUCT) & ReOpenBuff, OF_READ);
  if (hFile == -1)
    {                                      /* If not successful, say so.  */
    MessageBox (NULL,
        (LPSTR) "Problem opening file - OpenFile.txt",
        (LPSTR) "Error",
        MB_OK);
    }
  else
    {
    hMem = LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, Buf_Size);
    szBuf = LocalLock (hMem);
    errchk = read (hFile, szBuf, Buf_Size - 1);
    szBuf[Buf_Size - 1] = '\0';

    if (errchk == -1)
      {                     /* If problem while reading,   */
                            /* say so.                     */
      MessageBox (NULL, (LPSTR) "Problem reading file.",
          (LPSTR) "ERROR", MB_OK);
      }
    errchk = close (hFile);
    if (errchk != -1)
      {                             /* If no error, print message box */
                                    /* with file contents.            */
      MessageBox (NULL, (LPSTR) szBuf, (LPSTR) "Success", MB_OK);
      }
    else
      {                             /* Error closing file.           */
      MessageBox (NULL, (LPSTR) "File not closed", (LPSTR) "ERROR", MB_OK);
      }
    }
  LocalUnlock (hMem);
  LocalFree (hMem);
  return TRUE;
  }


OPENICON.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\ICON\OPENICON.C

/*
 * Function (s) demonstrated in this program: OpenIcon
 *
 * Description:
 * This sample program demonstrates how to use the OpenIcon Windows
 * function.  Two windows are created.  The first window is initially
 * displayed as an open window.  The second window is initially
 * displayed as an iconized window.  After both windows are created and
 * displayed then a message box prompts the user to press return.  Upon
 * receiving <RETURN>, The message box closes.  This is followed by a
 * call to the function OpenIcon which opens the iconized window.
 *
 */

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

long    FAR PASCAL WndProc1 (HWND, unsigned, WORD, LONG);
long    FAR PASCAL WndProc2 (HWND, unsigned, WORD, LONG);

static char     szAppName1 [] = "OpenIcon, window number 1";
static char     szAppName2 [] = "OpenIcon, window number 2";
static char  szResName [] = "ResMenu";
static HWND hWnd1, hWnd2;

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int  nCmdShow;
  {
  WNDCLASS wndclass;
  MSG      msg;
  HDC      hDC;
  HMENU    hMenu;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc1;
    wndclass.cbClsExtra    = 0;
    wndclass.cbWndExtra    = 0;
    wndclass.hInstance     = hInstance;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName  = NULL;
    wndclass.lpszClassName = szAppName1;

    if (!RegisterClass (&wndclass))
      return FALSE;

    wndclass.lpfnWndProc   = WndProc2;
    wndclass.lpszClassName = szAppName2;

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hMenu = LoadMenu (hInstance, "ResMenu");

  hWnd1 = CreateWindow (szAppName1, szAppName1,
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT, 0,
                       CW_USEDEFAULT, 0,
                       NULL, hMenu, hInstance, NULL);

  ShowWindow (hWnd1, nCmdShow);
  UpdateWindow (hWnd1);

  hWnd2 = CreateWindow (szAppName2, szAppName2,
                       WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT, 0,
                       CW_USEDEFAULT, 0,
                       NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd2, SW_MINIMIZE);

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

long    FAR PASCAL WndProc1 (hWnd1, iMessage, wParam, lParam)
HWND     hWnd1;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  switch (iMessage)
    {
    case WM_COMMAND:
      if (wParam == IDM_EXECUTE)
        OpenIcon (hWnd2);                /* Open the iconized window */
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd1, iMessage, wParam, lParam);
    }
  return (0L);
  }

long    FAR PASCAL WndProc2 (hWnd2, iMessage, wParam, lParam)
HWND     hWnd2;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
  {
  HDC hDC;
  PAINTSTRUCT ps;

  switch (iMessage)
    {
    case WM_PAINT:
      hDC = BeginPaint (hWnd2, &ps);
      TextOut (hDC, 30, 30,
          (LPSTR)"This window was opened by the OpenIcon function", 47);
      EndPaint (hWnd2, &ps);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd2, iMessage, wParam, lParam);
    }
  return (0L);
  }


OPENSND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SOUND\OPENSND.C

/*
 *  OpenSound
 *
 *  This program demonstrates the use of the function OpenSound.
 *  This function opens access to the play device ande prevents subsequent
 *  opening of the device by other applications.  This function has no
 *  parameters.
 *
 */

#include "windows.h"

int  sprintf (PSTR, PSTR, int);

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  short  nVoices;
  char  szBuffer[30];

  nVoices = OpenSound ();   /* Opens access to the play device and prevents
                             * subsequent opening of the device by other
                             * applications.  Return value specifies the
                                   * number of voices available. */

  CloseSound ();  /* CloseSound must be invoked to allow other applications
                        * to access the play device */

/* return code for OpenSound routine */
  if (nVoices == S_SERDVNA)
  {
    MessageBox (NULL, (LPSTR)"Play device in use",
        (LPSTR)"Done", MB_OK);
  }
  else if (nVoices == S_SEROFM)
  {
    MessageBox (NULL, (LPSTR)"Insufficient memory available",
        (LPSTR)"Done", MB_OK);
  }
  else
  {
    sprintf (szBuffer, "%d voice (s) are available", nVoices);
    MessageBox (GetFocus (), (LPSTR)szBuffer,
        (LPSTR)"Done", MB_OK);
  }
  return 0;
}




PAINTRGN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\PAINTRGN.C

/*

A handle to a display context is generated using the BeginPaint function.
This handle is used to select a new brush into the current display context.
Once this new brush is created, it is used to paint a grey backround within
a rectangle.

*/

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

long  FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance ;
LPSTR       lpszCmdLine ;
int  nCmdShow ;
{
  static char  szAppName [] = "PaintRgn" ;
  HWND        hWnd ;
  WNDCLASS    wndclass ;
  MSG msg;

  if (!hPrevInstance)
  {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
    wndclass.lpfnWndProc   = WndProc ;
    wndclass.cbClsExtra    = 0 ;
    wndclass.cbWndExtra    = 0 ;
    wndclass.hInstance     = hInstance ;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName  = NULL ;
    wndclass.lpszClassName = szAppName ;

    if (!RegisterClass (&wndclass))
      return FALSE ;
  }

  hWnd = CreateWindow (szAppName, (LPSTR)"PaintRgn",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, nCmdShow) ;
  UpdateWindow (hWnd) ;

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


long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned  iMessage ;
WORD     wParam ;
LONG     lParam ;
{
  HDC      hDC;
  HRGN     hRgn;
  short  xX,                                      /* X coordinate */
  yY;                                      /* Y coordinate */

  PAINTSTRUCT ps;
  switch (iMessage)
  {
  case WM_PAINT:
    {
      hDC = BeginPaint(hWnd, (LPPAINTSTRUCT) & ps);

      TextOut (hDC, 10, 10,
          (LPSTR)"The Windows function PaintRgn is used to fill the backround
          strlen("The Windows function PaintRgn is used to fill the backround
          );

      TextOut (hDC, 10, 22,
          (LPSTR)"with the selected grey brush.",
          strlen("with the selected grey brush.")
          );


      SelectObject (hDC, GetStockObject (GRAY_BRUSH));

      xX = GetSystemMetrics (SM_CXSCREEN);
      yY = GetSystemMetrics (SM_CYSCREEN);

      hRgn = CreateRectRgn (xX / 4, yY / 4, xX / 2, yY / 2);
/* PaintRgn fills the region specified by hRgn with the brush selected *
    * into the display context.
    */
      PaintRgn (hDC, hRgn);
      EndPaint(hWnd, (LPPAINTSTRUCT) & ps);
      break;
    }
  case WM_DESTROY:
    {
      PostQuitMessage(0);
      break;
    }
  default:
    {
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
    }
  }
  return (0L);
}




PEEKMSG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\PEEKMSG.C

/*
 *  PeekMessage
 *
 *  This program will demonstrate the use of PeekMessage by catching all
 *  of the WM_PAINT messages and beeping, using MessageBeep, when there
 *  is one in the queue.
 *
 */

#include "windows.h"
#include "peekmsg.h"

HANDLE hInst;

int  PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int  nCmdShow;
{
  BOOL bStatus;
  HWND hWnd;
  MSG msg;

  if (!hPrevInstance)
    if (!PeekMessageInit(hInstance))
      return (NULL);

  hInst = hInstance;   /* Saves the current instance      */

  hWnd = CreateWindow((LPSTR)"PeekMessage", (LPSTR)"PeekMessage Sample Applic
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,  0,
      CW_USEDEFAULT,  0,
      NULL,  NULL,  hInstance, NULL);

  if (!hWnd)
    return (NULL);

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  while (GetMessage(&msg, NULL, NULL, NULL))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    bStatus = PeekMessage(&msg,   /*  Message Structure  */
                          hWnd,   /*  Handle of window receiving the message
                          WM_PAINT,  /*  Lowest Message to examine  */
                          WM_PAINT,  /*  Highest Message to examine  */
                          PM_NOREMOVE);  /*  Don't remove the message  */

/*  To get a WM_PAINT message to be sent, size the window in different ways.
 *  Using the Diagonal sizing seems to give the best results  */

    if (bStatus)
      MessageBeep(MB_OK);  /*  We got a message, beep!!!  */
  }
  return (msg.wParam);    /* Returns the value from PostQuitMessage */
}


BOOL PeekMessageInit(hInstance)
HANDLE hInstance;
{
  HANDLE hMemory;          /* handle to allocated memory */
  PWNDCLASS pWndClass;
  BOOL bSuccess;          /* RegisterClass() result     */

  hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
  pWndClass = (PWNDCLASS) LocalLock(hMemory);

  pWndClass->style = NULL;
  pWndClass->lpfnWndProc = PeekMessageWndProc;
  pWndClass->hInstance = hInstance;
  pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION);
  pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
  pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  pWndClass->lpszMenuName = (LPSTR) NULL;
  pWndClass->lpszClassName = (LPSTR) "PeekMessage";

  bSuccess = RegisterClass(pWndClass);

  LocalUnlock(hMemory);       /* Unlocks the memory    */
  LocalFree(hMemory);        /* Returns it to Windows */

  return (bSuccess);   /* Returns result of registering the window */
}


long  FAR PASCAL PeekMessageWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  FARPROC lpProcAbout;
  HMENU hMenu;

  switch (message)
  {
  case WM_SYSCOMMAND:
    if (wParam == ID_ABOUT)
    {
      lpProcAbout = MakeProcInstance(About, hInst);

      DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);

      FreeProcInstance(lpProcAbout);
      break;
    }

    else
      return (DefWindowProc(hWnd, message, wParam, lParam));

  case WM_CREATE:

    hMenu = GetSystemMenu(hWnd, FALSE);

/* Add a separator to the menu */

    ChangeMenu(hMenu, NULL, NULL, NULL, MF_APPEND | MF_SEPARATOR);

/* Add new menu item to the System menu */

    ChangeMenu(hMenu, NULL, "A&bout PeekMessage...", ID_ABOUT,
        MF_APPEND | MF_STRING);
    break;

  case WM_DESTROY:    /* message: window being destroyed */
    PostQuitMessage(0);
    break;

  default:
    return (DefWindowProc(hWnd, message, wParam, lParam));
  }
  return (0L);
}


BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned  message;
WORD wParam;
LONG lParam;
{
  switch (message)
  {
  case WM_INITDIALOG:     /* message: initialize dialog box */
    return (TRUE);

  case WM_COMMAND:
    if (wParam == IDOK)
    {
      EndDialog(hDlg, NULL);
      return (TRUE);
    }
    break;
  }
  return (FALSE);
}




PIE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\PIE.C

/*
 *  Pie
 *
 *  This function demonstrates the use of the Pie function.  It will create
 *  a window, and procede to draw a pie inside of that window
 *
 */

#include <windows.h>

BOOL FAR PASCAL InitPie (HANDLE, HANDLE, int);
long  FAR PASCAL PieWindowProc (HANDLE, unsigned, WORD, LONG);

int  PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, cmdShow)

HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
{
  MSG  msg;
  InitPie (hInstance, hPrevInstance, cmdShow);

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

  exit(msg.wParam);
}


BOOL FAR PASCAL InitPie (hInstance, hPrevInstance, cmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
int  cmdShow;

{
  WNDCLASS  wcPieClass;
  HWND hWnd;

  wcPieClass.lpszClassName = (LPSTR) "Pie";
  wcPieClass.hInstance    = hInstance;
  wcPieClass.lpfnWndProc   = PieWindowProc;
  wcPieClass.hCursor    = LoadCursor (NULL, IDC_ARROW);
  wcPieClass.hIcon    = NULL;
  wcPieClass.lpszMenuName  = (LPSTR) NULL;
  wcPieClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcPieClass.style    = CS_HREDRAW | CS_VREDRAW;
  wcPieClass.cbClsExtra    = 0;
  wcPieClass.cbWndExtra    = 0;

  RegisterClass ((LPWNDCLASS) & wcPieClass);

  hWnd = CreateWindow((LPSTR) "Pie", (LPSTR) "Pie",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,  0,
      CW_USEDEFAULT,  0,
      NULL,  NULL,  hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
}


long  FAR PASCAL PieWindowProc (hWnd, message, wParam, lParam)

HWND     hWnd;
unsigned  message;
WORD     wParam;
LONG     lParam;
{
  switch (message)
  {
  case WM_PAINT:
    PaintPieWindow (hWnd);
    break;

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    return(DefWindowProc(hWnd, message, wParam, lParam));
    break;
  }
  return(0L);
}


PaintPieWindow (hWnd)

HWND hWnd;
{
  PAINTSTRUCT ps;
  HDC  hDC;

  BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
  hDC = ps.hdc;

  Pie (hDC, 100, 100, 300, 300, 300, 200, 200, 100);
/*  Draw the Pie
  *  Upper Left of box holding pie slice  = 100, 100
  *  Lower Right of box holding pie slice = 300, 300
  *  Start the arc at 300, 300
  *  End the arc at 200, 100
  *  The arc will be drawn in a counter clockwise direction
  */

  ValidateRect (hWnd, (LPRECT) NULL);
  EndPaint (hWnd, (LPPAINTSTRUCT) & ps);

  return TRUE;
}




PMETAFIL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\PMETAFIL.C

/*
 *
 *  This program demonstrates the use of the function PlayMetaFile.
 *  This function plays the contents of the specified metafile on the
 *  given context.
 *
 */

#include <windows.h>
#include "pmetafil.h"

static HANDLE hWnd;
static char  szResName [] = "ResMenu";
static char  szFileName[] = "pmetafil";
static char  szFuncName[] = "PlayMetaFile";

long  FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);

int  PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
{
  MSG msg;
  if (!hPrevInstance)
  {
    WNDCLASS rClass;

    rClass.lpszClassName = (LPSTR)szFileName;
    rClass.hInstance     = hInstance;
    rClass.lpfnWndProc   = WndProc;
    rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon(hInstance, IDI_APPLICATION);
    rClass.lpszMenuName  = NULL;
    rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;

    RegisterClass((LPWNDCLASS) & rClass);
  }

  hWnd = CreateWindow((LPSTR)szFileName, (LPSTR)szFuncName,
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

  ShowWindow(hWnd, cmdShow);
  UpdateWindow (hWnd) ;

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


long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned  iMessage ;
WORD     wParam ;
LONG     lParam ;
{
  static HANDLE hInstance;
  HMENU hMenu;
  HDC hDC;
  HANDLE hMF;
  BOOL bPlayed;
  switch (iMessage)
  {
  case WM_CREATE:
    {
      hInstance = GetWindowWord(hWnd, GWW_HINSTANCE);
      hMenu = LoadMenu(hInstance, "ResMenu");
      SetMenu(hWnd, hMenu);
      DrawMenuBar(hWnd);
      break;
    }
  case WM_COMMAND:
    {
      switch (wParam)
      {
      case IDM_EXECUTE:
  {
    hDC = GetDC(hWnd);
    hMF = GetMetaFile((LPSTR)"PMETAFIL.MET");

    MessageBox(GetFocus(), (LPSTR)"About To Play Metafile",
        (LPSTR)szFuncName, MB_OK);

    bPlayed = PlayMetaFile(hDC, hMF);

    if (bPlayed != 0)
      MessageBox(GetFocus(),
          (LPSTR)"Metafile Played Successfully (Rectangle Generated)",
          (LPSTR)szFuncName, MB_OK);
    else
      MessageBox (GetFocus(), (LPSTR)"Metafile Play Error", (LPSTR)szFuncName
          MB_OK);

    ReleaseDC(hWnd, hDC);
  }
      }
      break;
    }
  case WM_DESTROY:
    {
      PostQuitMessage(0);
      break;
    }
  default:
    {
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
    }
  }
  return (0L);
}




POLYGON.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\POLYGON.C

/*
 *  Polygon
 *
 *  This function demonstrates the use of the Polygon function.  It will
 *  create a window, and procede to draw a triangle in the window.
 *
 */

#include <windows.h>

BOOL FAR PASCAL InitPolygon (HANDLE, HANDLE, int);
long  FAR PASCAL PolygonWindowProc (HANDLE, unsigned, WORD, LONG);

int  PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, cmdShow)

HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
{
  MSG  msg;

  InitPolygon (hInstance, hPrevInstance, cmdShow);

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

  exit(msg.wParam);
}


BOOL FAR PASCAL InitPolygon (hInstance, hPrevInstance, cmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
int  cmdShow;

{
  WNDCLASS  wcPolygonClass;
  HWND hWnd;

  wcPolygonClass.lpszClassName = (LPSTR) "Polygon";
  wcPolygonClass.hInstance     = hInstance;
  wcPolygonClass.lpfnWndProc   = PolygonWindowProc;
  wcPolygonClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcPolygonClass.hIcon        = NULL;
  wcPolygonClass.lpszMenuName  = (LPSTR) NULL;
  wcPolygonClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcPolygonClass.style        = CS_HREDRAW | CS_VREDRAW;
  wcPolygonClass.cbClsExtra    = 0;
  wcPolygonClass.cbWndExtra    = 0;

  RegisterClass ((LPWNDCLASS) & wcPolygonClass);

  hWnd = CreateWindow((LPSTR)"Polygon", (LPSTR) "Polygon",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,  0,
      CW_USEDEFAULT,  0,
      NULL,  NULL,  hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
}


long  FAR PASCAL PolygonWindowProc (hWnd, message, wParam, lParam)

HWND     hWnd;
unsigned  message;
WORD     wParam;
LONG     lParam;
{
  switch (message)
  {
  case WM_PAINT:
    PaintPolygonWindow (hWnd);
    break;

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    return(DefWindowProc(hWnd, message, wParam, lParam));
    break;
  }
  return(0L);
}


PaintPolygonWindow (hWnd)

HWND hWnd;
{
  PAINTSTRUCT ps;
  HDC  hDC;
  POINT  lpTriangle[4];
  HANDLE hOldBrush, hBrush;


  BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
  hDC = ps.hdc;

  hBrush = GetStockObject (GRAY_BRUSH);
  hOldBrush = SelectObject (hDC, hBrush);

  lpTriangle[0].x = 150;    /* The values of the points  */
  lpTriangle[0].y = 100;
  lpTriangle[1].x = 100;
  lpTriangle[1].y = 200;
  lpTriangle[2].x = 200;
  lpTriangle[2].y = 200;

  Polygon (hDC, lpTriangle, 3);  /*  Draw the triangle */

  ValidateRect (hWnd, (LPRECT) NULL);
  EndPaint (hWnd, (LPPAINTSTRUCT) & ps);

  SelectObject(hDC, hOldBrush);
  return TRUE;
}




POLYLINE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\POLYLINE.C

/*
 *  Polyline
 *
 *  This function demonstrates the use of the Polyline function.  It will
 *  create a window, and procede to draw a small 3-D Box in the window.
 *
 */

#include <windows.h>

BOOL FAR PASCAL InitPolyline (HANDLE, HANDLE, int);
long  FAR PASCAL PolylineWindowProc (HANDLE, unsigned, WORD, LONG);

int  PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, cmdShow)

HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
{
  MSG  msg;

  InitPolyline (hInstance, hPrevInstance, cmdShow);

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

  exit(msg.wParam);
}


BOOL FAR PASCAL InitPolyline (hInstance, hPrevInstance, cmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
int  cmdShow;

{
  WNDCLASS  wcPolylineClass;
  HWND hWnd;

  wcPolylineClass.lpszClassName = (LPSTR) "Polyline";
  wcPolylineClass.hInstance     = hInstance;
  wcPolylineClass.lpfnWndProc   = PolylineWindowProc;
  wcPolylineClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcPolylineClass.hIcon         = NULL;
  wcPolylineClass.lpszMenuName  = (LPSTR) NULL;
  wcPolylineClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcPolylineClass.style         = CS_HREDRAW | CS_VREDRAW;
  wcPolylineClass.cbClsExtra    = 0;
  wcPolylineClass.cbWndExtra    = 0;

  RegisterClass ((LPWNDCLASS) & wcPolylineClass);

  hWnd = CreateWindow((LPSTR) "Polyline", (LPSTR) "Polyline",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,  0,
      CW_USEDEFAULT,  0,
      NULL,  NULL,  hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  return TRUE;
}


long  FAR PASCAL PolylineWindowProc (hWnd, message, wParam, lParam)

HWND     hWnd;
unsigned  message;
WORD     wParam;
LONG     lParam;
{
  switch (message)
  {
  case WM_PAINT:
    PaintPolylineWindow (hWnd);
    break;

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    return(DefWindowProc(hWnd, message, wParam, lParam));
    break;
  }
  return(0L);
}


PaintPolylineWindow (hWnd)

HWND hWnd;
{
  PAINTSTRUCT ps;
  HDC  hDC;
  POINT       lpSide1[4];
  POINT       lpSide2[4];
  POINT       lpSide3[4];
  POINT       lpSide4[4];

  BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
  hDC = ps.hdc;

  lpSide1[0].x = 140;  /*  The values of the box  */
  lpSide1[0].y = 130;
  lpSide1[1].x = 100;
  lpSide1[1].y = 100;
  lpSide1[2].x = 170;
  lpSide1[2].y = 100;
  lpSide1[3].x = 200;
  lpSide1[3].y = 130;
  lpSide2[0].x = 100;
  lpSide2[0].y = 100;
  lpSide2[1].x = 100;
  lpSide2[1].y = 170;
  lpSide2[2].x = 170;
  lpSide2[2].y = 170;
  lpSide2[3].x = 170;
  lpSide2[3].y = 100;
  lpSide3[0].x = 100;
  lpSide3[0].y = 170;
  lpSide3[1].x = 140;
  lpSide3[1].y = 200;
  lpSide3[2].x = 200;
  lpSide3[2].y = 200;
  lpSide3[3].x = 170;
  lpSide3[3].y = 170;
  lpSide4[0].x = 140;
  lpSide4[0].y = 200;
  lpSide4[1].x = 140;
  lpSide4[1].y = 130;
  lpSide4[2].x = 200;
  lpSide4[2].y = 130;
  lpSide4[3].x = 200;
  lpSide4[3].y = 200;

  Polyline(hDC, lpSide1, 4);  /*  Draw the sides of the box  */
  Polyline(hDC, lpSide2, 4);
  Polyline(hDC, lpSide3, 4);
  Polyline(hDC, lpSide4, 4);

  ValidateRect (hWnd, (LPRECT) NULL);
  EndPaint (hWnd, (LPPAINTSTRUCT) & ps);

  return TRUE;
}




POSTMSG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\POSTMSG.C

/*
 *  PostMessage
 *
 *  This example program will use the PostMessage function to send a
 *  WM_SYSCOMMAND message to the main window to make it iconic.  The
 *  wParam parameter will be set to SC_MINIMIZE to accomplish this.
 *
 */

#include "windows.h"
#include "postmsg.h"

HANDLE hInst;

int  PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR lpCmdLine;
int  nCmdShow;
{
  HWND hWnd;
  MSG msg;
  HANDLE hMenu;

  if (!hPrevInstance)
    if (!PostMsgInit(hInstance))
      return (NULL);

  hInst = hInstance;

  hMenu = LoadMenu(hInst, (LPSTR)"PostMsgMenu");


  hWnd = CreateWindow((LPSTR)"PostMsg", (LPSTR)"PostMessage Sample Applicatio
  WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, hMenu, hInstance, NULL);

  if (!hWnd)
    return (NULL);

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  while (GetMessage(&msg,
      NULL,
      NULL,
      NULL))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  return (msg.wParam);
}


BOOL PostMsgInit(hInstance)
HANDLE hInstance;
{
  HANDLE hMemory;
  PWNDCLASS pWndClass;
  BOOL bSuccess;

  hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
  pWndClass = (PWNDCLASS) LocalLock(hMemory);

  pWndClass->style = NULL;
  pWndClass->lpfnWndProc = PostMsgWndProc;
  pWndClass->hInstance = hInstance;
  pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION);
  pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
  pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
  pWndClass->lpszMenuName = (LPSTR) "PostMsgMenu";
  pWndClass->lpszClassName = (LPSTR) "PostMsg";

  bSuccess = RegisterClass(pWndClass);

  LocalUnlock(hMemory);
  LocalFree(hMemory);

  return (bSuccess);
}


long  FAR PASCAL PostMsgWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  FARPROC lpProcAbout;
  HMENU hMenu;

  switch (message)
  {
  case WM_SYSCOMMAND:
    if (wParam == ID_ABOUT)
    {
      lpProcAbout = MakeProcInstance(About, hInst);

      DialogBox(hInst, "AboutBox", hWnd, lpProcAbout);

      FreeProcInstance(lpProcAbout);
      break;
    }

    else
      return (DefWindowProc(hWnd, message, wParam, lParam));

  case WM_CREATE:

    hMenu = GetSystemMenu(hWnd, FALSE);

/* Add a separator to the menu */

    ChangeMenu(hMenu, NULL, NULL, NULL, MF_APPEND | MF_SEPARATOR);

/* Add new menu item to the System menu */

    ChangeMenu(hMenu, NULL, "A&bout PostMsg...", ID_ABOUT,
        MF_APPEND | MF_STRING);
    break;

  case WM_COMMAND:
    if (wParam == IDM_ICONIZE)
    {
      PostMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, (LONG) NULL);
    }
    break;

/*  PostMessage places the message into the applications message queue and
 *  does not wait for a response.  This is different from the SendMessage
 *  function in that SendMessage does wait.  The Window Procedure is called
 *  immediately when SendMessage is used.  For more information see
 *  PostMessage and SendMessage in the Programmer's Reference.
 */
  case WM_DESTROY:
    PostQuitMessage(0);
    break;

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


BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned  message;
WORD wParam;
LONG lParam;
{
  switch (message)
  {
  case WM_INITDIALOG:
    return (TRUE);

  case WM_COMMAND:
    if (wParam == IDOK)
    {
      EndDialog(hDlg, NULL);
      return (TRUE);
    }
    break;
  }
  return (FALSE);
}




POSTQUIT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\POSTQUIT.C

/* PostQuitMessage
 *
 *  When Execute is selected, a PostQuitMessage is generated and
 *  closes down this application.
 *
 */

#include <windows.h>
#include "postquit.h"

long  FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;

static char  szResName [] = "ResMenu";

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance ;
LPSTR       lpszCmdLine ;
int  nCmdShow ;
{
  static char  szAppName [] = "PostQuitMessage";
  HWND        hWnd ;
  MSG msg;
  WNDCLASS  wcPostQuitMessageClass;

  wcPostQuitMessageClass.lpszClassName = szAppName;
  wcPostQuitMessageClass.hInstance     = hInstance;
  wcPostQuitMessageClass.lpfnWndProc   = WndProc;
  wcPostQuitMessageClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wcPostQuitMessageClass.hIcon         = NULL;
  wcPostQuitMessageClass.lpszMenuName  = (LPSTR) NULL;
  wcPostQuitMessageClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcPostQuitMessageClass.style         = CS_HREDRAW | CS_VREDRAW;
  wcPostQuitMessageClass.cbClsExtra    = 0;
  wcPostQuitMessageClass.cbWndExtra    = 0;

  RegisterClass ((LPWNDCLASS) & wcPostQuitMessageClass);

  hWnd = CreateWindow(szAppName, (LPSTR) "PostQuitMessage",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,  0,
      CW_USEDEFAULT,  0,
      NULL, NULL,  hInstance, NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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


long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned  iMessage ;
WORD     wParam ;
LONG     lParam ;
{
  static HANDLE hInstance;
  HMENU hMenu;
  switch (iMessage)
  {
  case WM_CREATE:
    {
      hInstance = GetWindowWord(hWnd, GWW_HINSTANCE);
      hMenu = LoadMenu(hInstance, "ResMenu");
      SetMenu(hWnd, hMenu);
      DrawMenuBar(hWnd);
      break;
    }
  case WM_COMMAND:
    {
      switch (wParam)
      {
      case IDM_EXECUTE:
  {
    PostQuitMessage(0);
  }
      }
      break;
    }
  case WM_DESTROY:
    {
      PostQuitMessage(0);
      break;
    }
  default:
    {
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
    }
  }
  return (0L);
}




PROCINST.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\PROCINST.C

/*
 *
 *  FreeProcInstance
 *
 *  This program demonstrates the use of the function FreeProcInstance.
 *  This function frees the function specified bye the parameter from the
 *  data segment bound to it by the MakeProcInstance function.
 *
 *  Other references: DlgOpen.c, DlgSave.c, Print.c
 */

#include <windows.h>
#include "procinst.h"

typedef struct  {
  int  nDummy;
} SETUPDATA;

static SETUPDATA strSetUpData;
static HANDLE hInst;
static char  szFileName[] = "procinst";
static char  szFuncName[] = "FreeProcInstance";

long  FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);
BOOL FAR PASCAL TestFarFunc ();

int  PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  cmdShow;
{
  HWND hWnd;
  MSG  msg;
  if (!hPrevInstance)
  {
    WNDCLASS rClass;

    rClass.style         = CS_HREDRAW | CS_VREDRAW;
    rClass.lpfnWndProc   = WndProc;
    rClass.cbClsExtra    = 0;
    rClass.cbWndExtra    = 0;
    rClass.hInstance     = hInstance;
    rClass.hCursor       = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    rClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    rClass.lpszMenuName  = (LPSTR) NULL;
    rClass.lpszClassName = (LPSTR) szFileName;

    RegisterClass ((LPWNDCLASS) & rClass);
  }
  else
    GetInstanceData (hPrevInstance, (PSTR) & strSetUpData,
        sizeof (SETUPDATA));

  hInst = hInstance;

  hWnd = CreateWindow ((LPSTR) szFileName, (LPSTR) szFuncName,
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }
  exit(msg.wParam);
}


BOOL FAR PASCAL TestFarFunc ()
{
  return TRUE;
}

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 static HANDLE hInstance;
 FARPROC  lpProc;
 HMENU hMenu;
 switch(iMessage)
 {
  case WM_CREATE:
  {
   hInstance = GetWindowWord(hWnd, GWW_HINSTANCE);
   hMenu = LoadMenu(hInstance, "ResMenu");
   SetMenu(hWnd, hMenu);
   DrawMenuBar(hWnd);
   break;
  }
  case WM_COMMAND:
  {
   switch(wParam)
   {
    case IDM_EXECUTE:
    {
    lpProc = MakeProcInstance ((FARPROC) TestFarFunc, hInst);
    MessageBox (NULL, (LPSTR)"Freeing procedure instance", (LPSTR)szFuncName,
    FreeProcInstance (lpProc);
    MessageBox (NULL, (LPSTR)"Instance procedure freed", (LPSTR)szFuncName, M
    }
   }
   break;
  }
  case WM_DESTROY:
  {
   PostQuitMessage(0);
   break;
  }
  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}


PROPERTY.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\PROPERTY.C

/*

Function(s) demonstrated in this program: SetProp, GetProp, RemoveProp

Description:

This program demonstrates the use of the function SetProp, GetProp,
and RemoveProp.  SetProp copies the character string and a data handle
to the property list of the window.  This has the effect of
associating a data object with the window.  The string serves as a
label for the data handle.  The data handle is retrieved from the
property list using the GetProp function and specifying the character
string.  Before the window is destroyed the RemoveProp function must
be used  to remove the single entry in the property list.  Note that there
may be more than one data items associated with a window in the property
list.

*/

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "property.h"

VOID FAR PASCAL lstrcpy(LPSTR, LPSTR);
long  FAR PASCAL WndProc(HWND, unsigned, WORD, long);

/* This is the structure that is used to put into the property list. */
typedef struct tagData {
  short  nRow, nSeat;
  char  szName[20];
} SEATINGS;
static char  szResName [] = "ResMenu";

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance ;
LPSTR       lpszCmdLine ;
int  nCmdShow ;
{
  static char  szAppName [] = "Property" ;
  HWND        hWnd ;
  WNDCLASS    wndclass ;
  MSG msg;

  if (!hPrevInstance)
  {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
    wndclass.lpfnWndProc   = WndProc ;
    wndclass.cbClsExtra    = 0 ;
    wndclass.cbWndExtra    = 0 ;
    wndclass.hInstance     = hInstance ;
    wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName  = NULL ;
    wndclass.lpszClassName = szAppName ;

    if (!RegisterClass (&wndclass))
      return FALSE ;
  }

  hWnd = CreateWindow(szAppName, (LPSTR)"Setting the Property List",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0,
      NULL, NULL, hInstance, NULL) ;

  ShowWindow (hWnd, nCmdShow) ;
  UpdateWindow (hWnd) ;

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


long  FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned  iMessage ;
WORD     wParam ;
LONG     lParam ;
{
  static HANDLE hInstance;
  HANDLE hData;
  HMENU hMenu;
  char  szbuffer[200], szName[20];
  short  nRow, nSeat;
  SEATINGS FAR * pstrSeatings;
  switch (iMessage)
  {
  case WM_CREATE:
    {
      hInstance = GetWindowWord(hWnd, GWW_HINSTANCE);
      hMenu = LoadMenu(hInstance, "ResMenu");
      SetMenu(hWnd, hMenu);
      DrawMenuBar(hWnd);
      break;
    }
  case WM_COMMAND:
    {
      switch (wParam)
      {
      case IDM_EXECUTE:
  {
/* Putting the structure into the property list of the window
 * If it is successful, retrieve it to check if the correct structure
 * is put into the property list
 */
    hData = GlobalAlloc(GMEM_MOVEABLE, (LONG)sizeof(SEATINGS));


/* Initialize the data structure to be associated with the window */

    pstrSeatings = (SEATINGS FAR * )GlobalLock(hData);
    pstrSeatings->nRow = 4;
    pstrSeatings->nSeat = 2;
    lstrcpy (pstrSeatings->szName, "John Smith");

    GlobalUnlock(hData);
/* Add a new entry into the property list of the window specified *
 * by hWnd. The character string "Smith" identifies the entry to  *
 * be added.
 */
    if (!SetProp(hWnd, "Smith", hData))
      MessageBox(hWnd, (LPSTR)"The Windows function SetProp failed.",
          (LPSTR)"FAIL", MB_OK | MB_ICONHAND);

/* Prepare to display message */
    sprintf (szbuffer, "The following entry has been added to the \
property list of the parent window using the Windows function \
SetProp.\n\n  Smith at row 4, seat# 2\n");


    MessageBox(hWnd, szbuffer, "SetProp", MB_OK);

/* Retrieve an entry from the property list of the window specified *
 * by hWnd. The character string "Smith" identifies the entry to    *
 * be retrieved.
 */
    hData = GetProp(hWnd, "Smith");

    if (!hData)
    {
      MessageBox(hWnd, "GetProp has failed", "GetProp", MB_OK | MB_ICONHAND);
    }

    pstrSeatings = (SEATINGS FAR * )GlobalLock(hData);

/* Copy the global data objects into local data structures so that *
 * we can use sprintf.  Using small memory model, sprintf will     *
 * only accept pointer offsets into the current data segment
 */
    nRow = pstrSeatings->nRow;
    nSeat =  pstrSeatings->nSeat;
    lstrcpy(szName, pstrSeatings->szName);


/* Prepare to display message */

    sprintf(szbuffer, "The following entry has been retrieved from the \
property list of the parent window using the Windows function GetProp.\n\n \
%s at row %d, seat# %d\n",
                     szName, nRow, nSeat);

    MessageBox(hWnd, szbuffer, "GetProp", MB_OK);

    GlobalUnlock(hData);
    GlobalFree(hData);

/* Remove an entry from the property list of the window specified *
 * by hWnd. The character string "Smith" identifies the entry to  *
 * be removed.
 */
    if (!RemoveProp(hWnd, "Smith"))
    {
      MessageBox(hWnd, "RemoveProp has failed",
          "RemoveProp", MB_OK | MB_ICONHAND);
    }

/* Prepare to display message */
    sprintf(szbuffer, "The following entry has been removed from the \
property list of the parent window using the Windows function \
RemoveProp.\n\n %s at row %d, seat# %d\n",
                     szName, nRow, nSeat);

    MessageBox (hWnd, szbuffer, "RemoveProp", MB_OK);

  }
      }
      break;
    }
  case WM_DESTROY:
    {
      PostQuitMessage(0);
      break;
    }
  default:
    {
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
    }
  }
  return (0L);
}




PTVISI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIENT\PTVISI.C

/*
 *  PtVisible
 *
 *  This function demonstrates the use of the PtVisible function.  It will
 *  create a window using the CreateWindow function, and will display a
 *  message box telling the user if the point (200,200) is inside the client
 *  area of the window.
 *
 */

#include <windows.h>

BOOL FAR PASCAL InitPtVisible (HANDLE, HANDLE, int);
long  FAR PASCAL PtVisibleWindowProc (HANDLE, unsigned, WORD, LONG);
void FAR PASCAL CheckPoint (HWND);

int  PASCAL WinMain  (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)

HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int  nCmdShow;
{
  MSG  msg;

  InitPtVisible (hInstance, hPrevInstance, nCmdShow);

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

  exit(msg.wParam);
}


BOOL FAR PASCAL InitPtVisible (hInstance, hPrevInstance, nCmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
int  nCmdShow;

{
  WNDCLASS  wcPtVisibleClass;
  HWND hWnd;

  wcPtVisibleClass.lpszClassName = (LPSTR) "PtVisible";
  wcPtVisibleClass.hInstance  = hInstance;
  wcPtVisibleClass.lpfnWndProc  = PtVisibleWindowProc;
  wcPtVisibleClass.hCursor  = LoadCursor (NULL, IDC_ARROW);
  wcPtVisibleClass.hIcon  = NULL;
  wcPtVisibleClass.lpszMenuName  = (LPSTR) "PtVisibleMenu";
  wcPtVisibleClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcPtVisibleClass.style  = CS_HREDRAW | CS_VREDRAW;
  wcPtVisibleClass.cbClsExtra  = 0;
  wcPtVisibleClass.cbWndExtra  = 0;

  RegisterClass ((LPWNDCLASS) & wcPtVisibleClass);

  hWnd = CreateWindow((LPSTR) "PtVisible", (LPSTR) "PtVisible",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,  0,
      CW_USEDEFAULT,  0,
      NULL,  NULL,  hInstance, NULL);

  LoadMenu(hInstance, (LPSTR) "PtVisibleMenu");

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

  return TRUE;
}


long  FAR PASCAL PtVisibleWindowProc (hWnd, message, wParam, lParam)

HWND     hWnd;
unsigned  message;
WORD     wParam;
LONG     lParam;
{
  switch (message)
  {
  case WM_COMMAND:
    if (wParam == 1)
      CheckPoint(hWnd);
    break;

  case WM_PAINT:
    PaintPtVisibleWindow (hWnd);
    break;

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    return(DefWindowProc(hWnd, message, wParam, lParam));
    break;
  }
  return(0L);
}


PaintPtVisibleWindow (hWnd)

HWND hWnd;
{
  PAINTSTRUCT ps;
  HDC  hDC;

  BeginPaint (hWnd, (LPPAINTSTRUCT) & ps);
  hDC = ps.hdc;

  SetPixel (hDC, 200, 200, RGB(0, 0, 0));
/*  Draw a black pixel  */

  ValidateRect (hWnd, (LPRECT) NULL);
  EndPaint (hWnd, (LPPAINTSTRUCT) & ps);

  return TRUE;
}


/*  CheckPoint(hWnd) -  Check to see if (200, 200) is visible  */

void FAR PASCAL CheckPoint (hWnd)

HWND     hWnd;
{
  HDC  hDC;

  hDC = GetDC (hWnd);
  if (PtVisible (hDC, 200, 200))
/*  Find out if the point 200, 200 is in the current display
     *  context
     */

    MessageBox(hWnd, (LPSTR) "(200, 200) is Visible",
        (LPSTR)"OK", MB_OK);
  else
    MessageBox(hWnd, (LPSTR) "(200, 200) is not Visible",
        (LPSTR)"OK", MB_OK);

  ReleaseDC (hWnd, hDC);
}




QCHECKED.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\QCHECKED.C

/*
 *
 *   qchecked.c
 *
 *   This program demonstrates the use of the IsDlgButtonChecked function.
 *   IsDlgButtonChecked checks to see if the given button control or 3 state
 *   button is checked. That is not the same as seeing if the control has
 *   been chosen. To enact the dialog box, choose the "DIALOG" menu
 *   selection. To invoke a call to IsDlgButtonChecked,choose one of the two
 *   check boxes in the dialog box.
 *
 */

#include "windows.h"
#include "qchecked.h"

HANDLE hInst;

FARPROC lpprocDialog;
long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL DialogBoxProc(HWND, unsigned, WORD, LONG);


int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int   cmdShow;
  {
  MSG      msg;
  HWND      hWnd;
  HMENU     hMenu;
  WNDCLASS  wndclass;

  if (!hPrevInstance)
    {
    wndclass.style      = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc    = WndProc;
    wndclass.cbClsExtra     = 0;
    wndclass.cbWndExtra     = 0;
    wndclass.hInstance      = hInstance;
    wndclass.hIcon      = NULL;
    wndclass.hCursor      = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground  = GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName   = NULL;
    wndclass.lpszClassName  = "Sample Application";

    if (!RegisterClass(&wndclass))
      return FALSE;
    }

  hWnd = CreateWindow("Sample Application",
          "IsDlgItemChecked",
          WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          NULL,
          NULL,
          hInstance,
          NULL);

  hInst = hInstance;
  lpprocDialog = MakeProcInstance((FARPROC)DialogBoxProc, hInst);
  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);
  hMenu = LoadMenu(hInstance, "qchecked");
  SetMenu(hWnd, hMenu);

  while (GetMessage(&msg, NULL, 0, 0))
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
  FreeProcInstance (lpprocDialog);
  return msg.wParam;
  }


long FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned   message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_COMMAND:
      if (wParam == 80)
        {
        DialogBox(hInst, MAKEINTRESOURCE(2), hWnd, lpprocDialog);
        break;
        }
      else
        return DefWindowProc(hWnd, message, wParam, lParam);

    case WM_DESTROY:
      FreeProcInstance((FARPROC)lpprocDialog);
      PostQuitMessage(0);
      break;

    default:
      return DefWindowProc(hWnd, message, wParam, lParam);
    }
  return(0L);
  }


BOOL FAR PASCAL DialogBoxProc(hDlg, message, wParam, lParam)
HWND    hDlg;
unsigned  message;
WORD    wParam;
LONG    lParam;
  {
  HWND hCtl;

  switch (message)
    {
    case WM_INITDIALOG:
      SendDlgItemMessage(hDlg, TOP_CONTROL, BM_SETCHECK, TRUE, (LONG) 0);
      return TRUE;
      break;

    case WM_COMMAND:
      switch (wParam)
  {
  case TOP_CONTROL:
    if (IsDlgButtonChecked(hDlg, TOP_CONTROL))
            MessageBox(GetFocus(), "IS checked", "The top control:", MB_OK);
    else
            MessageBox(GetFocus(), "is NOT checked", "The top control:", MB_O
          break;

  case BOTTOM_CONTROL:
    if (IsDlgButtonChecked(hDlg, BOTTOM_CONTROL))
            MessageBox(GetFocus(), "IS checked", "The bottom control:", MB_OK
    else
            MessageBox(GetFocus(), "is NOT checked", "The bottom control:",
                       MB_OK);
          break;

  case ID_OK:
    EndDialog(hDlg, TRUE);
          break;

  default:
    MessageBox(NULL, "oops", NULL, MB_OK);
    return FALSE;
        }
      break;

    default:
      return FALSE;
    }
  }


QENABLED.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\QENABLED.C

/*
 *
 *   qenabled.c
 *
 *   This program demonstrates the use of the IsWindowEnabled function.
 *   IsWindowEnabled checks to see if the given window is enabled to receive
 *   input. Each window in this application, if enabled, should display a
 *   message box in response to a left button click. IsWindowEnabled is calle
 *   from WinMain in this sample application.
 */

#include "windows.h"

long  FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
long  FAR PASCAL ChildAProc(HWND, unsigned, WORD, LONG);
long  FAR PASCAL ChildBProc(HWND, unsigned, WORD, LONG);

HWND hChAWnd = NULL;
HWND hChBWnd = NULL;


int  PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE   hInstance, hPrevInstance;
LPSTR   lpszCmdLine;
int  cmdShow;
{
  MSG      msg;
  HWND      hWnd;
  HMENU     hMenu;
  BOOL      bEnabled;
  WNDCLASS  wndclass;

  if (!hPrevInstance)
  {
    wndclass.style     = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = WndProc;
    wndclass.cbClsExtra   = 0;
    wndclass.cbWndExtra   = 0;
    wndclass.hInstance   = hInstance;
    wndclass.hIcon     = NULL;
    wndclass.hCursor   = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground   = GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName   = NULL;
    wndclass.lpszClassName   = "Sample Application";

    if (!RegisterClass(&wndclass))
      return FALSE;

    wndclass.style     = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = ChildAProc;
    wndclass.cbClsExtra   = 0;
    wndclass.cbWndExtra   = 0;
    wndclass.hInstance   = hInstance;
    wndclass.hIcon     = NULL;
    wndclass.hCursor   = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground   = GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName   = NULL;
    wndclass.lpszClassName   = "CHILD A";

    if (!RegisterClass(&wndclass))
      return FALSE;

    wndclass.style     = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc   = ChildBProc;
    wndclass.cbClsExtra   = 0;
    wndclass.cbWndExtra   = 0;
    wndclass.hInstance   = hInstance;
    wndclass.hIcon     = NULL;
    wndclass.hCursor   = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground   = GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName   = NULL;
    wndclass.lpszClassName   = "CHILD B";

    if (!RegisterClass(&wndclass))
      return FALSE;
  }

  hWnd = CreateWindow("Sample Application",
      "IsWindowEnabled",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      NULL,
      NULL,
      hInstance,
      NULL);
  ShowWindow(hWnd, cmdShow);
  UpdateWindow(hWnd);

  hChAWnd = CreateWindow("CHILD A",
      "Child A",
      WS_CHILD | WS_SIZEBOX | WS_VISIBLE | WS_CAPTION | WS_CLIPSIBLINGS,
      5,
      5,
      150,
      150,
      hWnd,
      (HMENU)1,
      hInstance,
      NULL);

  hChBWnd = CreateWindow("CHILD B",
      "Child B",
      WS_CHILD | WS_SIZEBOX | WS_VISIBLE | WS_CAPTION | WS_CLIPSIBLINGS,
      270,
      5,
      150,
      150,
      hWnd,
      (HMENU)2,
      hInstance,
      NULL);

  MessageBox(hWnd,
      "if Child A is enabled",
      "I am going to see...",
      MB_OK);
  if (IsWindowEnabled(hChAWnd))
    MessageBox(hWnd,
        "Child A IS enabled",
        "'IsWindowEnabled' says...",
        MB_OK);
  else
    MessageBox(hWnd,
        "Child A is NOT enabled",
        "'IsWindowEnabled' says...",
        MB_OK);
  MessageBox(hWnd,
      "disable Child B",
      "I am going to...",
      MB_OK);
  EnableWindow(hChBWnd, FALSE);
  MessageBox(hWnd,
      "if Child B is enabled",
      "I am going to see...",
      MB_OK);
  if (IsWindowEnabled(hChBWnd))
    MessageBox(hWnd,
        "Child B IS enabled",
        "'IsWindowEnabled' says...",
        MB_OK);
  else
    MessageBox(hWnd,
        "Child B is NOT enabled",
        "'IsWindowEnabled' says...",
        MB_OK);

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

  return msg.wParam;
}


long  FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND    hWnd;
unsigned  message;
WORD    wParam;
LONG    lParam;
{
  switch (message)
  {
  case WM_LBUTTONDOWN:
    {
      MessageBox(hWnd,
          "Left Button Click",
          "PARENT WINDOW",
          MB_OK);
      break;
    }
  case WM_DESTROY:
    {
      PostQuitMessage(0);
      break;
    }
  default:
    return DefWindowProc(hWnd, message, wParam, lParam);
  }
  return(0L);
}


long  FAR PASCAL ChildAProc(hChAWnd, message, wParam, lParam)
HWND hChAWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {

  case WM_LBUTTONDOWN:
    MessageBox(hChAWnd, (LPSTR)"Left Button Click",
        (LPSTR)"CHILD A",
        MB_OK);
    break;

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  case WM_PAINT:
    BeginPaint(hChAWnd, (LPPAINTSTRUCT) & ps);
    EndPaint(hChAWnd, (LPPAINTSTRUCT) & ps);
    break;

  default:
    return DefWindowProc(hChAWnd, message, wParam, lParam);
    break;
  }
  return(0L);
}


long  FAR PASCAL ChildBProc(hChBWnd, message, wParam, lParam)
HWND hChBWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  PAINTSTRUCT ps;

  switch (message)
  {

  case WM_LBUTTONDOWN:
    MessageBox(hChBWnd, (LPSTR)"Left Button Click",
        (LPSTR)"CHILD B",
        MB_OK);
    break;

  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  case WM_PAINT:
    BeginPaint(hChBWnd, (LPPAINTSTRUCT) & ps);
    EndPaint(hChBWnd, (LPPAINTSTRUCT) & ps);
    break;

  default:
    return DefWindowProc(hChBWnd, message, wParam, lParam);
    break;
  }
  return(0L);
}




QUIT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\QUIT.C

/*
 *
 *  QUIT - Demonstrates PostAppMessage and GetWindowTask
 *
 *  This program will get the Task handle to the current Window, and send
 *  a WM_QUIT message to the window which will cause it to go away.
 */

#include <windows.h>
#define IDM_QUIT    100

HANDLE hInst;

int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);
long FAR PASCAL QuitWndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL About(HWND, unsigned, WORD, LONG);

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE   hInstance;
HANDLE   hPrevInstance;
LPSTR   lpCmdLine;
int   nCmdShow;
  {
  HWND      hWnd;
  MSG      msg;
  HANDLE    hMenu;
  WNDCLASS  wndclass;
  if (!hPrevInstance)
    {
    wndclass.style      = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc    = QuitWndProc;
    wndclass.cbClsExtra     = 0;
    wndclass.cbWndExtra     = 0;
    wndclass.hInstance      = hInstance;
    wndclass.hIcon      = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor      = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground  = GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName   = "QuitMenu";
    wndclass.lpszClassName  = "Quit";

    if (!RegisterClass(&wndclass))
      return FALSE;
    }
  hInst = hInstance;               /* Saves the current instance        */

  hMenu = LoadMenu(hInst, "QuitMenu");

  hWnd = CreateWindow("Quit",
          "Quit Sample Application",
          WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          NULL,
          hMenu,
          hInstance,
          NULL);

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

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


long FAR PASCAL QuitWndProc(hWnd, message, wParam, lParam)
HWND    hWnd;
unsigned  message;
WORD    wParam;
LONG    lParam;
  {
  HANDLE  hTask;

  switch (message)
    {
    case WM_COMMAND:
      if (wParam == IDM_QUIT)
  {
  hTask = GetWindowTask(hWnd);
  PostAppMessage(hTask, WM_QUIT, 0, 0L);
  }
      break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

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


QVISIBLE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\QVISIBLE.C

/*
 *
 *   qvisible.c
 *
 *   This program demonstrates the use of the IsWindowVisible function.
 */

#include "windows.h"

long    FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);
long    FAR PASCAL ChildProc (HWND, unsigned, WORD, LONG);

HWND hChildWnd = NULL;

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE     hInstance, hPrevInstance;
LPSTR      lpszCmdLine;
int        cmdShow;
  {
  MSG      msg;
  HWND      hWnd;
  HMENU     hMenu;
  WNDCLASS  wndclass;

  if (!hPrevInstance)
    {
    wndclass.style      = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc    = WndProc;
    wndclass.cbClsExtra     = 0;
    wndclass.cbWndExtra     = 0;
    wndclass.hInstance      = hInstance;
    wndclass.hIcon      = NULL;
    wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName   = NULL;
    wndclass.lpszClassName  = "Sample Application";

    if (!RegisterClass (&wndclass))
      return FALSE;

    wndclass.style      = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc    = ChildProc;
    wndclass.cbClsExtra     = 0;
    wndclass.cbWndExtra     = 0;
    wndclass.hInstance      = hInstance;
    wndclass.hIcon      = NULL;
    wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
    wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
    wndclass.lpszMenuName   = NULL;
    wndclass.lpszClassName  = "CHILD";

    if (!RegisterClass (&wndclass))
      return FALSE;
    }

  hWnd = CreateWindow ("Sample Application",
      "IsWindowVisible",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      NULL,
      NULL,
      hInstance,
      NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  hChildWnd = CreateWindow ("CHILD",
      "Child",
      WS_CHILD | WS_SIZEBOX | WS_CAPTION | WS_CLIPSIBLINGS,
      5,
      5,
      150,
      150,
      hWnd,
      (HMENU)1,
      hInstance,
      NULL);

  MessageBox (hWnd, "the child window is visible", "I am going to see if...",
             MB_OK);
  if (IsWindowVisible (hChildWnd))
    MessageBox (hWnd, "the child window IS visible",
        "'IsWindowVisible' says...", MB_OK);
  else
    MessageBox (hWnd, "the child window is NOT visible",
        "'IsWindowVisible' says...", MB_OK);

  ShowWindow (hChildWnd, SW_SHOWNORMAL);

  MessageBox (hWnd, "the child window is visible",
             "I am going to see if...", MB_OK);

  if (IsWindowVisible (hChildWnd))
    MessageBox (hWnd, "the child window IS visible",
        "'IsWindowVisible' says...", MB_OK);
  else
    MessageBox (hWnd, "the child window is NOT visible",
                "'IsWindowVisible' says...", MB_OK);

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


long    FAR PASCAL WndProc (hWnd, message, wParam, lParam)
HWND    hWnd;
unsigned  message;
WORD    wParam;
LONG    lParam;
  {
  switch (message)
    {
    case WM_LBUTTONDOWN:
      MessageBox (hWnd, "Left Button Click", "PARENT WINDOW", MB_OK);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hWnd, message, wParam, lParam);
    }
  return (0L);
  }

long    FAR PASCAL ChildProc (hChildWnd, message, wParam, lParam)
HWND    hChildWnd;
unsigned  message;
WORD    wParam;
LONG    lParam;
  {
  switch (message)
    {
    case WM_LBUTTONDOWN:
      MessageBox (hChildWnd, (LPSTR)"Left Button Click", (LPSTR)"CHILD A",
                  MB_OK);
      break;

    case WM_DESTROY:
      PostQuitMessage (0);
      break;

    default:
      return DefWindowProc (hChildWnd, message, wParam, lParam);
      break;
    }
  return (0L);
  }


RCLASS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLASS\RCLASS.C

/*
 *  RegisterClass
 *  This function demonstrates the use of the RegisterClass function.  It wil
 *  register a window Class, and then display that window.
 *
 */

#include <windows.h>


long  FAR PASCAL WndProc (HANDLE, unsigned, WORD, LONG);

int  PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR    lpszCmdLine;
int  nCmdShow;
{
  WNDCLASS  wcClass;
  MSG      msg;
  HWND      hWnd;

  if (!hPrevInstance)
  {
    wcClass.lpszClassName = "WndClass";
    wcClass.hInstance    = hInstance;
    wcClass.lpfnWndProc   = WndProc;
    wcClass.hCursor    = LoadCursor (NULL, IDC_ARROW);
    wcClass.hIcon    = NULL;
    wcClass.lpszMenuName  = NULL;
    wcClass.hbrBackground = GetStockObject (WHITE_BRUSH);
    wcClass.style    = CS_HREDRAW | CS_VREDRAW;
    wcClass.cbClsExtra    = 0;
    wcClass.cbWndExtra    = 0;

    if (!RegisterClass (&wcClass))
      return FALSE;
  }

  hWnd = CreateWindow("WndClass",
      "RegisterClass",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      NULL,
      NULL,
      hInstance,
      NULL);

  ShowWindow (hWnd, nCmdShow);
  UpdateWindow (hWnd);

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


long  FAR PASCAL WndProc(hWnd, message, wParam, lParam)
HWND      hWnd;
unsigned  message;
WORD      wParam;
LONG      lParam;
{
  PAINTSTRUCT   ps;
  HDC           hDC;
  HWND    hButton;
  HANDLE  hInst;
  short  xChar,
  yChar;
  TEXTMETRIC  tm;
  WNDCLASS  wndclass;
  BOOL    bRegClass;

  hInst = GetWindowWord(hWnd, GWW_HINSTANCE);
  switch (message)
  {
  case WM_CREATE:
    {
      hDC = GetDC(hWnd);
      GetTextMetrics(hDC, &tm);
      xChar = tm.tmAveCharWidth;
      yChar = tm.tmHeight + tm.tmExternalLeading;
      ReleaseDC(hWnd, hDC);
      hButton = CreateWindow("button",
          "Register Window Class",
          WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
          xChar * 20,
          yChar * 7,
          xChar * 23,
          yChar * 3,
          hWnd,
          0,
          hInst,
          NULL);
      break;
    }
  case WM_COMMAND:
    {
      if (wParam == 0)
      {
  MessageBox(hWnd,
      "Registering window\nclass FooClass:",
      "RegisterClass()",
      MB_OK);
  wndclass.lpszClassName = "FooClass";
  wndclass.hInstance     = hInst;
  wndclass.lpfnWndProc   = DefWindowProc;
  wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  wndclass.hIcon         = NULL;
  wndclass.lpszMenuName  = NULL;
  wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  wndclass.cbClsExtra    = 0;
  wndclass.cbWndExtra    = 0;

  bRegClass = RegisterClass(&wndclass);
  if (bRegClass)
    MessageBox(hWnd,
        "Window class FooClass\nhas been registered.\nAll re-registration\nat
        "RegisterClass()",
        MB_ICONASTERISK);
  else
    MessageBox(hWnd,
        "Registration failed.\nThe class is already\nregistered.",
        "RegisterClass()",
        MB_ICONEXCLAMATION);
      }
      break;
    }
  case WM_DESTROY:
    {
      PostQuitMessage(0);
      break;
    }
  default:
    return(DefWindowProc(hWnd, message, wParam, lParam));
  }
  return(0L);
}




READCOMM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\READCOMM.C

/*
 *  ReadComm
 *  This program demonstrates the use of the function ReadComm.
 *  It attempts to read a specified number of characters from the
 *  communication device that has already been opened and copy the
 *  characters into a buffer. Before attempting to do any read, the
 *  communication device must have its device control block set up
 *  properly to a correct configuration.
 *
 *  This program will only run properly if there is a dumb terminal connected
 *  to COM1: port.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Readcomm";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND    hWnd;          /* Handle to the parent window             */
    short   nCid;          /* Short integer identifying the opened
                            * communication device                    */
    short   nBytes;        /* The number of characters read           */
    char    szBuffer[20];  /* The buffer that is recieving the
                            * characters to be read                   */
    HDC     hDC;           /* Handle to the DC of the client area     */
    DCB     dcb;           /* The device control block                */
    COMSTAT cstat;         /* The current status of the communication
                            * device                                  */

    WinInit( hInstance );

    hWnd = CreateWindow((LPSTR)"Readcomm",
                        (LPSTR)"Read from Communication Devices",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* attempt to open the com1 port */
    nCid = OpenComm ((LPSTR)"COM1", 20, 20);
    if (nCid < 0)
      {
         MessageBox (hWnd, (LPSTR)"Com port not opened!!",(LPSTR)"FAIL!",MB_O
         return 0;
      }

    /* the communication device control block must be set to the appropriate
     * settings of the other dumb terminal in order to read and write
     * properly
     */
    if (GetCommState (nCid, (DCB FAR *) &dcb) >= 0)
      { dcb.BaudRate = 9600;
        dcb.ByteSize = 8;
        dcb.StopBits = ONESTOPBIT;
        dcb.Parity   = NOPARITY;
        dcb.fRtsflow = FALSE;
        dcb.fDtrflow = FALSE;
        dcb.fOutX    = FALSE;
        dcb.fInX     = FALSE;
        dcb.fNull    = FALSE;
        dcb.XonLim   = 1;
        dcb.XoffLim  = 20;
      }

    SetCommState ((DCB FAR *) &dcb);

    /* Put something into the transmit queue of the dumb terminal */
    MessageBox (hWnd, (LPSTR)"Type in something at the other terminal",
                (LPSTR)"Quick", MB_OK);

    /* attempt to read from the recieve queue of the communication device */
    nBytes = ReadComm (nCid, (LPSTR)szBuffer, 20);

    /* in case of an overflow of the recieve queue, GetCommError is
     * called to clear the error condition,; otherwise no other communication
     * function will work properly
     */
    if (GetCommError (nCid, (COMSTAT FAR *) &cstat) == CE_RXOVER)
      {  MessageBox (hWnd, (LPSTR)"Receive Queue overflow", (LPSTR)"ERROR!!",

         /* The error code must be cleared first before reading the receive
          * queue again
          */
         nBytes = ReadComm (nCid, (LPSTR)szBuffer, 20);
      }

    /* Check to see if the read is successfully */
    if (nBytes == 0)
      MessageBox (hWnd, (LPSTR)"No character in the recieve queue",
                    (LPSTR)"None Read", MB_OK);

    if (nBytes > 0)
      { hDC = GetDC (hWnd);
        TextOut (hDC, 10, 10, (LPSTR)szBuffer, nBytes);
        ReleaseDC (hWnd, hDC);
        MessageBox (hWnd,
                    (LPSTR)"Some characters read from the recieve queue",
                    (LPSTR)"Read", MB_OK);
      }

    if (nBytes < 0)
      MessageBox (hWnd, (LPSTR)"Nothing read", (LPSTR)NULL, MB_OK);


    /* must close the communication device before leaving the program */
    CloseComm (nCid);

    return 0;
}


RECT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\RECT.C

/*

Function(s) demonstrated in this program: SetRectEmpty, UnionRect, OffsetRect

Description:  The SetRectEmpty sets all the fields of a rectangle structure
    to 0.  The UnionRect function takes two rectangle structures, and
    places in a third rectangle structure the coordinates of the smallest
    rectangle which contains both of the other rectangles.  The OffsetRect
    function adjusts the coordinates of the rectangle structrure by the
    offsets supplied.

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "Rect.h"

#define PI 3.14159265


char    szRadius  [15];
HANDLE  hInstMain;
FARPROC lpProcGetRadius;
char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];
HWND     hWndMain, hX, hY, hOK2;
FARPROC  lpProcEnterPoint;
FARPROC  lpProcNewEnterPoint;
FARPROC  lpProcOldX;
FARPROC  lpProcOldY;
char     szXValue [40];
char     szYValue [40];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use of the SetRectEmpty, UnionRect, and OffsetRect\n\
Windows functions.",

"Help Message",
"     This program uses the Windows functions\n\
SetRectEmpty, UnionRect, and OffsetRect.  There are\n\
three rectangles displayed in the window.  Two of\n\
these windows are adjustable, and the third is\n\
a union of the first two.  Use the menu to\n\
adjust the size and position of the two rectangles\n\
in pixels.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
    HANDLE  hInstance, hPrevInstance;
    LPSTR  lpszCmdLine;
    int   nCmdShow;
    {
    static char szAppName[] = "Rect";
    HWND  hWnd;
    MSG   msg;
    WNDCLASS  wndclass;

    if (!hPrevInstance)  {
        wndclass.style          = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc    = WndProc;
        wndclass.cbClsExtra     = 0;
        wndclass.cbWndExtra     = 0;
        wndclass.hInstance      = hInstance;
        wndclass.hIcon          = NULL; /*LoadIcon (NULL, IDI_ASTERISK);*/
        wndclass.hCursor        = LoadCursor (NULL, IDC_CROSS);
        wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
        wndclass.lpszMenuName   = szAppName;
        wndclass.lpszClassName  = szAppName;

        if (!RegisterClass (&wndclass) )
            return FALSE;
    }


    hWnd = CreateWindow (szAppName, "Rect",
      WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
      CW_USEDEFAULT, 0, NULL, NULL,
      hInstance, NULL);

    hInstMain = hInstance;
    hWndMain  = hWnd;

    ShowWindow (hWnd, nCmdShow);
    UpdateWindow (hWnd);

    lpProcEnterPoint    = MakeProcInstance (EnterPointDlgProc, hInstance);
    lpProcNewEnterPoint = MakeProcInstance (NewEnterPointDlgProc,hInstance);

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
  HWND      hWnd;
  unsigned    iMessage;
  WORD      wParam;
  LONG      lParam;
  {
   HMENU         hMenu;
static   RECT    Rect1, Rect2, Rect3;
  static short  xClient, yClient;
  HDC          hDC;
  PAINTSTRUCT   ps;
   int           xOffset, yOffset;

  switch (iMessage) {
       case WM_CREATE:
            hMenu = GetSystemMenu (hWnd, FALSE);

            ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                        MF_APPEND | MF_STRING);
            SetRectEmpty (&Rect1);
            SetRectEmpty (&Rect2);
            SetRectEmpty (&Rect3);

            Rect1.top = 50;
            Rect1.left = 150;
            Rect1.right = 250;
            Rect1.bottom = 110;

            Rect2.top = 160;
            Rect2.left = 400;
            Rect2.right = 500;
            Rect2.bottom = 220;
            UnionRect (&Rect3, &Rect2, &Rect1);
            break;

       case WM_SYSCOMMAND:
            switch (wParam) {
               case IDM_ABOUT:
                    ProcessMessage (hWnd, 0);
                    break;
               default:
                    return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
            }
            break;

      case WM_SIZE:
            xClient=LOWORD (lParam);
            yClient=HIWORD (lParam);
            break;


       case WM_COMMAND:
            switch (wParam) {
               case IDM_CHANGERECT1:
                    SetRectEmpty (&Rect1);
                    MessageBox (hWnd, "Rectangle 1 has been emptied",
                                "SetRectEmpty", MB_OK);
                    sprintf (szYValue, "Enter Coordinates");
                    sprintf (szXValue, "rect1.top,  rect1.left");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    Rect1.top  = atoi (szXValue);
                    Rect1.left = atoi (szYValue);

                    sprintf (szYValue, "Enter Coordinates");
                    sprintf (szXValue, "rect1.bottom, rect1.right");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    Rect1.bottom = atoi (szXValue);
                    Rect1.right  = atoi (szYValue);

                    UnionRect (&Rect3, &Rect2, &Rect1);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_CHANGERECT2:
                    SetRectEmpty (&Rect2);
                    MessageBox (hWnd, "Rectangle 2 has been emptied",
                                "SetRectEmpty", MB_OK);
                    sprintf (szYValue, "Enter Coordinates");
                    sprintf (szXValue, "rect2.top,  rect2.left");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    Rect2.top  = atoi (szXValue);
                    Rect2.left = atoi (szYValue);

                    sprintf (szYValue, "Enter Coordinates");
                    sprintf (szXValue, "rect2.bottom, rect2.right");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    Rect2.bottom = atoi (szXValue);
                    Rect2.right  = atoi (szYValue);

                    UnionRect (&Rect3, &Rect2, &Rect1);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_OFFSETRECT1:
                    sprintf (szYValue, "Enter Offsets");
                    sprintf (szXValue, "X Offset, Y Offset");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    xOffset = atoi (szXValue);
                    yOffset = atoi (szYValue);

                    OffsetRect (&Rect1, xOffset, yOffset);
                    UnionRect (&Rect3, &Rect2, &Rect1);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_OFFSETRECT2:
                    sprintf (szYValue, "Enter Offsets");
                    sprintf (szXValue, "X Offset, Y Offset");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    xOffset = atoi (szXValue);
                    yOffset = atoi (szYValue);

                    OffsetRect (&Rect2, xOffset, yOffset);
                    UnionRect (&Rect3, &Rect2, &Rect1);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_HELP:
                    ProcessMessage (hWnd, 2);
                    break;
            }
            break;

      case WM_PAINT:
            hDC=BeginPaint(hWnd, &ps);
            DrawSquare (hDC, Rect1);
            DrawSquare (hDC, Rect2);
            DrawSquare (hDC, Rect3);

            EndPaint (hWnd, &ps);
            break;

       case WM_DESTROY:
            PostQuitMessage (0);
            break;

      default:
            return DefWindowProc( hWnd, iMessage, wParam, lParam );
       }
  return 0L;
}

/***************************************************************************/

BOOL FAR PASCAL GetRadiusDlgProc (hDlg, iMessage, wParam, lParam)
HWND hDlg;
unsigned iMessage;
WORD wParam;
LONG lParam;
{
     int Index;
     char szChange [10];
     long lReturn;

     switch (iMessage) {
        case WM_INITDIALOG:
             SendDlgItemMessage (hDlg, IDD_RADIUS, EM_LIMITTEXT,
                                 (WORD)80, 0L);
             SetDlgItemText (hDlg, IDD_RADIUS, "1.0");
             return TRUE;
             break;

        case WM_COMMAND:
             switch (wParam)
             {
               case IDD_RADIUS:
                    if (HIWORD (lParam) == EN_CHANGE)
                        EnableWindow (GetDlgItem(hDlg,IDOK),
                                     (BOOL)SendMessage(LOWORD (lParam),
                                      WM_GETTEXTLENGTH, 0, 0L)) ;
                    break;

               case IDOK:
                    GetDlgItemText (hDlg, IDD_RADIUS, szRadius, 80) ;
                    OemToAnsi (szRadius, szRadius);
                    EndDialog (hDlg, TRUE);
                    break;

               case IDCANCEL:
                EndDialog (hDlg, FALSE) ;
                    break;

               default:
                    return FALSE;
             }
        default:
             return FALSE;
     }
     return TRUE;
}

/****************************************************************************

BOOL FAR PASCAL EnterPointDlgProc (hDlg, iMessage, wParam, lParam)
HWND hDlg;
unsigned iMessage;
WORD wParam;
LONG lParam;
{
     int Index;
     char szChange [10];
     long lReturn;

     switch (iMessage) {
     case WM_INITDIALOG:
       SendDlgItemMessage (hDlg, IDD_X, EM_LIMITTEXT,
                           (WORD)40, 0L);
       SendDlgItemMessage (hDlg, IDD_Y, EM_LIMITTEXT,
                           (WORD)40, 0L);
       SetDlgItemText (hDlg, IDD_TEXT1, szXValue);
       SetDlgItemText (hDlg, IDD_TEXT2, szYValue);

       hX = GetDlgItem (hDlg, IDD_X);
         lpProcOldX = (FARPROC) GetWindowLong (hX, GWL_WNDPROC);
         SetWindowLong (hX, GWL_WNDPROC, (LONG) lpProcNewEnterPoint);
         SendMessage (hX, EM_SETSEL, 0, MAKELONG (0,32767));
       hY = GetDlgItem (hDlg, IDD_Y);
         lpProcOldY = (FARPROC) GetWindowLong (hY, GWL_WNDPROC);
         SetWindowLong (hY, GWL_WNDPROC, (LONG) lpProcNewEnterPoint);
         SendMessage (hY, EM_SETSEL, 0, MAKELONG (0,32767));
       hOK2 = GetDlgItem (hDlg, IDOK);

       return TRUE;
       break;

     case WM_COMMAND:
       switch (wParam) {
         case IDD_X:
              break;

         case IDD_Y:
              break;

         case IDOK:
              GetDlgItemText (hDlg, IDD_X, szXValue, 10) ;
              GetDlgItemText (hDlg, IDD_Y, szYValue, 10) ;
              EndDialog (hDlg, TRUE);
              break;

         default:
              return FALSE;
      }
    default:
      return FALSE;
  }
  return TRUE;
}

/****************************************************************************

BOOL FAR PASCAL NewEnterPointDlgProc  (hWnd, iMessage, wParam, lParam)
     HWND     hWnd;
     unsigned iMessage;
     WORD     wParam;
     LONG     lParam;
{
     switch (iMessage) {
       case WM_GETDLGCODE:
            return (DLGC_WANTALLKEYS);

       case WM_CHAR:
            if ((wParam == VK_TAB) || (wParam == VK_RETURN)) {
                SendMessage (hWndMain, WM_USER, 0, 0L);
                SetFocus (FindNextWindow (hWnd));
                return TRUE;
            }
            else {
              if (hWnd == hX)
                return ((BOOL)CallWindowProc (lpProcOldX, hWnd,
                        iMessage, wParam, lParam));
              if (hWnd == hY)
                return ((BOOL)CallWindowProc (lpProcOldY, hWnd,
                        iMessage, wParam, lParam));
            }
            break;

       default:
         if (hWnd == hX)
            return ((BOOL)CallWindowProc (lpProcOldX, hWnd,
                    iMessage, wParam, lParam));
         if (hWnd == hY)
            return ((BOOL)CallWindowProc (lpProcOldY, hWnd,
                    iMessage, wParam, lParam));
     }
}

/****************************************************************************

HWND FindNextWindow (hWnd)
     HWND   hWnd;
{
     if (hWnd == hX)      return hY;
     if (hWnd == hY)      return hOK2;
     return NULL;
}

/****************************************************************************

void DrawSquare (hDC, rect)
     HDC       hDC;
     RECT      rect;
{
     MoveTo (hDC, rect.left,  rect.top);
     LineTo (hDC, rect.right, rect.top);
     LineTo (hDC, rect.right, rect.bottom);
     LineTo (hDC, rect.left,  rect.bottom);
     LineTo (hDC, rect.left,  rect.top);
}



RELABS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\RELABS.C

/*

Description:

This program first invokes the function GetRelAbs to find and display
the current mode.  The mode is set to another value using the SetRelAbs
function. GetRelAbs is called again to verify that the mode has indeed
changed.  Below are descriptions for the demonstrated functions.

SetRelAbs sets the relative or absolute mode. This function specifies
whether the coordinates in GDI functions are relative to the origin
of the given device (ABSOLUTE), or relative to the current position
(RELATIVE).  The mode affects the output created by the LineTo and
Polyline functions.

GetRelAbs retrieves the relative-absolute flag. The return value
specifies the current mode.  It can be ABSOLUTE or RELATIVE.

****************************************************************************/

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

long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "GetRelAbs" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWnd = CreateWindow (szAppName,            /* window class name       */
                    "GetRelAbs",  /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWnd, nCmdShow) ;

     UpdateWindow (hWnd) ;

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 PAINTSTRUCT     ps;
 short           fRelAbsFlag;
 HDC             hDC;
 TEXTMETRIC      tm;
 static short    xChar,
                 yChar;

 switch(iMessage)
 {
  case WM_CREATE:
  {
   hDC = GetDC (hWnd);
   GetTextMetrics (hDC, &tm);
   xChar = tm.tmAveCharWidth;
   yChar = tm.tmHeight + tm.tmExternalLeading;
   ReleaseDC (hWnd, hDC);
   break;
  }
  case WM_PAINT:
  {
   hDC = BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);

   fRelAbsFlag = GetRelAbs (hDC);                        /* Check the mode */

   if (fRelAbsFlag == RELATIVE)
      {
      TextOut (hDC,
               xChar,
               yChar,
               (LPSTR)"1. Function GetRelAbs returns RELATIVE, so the mode is
               strlen("1. Function GetRelAbs returns RELATIVE, so the mode is
              );

      SetRelAbs (hDC, ABSOLUTE);
      }
   else /* fRelAbsFlag ==  ABSOLUTE */         /* Set the mode to ABSOLUTE */
      {
      TextOut (hDC,
               xChar,
               yChar,
               (LPSTR)"1. Function GetRelAbs returns ABSOLUTE, so the mode is
               strlen("1. Function GetRelAbs returns ABSOLUTE, so the mode is
              );

      SetRelAbs (hDC, RELATIVE);               /* Set the mode to RELATIVE */
      }

   fRelAbsFlag = GetRelAbs (hDC);                        /* Check the mode */

   if (fRelAbsFlag == RELATIVE)
      {
      TextOut (hDC,
               xChar,
               yChar * 2,
               (LPSTR)"2. Function SetRelAbs sets mode to RELATIVE.  Function
               strlen("2. Function SetRelAbs sets mode to RELATIVE.  Function
              );
      }
   else /* fRelAbsFlag ==  ABSOLUTE */
      {
      TextOut (hDC,
               xChar,
               yChar * 2,
               (LPSTR)"2. Function SetRelAbs sets mode to ABSOLUTE.  Function
               strlen("2. Function SetRelAbs sets mode to ABSOLUTE.  Function
              );
      }


   EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
   break;
  }
  case WM_DESTROY:
  {
   PostQuitMessage(0);
   break;
  }
  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}


REPLY.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\REPLY.C

/*

Description:   This function specifies whether the current window function
    is processing a message that is passed to it through a call to the
    SendMessage function.

*/


#include <windows.h>
#include "Reply.h"
#include "string.h"
#include "stdio.h"

       char         szAppName             [] = "Reply"             ;
       HANDLE       hInstMain                                      ;
       HWND         hWndMain                                       ;
       char         szOutputBuffer1       [70]                     ;
       char         szOutputBuffer2       [600]                    ;

/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use  of  the  ReplyMessage Windows function.  ",

"Help Message",
"     Sample program to illustrate the use of ReplyMessage.\n\
Use the WINSPAWN program to spawn this program in one of\n\
two ways.  The first way, 'Reply Using ReplyMessage',\n\
will capture the input focus using the ReplyMessage\n\
Windows Function.   The second way, 'Reply Regular Spawn',\n\
will not capture the focus.",

"In Reply",
"     Message sent and received from within Reply.\n\
The Reply program has successfully captured the input\n\
focus."

};
/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
    HANDLE  hInstance, hPrevInstance;
    LPSTR  lpszCmdLine;
    int   nCmdShow;
    {
    HWND  hWnd;
    MSG   msg;
    WNDCLASS  wndclass;
    HMENU  hMenu;
    short   xScreen, yScreen;


    if (!hPrevInstance)
  {
  wndclass.style           = CS_HREDRAW | CS_VREDRAW | CS_SAVEBITS;
  wndclass.lpfnWndProc    = WndProc;
  wndclass.cbClsExtra     = 0;
  wndclass.cbWndExtra     = 0;
  wndclass.hInstance      = hInstance;
  wndclass.hIcon           = NULL;
   wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
  wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
  wndclass.lpszMenuName  = szAppName;
  wndclass.lpszClassName  = szAppName;

    if (!RegisterClass (&wndclass) )
        return FALSE;
    }

   xScreen = GetSystemMetrics (SM_CXSCREEN);
    yScreen = GetSystemMetrics (SM_CYSCREEN);

    hWnd = CreateWindow (szAppName, "Reply",
           WS_OVERLAPPEDWINDOW, xScreen / 7, yScreen / 58,
           xScreen * 3 / 4, yScreen * 49 / 50, NULL, NULL,
           hInstance, NULL);

    hInstMain = hInstance;
    hWndMain  = hWnd;

    ShowWindow (hWnd, nCmdShow);
    UpdateWindow (hWnd);

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

    return msg.wParam;
}
/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
   HWND      hWnd;
   unsigned  iMessage;
   WORD      wParam;
   LONG      lParam;
   {
   HMENU         hMenu;
   int           Index;
   HANDLE        hDC;
   HDC           hMemoryDC;
   BITMAP        Bitmap;
  short         foo;
   BOOL          InSend;

   switch (iMessage)
       {
       case WM_CREATE:
            hMenu = GetSystemMenu (hWnd, FALSE);

            ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                        MF_APPEND | MF_STRING);
            break;

       case WM_SIZE:
            break;

       case WM_SYSCOMMAND:
            switch (wParam) {
               case IDM_ABOUT:
                    ProcessMessage (hWnd, 0);
                    break;
               default:
                    return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
            }
       break;


       case WM_COMMAND:
            switch (wParam) {
              case IDM_RECEIVE:
                   ProcessMessage (hWnd, 4);
                   break;

              case IDM_SEND:
                   ReplyMessage (1L);
                   SendMessage (hWnd, WM_COMMAND, IDM_RECEIVE, 0L);
                   break;

              case IDM_REGULAR:
                   break;

              case IDM_HELP:
                   ProcessMessage (hWnd, 2);
                   break;
           }
            break;

       case WM_DESTROY:
            PostQuitMessage (0);
            break;

      default:
            return DefWindowProc( hWnd, iMessage, wParam, lParam );
       }
  return 0L;
}

/****************************************************************************



RRECT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\RRECT.C

/*
 *  RoundRect
 *
 *  This program demonstrates the use of the function RoundRect.
 *  It gets a DC and then draws a rectangle with rounded corners in the
 *  client area.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Rrect";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;             /* Handle to the parent window    */
    BOOL  bRect;            /* flag for RoundRect routine     */
    HDC   hDC;              /* display context of client area */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Rrect",
                        (LPSTR)"Drawing Round Rectangle",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* draw the round rectangle on the client area */
    hDC = GetDC (hWnd);
    bRect = RoundRect (hDC, 50, 50, 175, 150, 25, 20);
    ReleaseDC (hWnd, hDC);

    /* return code for RoundRect routine */
    if (bRect)
      {  MessageBox (hWnd, (LPSTR)"The rectangle is drawn",
                     (LPSTR)"Done", MB_OK);
      }
    else
      {  MessageBox (hWnd, (LPSTR)"The rectangle is not drawn",
                     (LPSTR)NULL, MB_OK);
      }

    return 0;
}



SAVEDC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DISPLAY\SAVEDC.C

/*
 *  SaveDC
 *  savedc.c,
 *
 *  This program demonstrates the use of the function SaveDC.
 *  It saves the current state of the display context by copying state
 *  information to a context stack. The saved display context can later
 *  be restored by using the RestoreDC function.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Savedc";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND   hWnd;                /* Handle to the parent window    */
    HDC    hDC;                 /* Display context of client area */
    HBRUSH hNewBrush, hOldBrush;/* Handle to the brushes          */
    short  nDCIdentity;         /* identifier to the saved DC     */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Savedc",
                        (LPSTR)"Saving Display Context",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Get the DC of the client area */
    hDC = GetDC (hWnd);

    /* Create a new brush and change the DC */
    hNewBrush = CreateSolidBrush (GetSysColor (COLOR_WINDOW));
    hOldBrush = (HBRUSH) SelectObject (hDC, (HANDLE) hNewBrush);

    /* Save the DC and get an unique identity of the saved DC */
    nDCIdentity = SaveDC (hDC);

    /* Release the DC */
    ReleaseDC (hWnd, hDC);

    /* return code for SaveDC routine. It is 0 if the DC is not saved */
    if (nDCIdentity)
      {  MessageBox (hWnd, (LPSTR)"The DC is saved",
                     (LPSTR)"Done", MB_OK);
      }
    else
      {  MessageBox (hWnd, (LPSTR)"The DC is not saved",
                     (LPSTR)NULL, MB_OK);
      }

    return 0;
}


SBITDIM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\SBITDIM.C

/*
 *  SetBitmapDimension
 *  sbitdim.c,
 *
 *  This program demonstrates the use of the function SetBitmapDimension.
 *  This funtion assigns a width and height to a bitmap in 0.1 millimeters
 *  units.  These values are not used internally by GDI.
 *
 */

#include "windows.h"

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  HBITMAP hBitmap;
  DWORD ptOldDimensions;
  DWORD ptDimensions;

  hBitmap = LoadBitmap ( hInstance, (LPSTR)"SMILE" );

  MessageBox (NULL, (LPSTR)"Setting new dimensions ",
             (LPSTR)"SetBitmapDimension", MB_OK);

  ptOldDimensions = SetBitmapDimension ( hBitmap, 15, 15 );

  ptDimensions = GetBitmapDimension ( hBitmap );

  if ( (HIWORD(ptDimensions) != 0) || (LOWORD(ptDimensions) != 0) )
     MessageBox (NULL, (LPSTR)"New dimensions set.",
                (LPSTR)"SetBitmapDimension", MB_OK);
  else
     MessageBox (NULL, (LPSTR)"New dimensions not set",
                (LPSTR)"SetBitmapDimension", MB_OK);

  return 0;
}


SCEM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\SCEM.C

/*
 *
 *  SetCommEventMask
 *
 *  This program demonstrates the use of the function SetCommEventMask.
 *  This function enables and retrieves the event mask of the communication
 *  device specified bye the first parameter.
 *
 *  Microsoft Product Support Services
 *  Windows Version 2.0 function demonstration application
 *
 */

#include <windows.h>

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  int nCid;
  WORD lpEvent;
  char szBuffer [70];

  nCid = OpenComm ( (LPSTR)"COM1", 50, 50);
  if ( nCid < 0 )
     {
     MessageBox (NULL, (LPSTR)"OpenComm Failed", (LPSTR)"OpenComm",
        MB_OK|MB_ICONEXCLAMATION);
     exit (1);
     }
  MessageBox (NULL, (LPSTR)"Setting EV_ERR mask", (LPSTR)"SetCommEventMask",
     MB_OK);

  SetCommEventMask ( nCid, EV_ERR );

  GetCommEventMask ( nCid, EV_ERR );
  WriteComm ( nCid, (LPSTR)"This is a test!!!", 25 );

  lpEvent = SetCommEventMask( nCid, EV_ERR );
  sprintf (szBuffer, "Pointer to the event mask is %x", lpEvent);

  MessageBox (NULL, (LPSTR)szBuffer, (LPSTR)"SetCommEventMask",
              MB_OK);

  CloseComm ( nCid );

  return 0;
}


SCNTOCLI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLIENT\SCNTOCLI.C

/*
 *  ScreenToClient
 *  scntocli.c,
 *
 *  This program demonstrates the use of the function ScreenToClient.
 *  It converts the screen coordinates of the point into equivalent client
 *  coordinates. The new coordinates replace the existing point.
 *
 */

#include "windows.h"
#include <stdio.h>

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Scntocli";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND   hWnd;                /* Handle to the parent window    */
    POINT  ptCurrentPoint;      /* POINT data type                */
    char   szBuffer[60];        /* string buffer for output       */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Scntocli",
                        (LPSTR)"Screen/Client Coordinates",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Initializing the point to some screen coordinate and display the
     * value in a message box
     */
    ptCurrentPoint.x = 234;
    ptCurrentPoint.y = 150;
    sprintf (szBuffer, "The screen coordinates of the point is %d and %d",
             ptCurrentPoint.x, ptCurrentPoint.y);
    MessageBox (hWnd, (LPSTR)szBuffer, (LPSTR)"Screen", MB_OK);

    /* convert the point to client coordinate and display the new value
     * in a message box
     */
    ScreenToClient (hWnd, (POINT FAR *) &ptCurrentPoint);
    sprintf (szBuffer, "The client coordinates of the point is %d and %d",
             ptCurrentPoint.x, ptCurrentPoint.y);
    MessageBox (hWnd, (LPSTR)szBuffer, (LPSTR)"Client", MB_OK);

    return 0;
}


SCRDC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SCROLL\SCRDC.C

/*
Function(s) demonstrated in this program: ScrollDC
Compiler version: C 5.1
Description:
*/

#include <windows.h>
#include "scrdc.h"

static char szFuncName [] = "ScrollDC";
static char szAppName [] = "SCRDC";

int PASCAL WinMain ( hInstance, hPrevInstance, lpszCmdLine, nCmdShow )
HANDLE      hInstance, hPrevInstance;
LPSTR       lpszCmdLine;
int         nCmdShow;
{
     HWND        hWnd;
     WNDCLASS    wndclass;
     MSG         msg;
     HMENU       hMenu;

     if (!hPrevInstance) {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW;
          wndclass.lpfnWndProc   = WndProc;
          wndclass.cbClsExtra    = 0;
          wndclass.cbWndExtra    = 0;
          wndclass.hInstance     = hInstance;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
          wndclass.lpszMenuName  = "SCR";
          wndclass.lpszClassName = szFuncName;

          if (!RegisterClass (&wndclass))
               return FALSE;
          }

     hMenu = LoadMenu ( hInstance, "SCR" );


     hWnd = CreateWindow (szFuncName,           /* window class name       */
                    szAppName,                  /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    hMenu,                      /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL);                      /* create parameters       */

     ShowWindow (hWnd, nCmdShow);
     UpdateWindow (hWnd);

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
{
   HDC         hDC;
   PAINTSTRUCT ps;
   RECT        strRectangle;
   RECT        strClipRectangle;
   RECT        strDirtyRectangle;
   HBRUSH      hSolidBrush;
   BOOL        bfScrolled;
   int         nIndex;

   switch(iMessage)
   {
   case WM_INITMENU:
      InvalidateRect ( hWnd, (LPRECT)NULL, TRUE );
      break;
    case WM_COMMAND:
       switch ( wParam )
          {
          case IDM_BOX:
             strRectangle.top = 0;
             strRectangle.bottom = 100;
             strRectangle.left = 0;
             strRectangle.right = 100;
             strClipRectangle.top = 0;
             strClipRectangle.bottom = 100;
             strClipRectangle.left = 0;
             strClipRectangle.right = 250;

             hDC = GetDC ( hWnd );
             hSolidBrush = CreateSolidBrush ( 0xFF0000 );
             FillRect ( hDC, (LPRECT)&strRectangle, hSolidBrush );

             MessageBox ( hWnd, (LPSTR)"Going to scroll the DC.",
                (LPSTR)szFuncName, MB_OK );

             bfScrolled = ScrollDC ( hDC, 110, 0, (LPRECT)&strRectangle,
                (LPRECT)&strClipRectangle, NULL, (LPRECT)&strDirtyRectangle )

             if ( bfScrolled == TRUE )
                {
                MessageBox ( hWnd, (LPSTR)"Going to invalidate the box.",
                   (LPSTR)szFuncName, MB_OK );
                InvalidateRect ( hWnd, (LPRECT)&strRectangle, TRUE );
                }
             else
                MessageBox ( hWnd, (LPSTR)"Could not scroll the DC.",
                   (LPSTR)szFuncName, MB_OK | MB_ICONHAND );

             ReleaseDC ( hWnd, hDC );

             break;
          default :
             break;
          }
       break;
     case WM_DESTROY:
       PostQuitMessage(0);
       break;
     default:
       return DefWindowProc (hWnd, iMessage, wParam, lParam);
     return (0L);
   }
}


SCROLL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SCROLL\SCROLL.C

/* SCROLL.C               */
/* This program illistrates the use of ScrollDC and ScrollWindow */
/* as well as many other Windows functions. ScrollDC is used to  */
/* "Bounce" individual balls, one at a time, from the top of the */
/* display to the bottom of the display. ScrollWindow is used to */
/* "Raise" all the balls from the bottom of the display to the   */
/* top of the display. This program gets the resolution of the   */
/* screen to determine what would be a good shape for the ball   */
/* as well as to deternime how fast to scroll the ball. We also  */
/* get the size of the client area so that we can deternime how  */
/* many balls to draw on the screen. I decided the height of the */
/* ball should be 1/10 the height of the client area and the it  */
/* should be drawn 1/10 of the way down the client area and the  */
/* same distance over on the client area. The other balls are   */
/* drawn similarly. Enjoy .....................................  */

#include <windows.h>
#include "scroll.h"


long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;

static char szAppName [] = "Scroll" ;

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {

     HWND        hWnd ;
     MSG         msg ;
     WNDCLASS   wndclass ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
    wndclass.hIcon   = LoadIcon (hInstance, szAppName) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName  = szAppName;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWnd = CreateWindow (szAppName,       /* window class    */
        "Scroll",   /* window caption      */
                    WS_OVERLAPPEDWINDOW,     /* window style            */
                    CW_USEDEFAULT,           /* initial x position      */
                    0,                       /* initial y position      */
                    CW_USEDEFAULT,           /* initial x size          */
                    0,                       /* initial y size          */
                    NULL,                    /* parent window handle    */
                    NULL,                    /* window menu handle      */
                    hInstance,               /* program instance handle */
                    NULL) ;                  /* create parameters       */

     ShowWindow (hWnd, nCmdShow) ;
     UpdateWindow (hWnd) ;

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

void FAR PASCAL StopOne(){
    return;
    }


long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
     HWND      hWnd ;
     unsigned      iMessage ;
     WORD      wParam ;
     LONG      lParam ;
     {
     static int   xClient, yClient ;
     static int   xScreen, yScreen ;
     static short   numBalls , bounced ;
     static short   ScrollRate ;
     HDC      hDC ;
     PAINTSTRUCT    ps ;
     RECT      ClientRect ;
     RECT      DcRect ;
     RECT      Ball ;
     RECT      NewBall ;
     RECT      ScrollBox ;
     short      i, j, up, down ;
     char szBuffer[80] ;

     switch (iMessage)
    {
    case WM_CREATE:

/* Get the resolution of the Screen */

         xScreen = GetSystemMetrics (SM_CXSCREEN) ;
         yScreen = GetSystemMetrics (SM_CYSCREEN) ;

/* Get the size of the client area initially */

         GetClientRect (hWnd, &ClientRect) ;

/* and save it in static variables */

         yClient = ClientRect.bottom - ClientRect.top ;
         xClient = ClientRect.right - ClientRect.left  ;

/* Set scroll speed for different resolutions */

         if (yClient <= 50) ScrollRate = 1 ;
         if (yClient > 100)  ScrollRate = 3 ;
         if (yClient > 175)  ScrollRate = 5 ;

         break ;


    case WM_SIZE:

/* Update the size of the client area */

         yClient = HIWORD (lParam) ;
         xClient = LOWORD (lParam) ;

/* Set scroll speed for different resolutions */

         if (yClient <= 50) ScrollRate = 1 ;
         if (yClient > 100)  ScrollRate = 3 ;
         if (yClient > 175)  ScrollRate = 5 ;

         break ;


         break ;

    case WM_PAINT:

/* Begin to paint the client area and redraw the balls */

         BeginPaint (hWnd, &ps);

/* Initialize the size of the ball */

         Ball.top    = ( yClient / 10) ;
         Ball.bottom = ( yClient / 5) ;
         Ball.left   = ((Ball.bottom - Ball.top) * (xScreen / yScreen)) ;
         Ball.right  = 2 * Ball.left ;

/* Determine the number of balls that can fit on the screen */

         numBalls = ( xClient - (Ball.right - Ball.left) ) /
            ( 2 * (Ball.right - Ball.left)) ;

/* And use this as a standard for drawing the balls */

         NewBall = Ball ;

         for (i = 0 ; i < numBalls; i ++ ) {

     Ellipse (ps.hdc, NewBall.left, NewBall.top,
        NewBall.right, NewBall.bottom);

/* Update the position of the new ball */

     NewBall.left = NewBall.left +  2 * (Ball.right - Ball.left);
     NewBall.right = NewBall.right + 2 * (Ball.right - Ball.left);

         }

         EndPaint (hWnd, &ps);

/* Set bounced to false, signifing that the balls are on the
      top of the display */

         bounced = 0 ;

         break ;

    case WM_COMMAND:

         switch (wParam)
         {
         case IDM_DC:

        if (!bounced) {

/* Initialize the size of the ball */

           Ball.top   = ( yClient / 10) ;
           Ball.bottom = ( yClient / 5) ;
           Ball.left   = ((Ball.bottom - Ball.top) * (xScreen / yScreen)) ;
           Ball.right  = 2 * Ball.left ;

/* Initialize the scrolling area for one ball */

           ScrollBox.top = 1 ;
           ScrollBox.left = Ball.left / 2 ;
           ScrollBox.bottom = yClient ;
           ScrollBox.right = ScrollBox.left + (2 * Ball.left) ;

           hDC = GetDC (hWnd) ;
           for (i = 0 ; i < numBalls; i ++ ) {

             up = Ball.bottom ;
             down = yClient - (2 * ScrollRate) ;

/* Until the ball is done bouncing */

             while (up < down ) {

/* It goes down */

         for (j = up ; j <= down ; j += ScrollRate ) {
           ScrollDC (hDC,0, ScrollRate,
                 &ScrollBox,&ScrollBox,
                 NULL,NULL);
         }

/* and won't go up quit so high */
         up = up + ((down - up) / 3) + 1 ;
           /*  MessageBeep (0); */


/* and now it bounces up */
         for (j = up ; j <= down ; j += ScrollRate ) {
           ScrollDC (hDC,0, - ScrollRate,
                 &ScrollBox,&ScrollBox,
                 NULL,NULL);
         }
             }

/* and bounces down for the last time */

             for (j = up ; j <= down ; j += ScrollRate ) {
         ScrollDC (hDC,0, 1,&ScrollBox,&ScrollBox,
               NULL,NULL);
             }

/* Move to the next scrolling area */

             ScrollBox.left = ScrollBox.left + ( 2 * Ball.left) ;
             ScrollBox.right = ScrollBox.right + (2 * Ball.left);
           }

           ReleaseDC (hWnd, hDC) ;
           bounced = 1 ;
        }

        break ;

         case IDM_WIN:

/* If the balls are at the bottom of the display then */

        if (bounced) {

/* Initialize how far they need to rise */

          down = yClient - (2 * ScrollRate);
          up = (yClient / 5) ;

/* And raise them to the top */

          for (j = up ; j <= down ; j += ScrollRate ) {
            ScrollWindow (hWnd, 0,- ScrollRate,
                 NULL, NULL) ;
          }

          MessageBeep (0);

/* Set bounced to false, signifing the balls are at the top of the display */

          bounced = 0 ;

        }

        break ;

         case IDM_EXIT:

        SendMessage (hWnd, WM_CLOSE, 0, 0L);
        break;

         case IDM_HELP:

        MessageBox (hWnd, "Try Scrolling the DC ...",
             szAppName, MB_ICONASTERISK | MB_OK) ;
        break;
         case IDM_ABOUT:

        MessageBox (hWnd, "SCROLL DEMO.",
             szAppName, MB_ICONASTERISK | MB_OK) ;
         default:
        break;
         }
         break;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               break ;

          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
          }
     return 0L ;
     }



SCRPAT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SCROLL\SCRPAT.C

/*
 *  Function(s) demonstrated in this program: UnrealizeObject, SetBrushOrg,
 *                                            PatBlt
 *  Compiler version: 5.1
 *  Description:
 *     This program will set up a cross hatched pattern on the client
 *  area of a window.  It will then scroll it using the two above functions
 *  in conjunction with timer messages.
 */

#include <windows.h>

int     iTimerCount;
HBRUSH  hNewBrush;
RECT    rRect;

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance ;
LPSTR       lpszCmdLine ;
int         nCmdShow ;
  {
  static char szAppName [] = "ScrPat" ;
  HWND        hWnd ;
  WNDCLASS    wndclass ;
  MSG msg;
  HDC hDC;

  if (!hPrevInstance)
    {
    wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
    wndclass.lpfnWndProc   = WndProc ;
    wndclass.cbClsExtra    = 0 ;
    wndclass.cbWndExtra    = 0 ;
    wndclass.hInstance     = hInstance ;
    wndclass.hIcon         = NULL;
    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = NULL;
    wndclass.lpszMenuName  = NULL ;
    wndclass.lpszClassName = szAppName ;

    if (!RegisterClass (&wndclass))
      return FALSE ;
    }

  hWnd = CreateWindow (szAppName,            /* window class name       */
                 "ScrPat Sample Application",  /* window caption          */
                 WS_OVERLAPPEDWINDOW,        /* window style            */
                 CW_USEDEFAULT,              /* initial x position      */
                 0,                          /* initial y position      */
                 CW_USEDEFAULT,              /* initial x size          */
                 0,                          /* initial y size          */
                 NULL,                       /* parent window handle    */
                 NULL,                       /* window menu handle      */
                 hInstance,                  /* program instance handle */
                 NULL) ;                     /* create parameters       */

  /* Set up the background brush. */
  hNewBrush = CreateHatchBrush(HS_DIAGCROSS, RGB(0, 0, 255));
  hDC = GetDC(hWnd);
  GetClientRect( hWnd, (LPRECT) &rRect );
  ReleaseDC(hWnd, hDC);

  /* Start up the timer to roll the pattern. */
  SetTimer(hWnd, 100, 133, 0L);

  ShowWindow (hWnd, nCmdShow) ;
  UpdateWindow (hWnd) ;

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
  {
  HDC         hDC;
  HMENU       hMenu;
  PAINTSTRUCT ps;

  switch(iMessage)
    {
    case WM_CREATE:
      break;

    case WM_ERASEBKGND:
        /* Don't let it paint the background. */
        return((long)TRUE);

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );

        SelectObject(ps.hdc, GetStockObject(NULL_BRUSH));
        UnrealizeObject(hNewBrush);
        SetBrushOrg(ps.hdc, 0, iTimerCount);
        SelectObject(ps.hdc, hNewBrush);

        PatBlt(ps.hdc,
               ps.rcPaint.left,
               ps.rcPaint.top,
               ps.rcPaint.right - ps.rcPaint.left,
               ps.rcPaint.bottom - ps.rcPaint.top,
               PATCOPY);

        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_TIMER:
        if (wParam == 100 ) {

            iTimerCount = (iTimerCount+1) % 64;

            hDC = GetDC(hWnd);

            SelectObject(hDC, GetStockObject(NULL_BRUSH));
            UnrealizeObject(hNewBrush);
            SetBrushOrg(hDC, 0, iTimerCount);
            SelectObject(hDC, hNewBrush);

            PatBlt(hDC,
                   rRect.left,
                   rRect.top,
                   rRect.right,
                   rRect.bottom,
                   PATCOPY);

            ReleaseDC(hWnd, hDC);

            break;
            }

    case WM_DESTROY:
      {
      PostQuitMessage(0);
      break;
      }
    default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
    }
    return (0L);
  }


SECLIPRG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\SECLIPRG.C

/*
 *  Program Name:    secliprg.c
 *
 *  Description:
 *   The program below will create a region and select it as a
 *   clip region in the window.  A (partial) rectangle will be
 *   drawn in the clip region to show where the clipping takes place.
 *
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_SelectClipRgn(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  HRGN hNewRgn;
  short nRgnType;

  hNewRgn = CreateRectRgn(50, 50, 200, 100);

  nRgnType = SelectClipRgn(hDC, hNewRgn);      /* region selected     */

  if (nRgnType == 1)                     /* Check for error */
    {
    MessageBox(hWnd,(LPSTR)"SelectClipRgn failed.",(LPSTR)"ERROR",MB_ICONHAND
      return;
    }

  Rectangle( hDC, 60, 60, 220, 80);
  DeleteObject( hNewRgn );

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"SelectClipRgn";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"SelectClipRgn",
                        (LPSTR)"SelectClipRgn()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_SelectClipRgn(hWnd, ps.hdc);
        ValidateRect(hWnd, (LPRECT) NULL);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


SELOBJ.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\OBJECT\SELOBJ.C

/*
Function(s) demonstrated in this program: SelectObject
Compiler version:5.1
Description: This example creates a object (a pen), selects the object into
             the hDC, and checks the return value.
*/

#include <windows.h>
#include "selobj.h"

static char szAppName [] = "SELOBJ";
static char szFuncName [] = "SelectObject";

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance;
HANDLE      hPrevInstance;
LPSTR       lpszCmdLine;
int         nCmdShow;
{

   HWND        hWnd;
   WNDCLASS    wndclass;
   MSG         msg;
   HMENU       hMenu;

   if (!hPrevInstance)
      {
      wndclass.style         = CS_HREDRAW | CS_VREDRAW;
      wndclass.lpfnWndProc   = WndProc;
      wndclass.cbClsExtra    = 0;
      wndclass.cbWndExtra    = 0;
      wndclass.hInstance     = hInstance;
      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION);
      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
      wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
      wndclass.lpszMenuName  = (LPSTR)"Select";
      wndclass.lpszClassName = szAppName;

      if (!RegisterClass (&wndclass))
         return FALSE;
      }

   hMenu = LoadMenu ( hInstance, (LPSTR)"Select" );

   hWnd = CreateWindow (szAppName,            /* window class name       */
                  szFuncName,                 /* window caption          */
                  WS_OVERLAPPEDWINDOW,        /* window style            */
                  CW_USEDEFAULT,              /* initial x position      */
                  0,                          /* initial y position      */
                  CW_USEDEFAULT,              /* initial x size          */
                  0,                          /* initial y size          */
                  NULL,                       /* parent window handle    */
                  hMenu,                      /* window menu handle      */
                  hInstance,                  /* program instance handle */
                  NULL);                      /* create parameters       */

   ShowWindow (hWnd, nCmdShow);
   UpdateWindow (hWnd);

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

   return (msg.wParam);
}

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
{
   HANDLE   hObject;
   HDC      hDC;
   HPEN     hPen;

   switch(iMessage)
   {
   case WM_COMMAND:
      switch ( wParam )
         {
         case IDM_SELECT:
            hDC = GetDC ( hWnd );
            hPen = CreatePen ( 0, 2, (DWORD)0xFF00FF );
            if ( !hPen )
               {
               MessageBox ( hWnd, (LPSTR)"Pen was not created",
                  (LPSTR)szFuncName, MB_OK );
               return (0L);
               }

            hObject = SelectObject ( hDC, hPen );
            if ( hObject )
               MessageBox ( hWnd, (LPSTR)"The object (a pen) was selected",
                  (LPSTR)szFuncName, MB_OK );
            else
               MessageBox ( hWnd, (LPSTR)"The object (a pen) was not selected
                  (LPSTR)szFuncName, MB_OK );

            DeleteObject ( hObject );
            ReleaseDC ( hWnd, hDC );
            break;

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

   case WM_DESTROY:
      PostQuitMessage(0);
      break;

   default:
      return DefWindowProc (hWnd, iMessage, wParam, lParam);
   }
   return (0L);
}


SENDDLG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DIALOG\SENDDLG.C

/*
 *  SendDlgItemMessage
 *  senddlg.c,
 *
 *  This program will open up a Dialog box with an edit conrol. When the
 *  user hits the ADD button, the program will send the LISTBOX a
 *  LB_ADDSTRING message to along with appropriate parameters to add the
 *  string in the edit control to the listbox.
 *
 */

 "windows.h"      /* required for all Windows applications */
 "senddlg.h"      /* specific to this program              */

HANDLE hInst;             /* current instance                      */

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;         /* current instance             */
HANDLE hPrevInstance;     /* previous instance            */
LPSTR lpCmdLine;          /* command line                 */
int nCmdShow;             /* show-window type (open/icon) */
{
    HWND hWnd;            /* window handle       */
    MSG msg;              /* message             */
    HANDLE hMenu;         /* Handle to the menu  */

    if (!hPrevInstance)              /* Has application been initialized? */
        if (!SendDlgInit(hInstance))
            return (NULL);           /* Exits if unable to initialize     */

    hInst = hInstance;               /* Saves the current instance        */

    hMenu = LoadMenu( hInst, (LPSTR)"SendDlgMenu" );
                                     /*  Load the menu    */

    hWnd = CreateWindow("SendDlg",   /* window class      */
        "SendDlg Sample Application",  /* window name       */
        WS_OVERLAPPEDWINDOW,         /* window style      */
        CW_USEDEFAULT,               /* x position        */
        CW_USEDEFAULT,               /* y position        */
        CW_USEDEFAULT,               /* width             */
        CW_USEDEFAULT,               /* height            */
        NULL,                        /* parent handle     */
        hMenu,                       /* menu or child ID  */
        hInstance,                   /* instance          */
        NULL);                       /* additional info   */

    if (!hWnd)                       /* Was the window created? */
        return (NULL);

    ShowWindow(hWnd, nCmdShow);      /* Shows the window        */
    UpdateWindow(hWnd);              /* Sends WM_PAINT message  */

    while (GetMessage(&msg,     /* message structure                      */
            NULL,               /* handle of window receiving the message */
            NULL,               /* lowest message to examine              */
            NULL))              /* highest message to examine             */
        {
        TranslateMessage(&msg);  /* Translates virtual key codes           */
        DispatchMessage(&msg);   /* Dispatches message to window           */
    }
    return (msg.wParam);         /* Returns the value from PostQuitMessage */
}

BOOL SendDlgInit(hInstance)
HANDLE hInstance;                /* current instance           */
{
    HANDLE hMemory;              /* handle to allocated memory */
    PWNDCLASS pWndClass;         /* structure pointer          */
    BOOL bSuccess;               /* RegisterClass() result     */

    hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
    pWndClass = (PWNDCLASS) LocalLock(hMemory);

    pWndClass->style = NULL;
    pWndClass->lpfnWndProc = SendDlgWndProc;
    pWndClass->hInstance = hInstance;
    pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION);
    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
    pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
    pWndClass->lpszMenuName = (LPSTR) "SendDlgMenu";
    pWndClass->lpszClassName = (LPSTR) "SendDlg";

    bSuccess = RegisterClass(pWndClass);

    LocalUnlock(hMemory);     /* Unlocks the memory    */
    LocalFree(hMemory);       /* Returns it to Windows */

    return (bSuccess);        /* Returns result of registering the window */
}

long FAR PASCAL SendDlgWndProc(hWnd, message, wParam, lParam)
HWND hWnd;                    /* window handle                   */
unsigned message;             /* type of message                 */
WORD wParam;                  /* additional information          */
LONG lParam;                  /* additional information          */
{
    FARPROC lpProcAbout;      /* pointer to the "About" function */
    HMENU hMenu;              /* handle to the System menu       */

    switch (message) {
        case WM_SYSCOMMAND:   /* message: command from system menu */
            if (wParam == ID_ABOUT) {
                lpProcAbout = MakeProcInstance(About, hInst);

                DialogBox(hInst,         /* current instance         */
                    "AboutBox",          /* resource to use          */
                    hWnd,                /* parent handle            */
                    lpProcAbout);        /* About() instance address */

                FreeProcInstance(lpProcAbout);
                break;
            }

            else                         /* Lets Windows process it       */
                return (DefWindowProc(hWnd, message, wParam, lParam));

        case WM_CREATE:                  /* message: window being created */

            /* Get the handle of the System menu */

            hMenu = GetSystemMenu(hWnd, FALSE);

            /* Add a separator to the menu */

            ChangeMenu(hMenu,                    /* menu handle         */
                NULL,                            /* menu item to change */
                NULL,                            /* new menu item       */
                NULL,                            /* menu identifier     */
                MF_APPEND | MF_SEPARATOR);       /* type of change      */

            /* Add new menu item to the System menu */

            ChangeMenu(hMenu,                    /* menu handle         */
                NULL,                            /* menu item to change */
                "A&bout SendDlg...",             /* new menu item       */
                ID_ABOUT,                        /* menu identifier     */
                MF_APPEND | MF_STRING);          /* type of change      */
            break;

        case WM_COMMAND:
            if ( wParam == IDM_DIALOG )
              {
              FARPROC    lpProcLineList;

              lpProcLineList = MakeProcInstance( LineList, hInst );

              DialogBox( hInst,             /*  Current Instance  */
                         "ListIn",          /*  Resource to use  */
                         hWnd,              /*  Parent Handle  */
                         lpProcLineList );
              FreeProcInstance( lpProcLineList );
              break;
              }

        case WM_DESTROY:             /* message: window being destroyed */
            PostQuitMessage(0);
            break;

        default:                     /* Passes it on if unproccessed    */
            return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (NULL);
}

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:              /* message: initialize dialog box */
            return (TRUE);

        case WM_COMMAND:                 /* message: received a command */
            if (wParam == IDOK) {        /* "OK" box selected?          */
                EndDialog(hDlg, NULL);   /* Exits the dialog box        */
                return (TRUE);
            }
            break;
    }
    return (FALSE);                      /* Didn't process a message    */
}

BOOL FAR PASCAL LineList(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    char  szBuffer[ 50 ];    /*  Buffer to hold text from edit control  */

    switch (message) {
        case WM_INITDIALOG:              /* message: initialize dialog box */
            return (TRUE);

        case WM_COMMAND:                 /* message: received a command */
            if (wParam == ID_ADD )       /* "ADD" box selected?         */
              {
              GetDlgItemText( hDlg,      /*  Handle to the dialog box  */
                              ID_EDIT,   /*  ID of item to get text from  */
                              (LPSTR)szBuffer,  /*  Pointer to buffer  */
                              50 );      /*  Maximum size of buffer  */
              SendDlgItemMessage( hDlg,  /*  Handle to the dialog box  */
                                  ID_LISTBOX,  /*  ID for item to send the
                                                *  message to  */
                                  LB_ADDSTRING,  /*  Message to send  */
                                  0,     /*  The wParam parameter  */
                                  (LONG)(LPSTR)szBuffer );  /*  lParam  */
              SetDlgItemText( hDlg,         /*  Handle to the dialog box  */
                              ID_EDIT,      /*  ID for the edit control  */
                              (LPSTR)"" );  /*  Text to put in edit control *
              SetFocus( GetDlgItem( hDlg, ID_EDIT ) );
                             /*  Give the focus to the edit control  */
/*  The SendDlgItemMessage sends a message to the Listbox to add the
 *  string to the listbox.  After that we set the text in the edit control
 *  to an empty string, effectively clearing the edit control.  Then
 *  finally we set the focus to the edit control.  */

              return (TRUE);      /*  We processed a message  */
              }
            if ( wParam == ID_OK )
              {
              EndDialog(hDlg, NULL);   /* Exits the dialog box        */
              return (TRUE);
              }
            if ( wParam == ID_CANCEL )
              {
              EndDialog(hDlg, NULL);   /* Exits the dialog box        */
              return (TRUE);
              }
            break;

    }
    return (FALSE);                      /* Didn't process a message    */
}


SENDMSG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\SENDMSG.C

/*
 *  SendMessage
 *  sendmsg.c,
 *
 *  This program demonstrates the use of the function SendMessage.
 *  It sends a message to the specified window immediately without
 *  putting the message in the application queue. SendMessage does not
 *  return until the message has been processed. The window function
 *  is called immediately, as a subroutine.
 *
 */

#include "windows.h"

long FAR PASCAL SampleWindowProc (HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Sendmsg";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = SampleWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND   hWnd;                /* Handle to the parent window     */
    MSG    msg;                 /* Message received from the queue */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Sendmsg",
                        (LPSTR)"Sending Messages",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Sending the window a WM_DESTROY message directly to the
     * window procedure immediately
     */
    MessageBox (hWnd, (LPSTR)"Sending the window a destroy message",
                (LPSTR)"SENDING", MB_OK);
    SendMessage (hWnd, WM_DESTROY, 0,0L);

    return 0;
}

/* The window procedure for this program */
long FAR PASCAL SampleWindowProc (hWnd, message, wParam, lParam)
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message)
      {  case WM_DESTROY:
           MessageBox (hWnd, (LPSTR)"Destroy Message Received",
                       (LPSTR)"RECEIVED", MB_OK);
           PostQuitMessage (0);
           break;

         default:
           return (DefWindowProc (hWnd, message, wParam, lParam));
           break;
      }
    return 0L;
}


SETACTWN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\SETACTWN.C

/*
 *  SetActiveWindow
 *  setactwn.c,
 *
 *  This program demonstrates the use of the function SetActiveWindow.
 *  It makes a tiled window or popup style window the active window.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setactwn";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG          msg;                 /* Window messages                */
    HWND         hWnd;                /* Handle to the parent window    */
    HDC          hDC;                 /* Display context of client area */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setactwn",
                        (LPSTR)"Active Window",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Message Box will make the parent window inactive */
    MessageBox (hWnd, (LPSTR)"The window is not active\n(Look at the caption
                (LPSTR)"Before", MB_OK);

    /* make the window becomes the active window */
    SetActiveWindow (hWnd);
    hDC = GetDC (hWnd);
    TextOut (hDC, 10, 10, (LPSTR)" Now this window is active.", 26);
    ReleaseDC (hWnd, hDC);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
      {
        TranslateMessage ((LPMSG)&msg);
        DispatchMessage  ((LPMSG)&msg);
      }

    return (int)msg.wParam;
}


SETBKCOL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TEXT\SETBKCOL.C

/*
 *  SetBKColor
 *  setbkcol.c,
 *
 *  This program demonstrates the use of the function SetBkColor.  The
 *  change in the backround color is demonstrated using the TextOut function.
 *  The color of the text is also changed so that it can be seen against
 *  against the new backround color.
 *
 */

#include "windows.h"
 ERR 0x80000000 /* Error value returned by SetBkColor
      * if an error occurs */

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pClass;

    pClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    /* registering the parent window class */
    pClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pClass->lpszMenuName   = (LPSTR)NULL;
    pClass->lpszClassName  = (LPSTR)"Window";
    pClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pClass->hInstance      = hInstance;
    pClass->style          = CS_HREDRAW | CS_VREDRAW;
    pClass->lpfnWndProc    = DefWindowProc;

    if (!RegisterClass( (LPWNDCLASS)pClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE) pClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;            /* Handle to the parent window  */
    HDC   hDC;          /* Handle to the display context of client area */
    DWORD rgbcolor;        /* Return value from SetTextColor routine */
    DWORD black = RGB(0x00,0x00,0x00); /* Color of text backround      */
    DWORD white = RGB(0xff,0xff,0xff); /* Color of the output text     */
    long  lpReturn;           /* Return value for SetBkColor  */


    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Window",
      (LPSTR)"SetBkColor",
                        WS_TILEDWINDOW,
                        20,20,400,200,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    hDC = GetDC (hWnd);

       /* The following text will be black so it can be seen
        * on the white backround         */
    TextOut(hDC,
      0,
      0,
      (LPSTR) "The backround color is white before invoking SetBkColor.",
      strlen ("The backround color is white before invoking SetBkColor.")
      );

/**************************************************************************/
/* SetBkColor sets the backround color of future text output to black.
 * The parameters needed are a handle to a display context (hDC) and
 * and an RGB color value - black in this case        */

    lpReturn  = SetBkColor(hDC,black); /* lpReturn contains 80000000H if
          * an error occurs */

/**************************************************************************/

    SetTextColor(hDC,white); /* Set the text color to white to
            * so the text can be seen on the
            * black backround */

    TextOut(hDC,
      0,
      15,
      (LPSTR) "The backround color is black after invoking SetBkcolor.",
      strlen ("The backround color is black after invoking SetBkcolor.")
     );
    ReleaseDC (hWnd, hDC);

    if (lpReturn = ERR)
      MessageBox (hWnd, (LPSTR)"The backround color is changed. No errors",
      (LPSTR)"Done", MB_OK);

    return 0;
}


SETBKMD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TEXT\SETBKMD.C

/*
 *  SetBkMode
 *  setbkmd.c
 *
 *  This program demonstrates the use of the function SetBkMode.
 *  It sets the background mode used with text, hatched brushes, and
 *  line styles. This program only illustrates with text in the client
 *  area.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setbkmd";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( LTGRAY_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;                        /* Handle to the parent window    */
    HDC   hDC;                         /* Display context of client area */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setbkmd",
                        (LPSTR)"Setting Background Mode",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Get a DC before writing to the client area */
    hDC = GetDC (hWnd);

    /* The default background mode is Opaque */
    TextOut(hDC, 20, 10, (LPSTR) "This is Opaque Background Mode", 30);

    /* Change the background mode to Transparent */
    SetBkMode (hDC, TRANSPARENT);
    TextOut(hDC, 20, 30, (LPSTR) "This is Transparent Background mode", 35);

    ReleaseDC (hWnd, hDC);

    MessageBox (hWnd, (LPSTR)"The background mode has changed", (LPSTR)"Done"

    return 0;
}


SETBLT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\SETBLT.C

/*
 *
 *  SetStretchBltMode
 *  setblt
 *
 *  SetStretchBltMode sets the stretching mode for the StretchBlt function.
 *  The stretching mode defines which scan lines and/or columns
 *  StretchBlt eliminates when contracting a bitmap.
 *
 *  This program demonstrates the use of the function SetStretchBltMode.
 *  The stretch mode is set in one statement.  The SetStretchBltMode function
 *  is passed two parameters: a handle to a display context,(ie. hDC) and a
 *  new stretching mode (ie. WHITEONBLACK, BLACKONWHITE, or COLORONCOLOR).
 *  SetStretchBltMode returns the previous stretching mode.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pClass;

    pClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    /* registering the parent window class */
    pClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pClass->lpszMenuName   = (LPSTR)NULL;
    pClass->lpszClassName  = (LPSTR)"Window";
    pClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pClass->hInstance      = hInstance;
    pClass->style          = CS_HREDRAW | CS_VREDRAW;
    pClass->lpfnWndProc    = DefWindowProc;

    if (!RegisterClass( (LPWNDCLASS)pClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE) pClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;             /* Handle to the parent window    */
    short nOldStretchMode;  /* Return value for the SetStretchBltMode Routine
    HDC   hDC;              /* display context of client area */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Window",
                        (LPSTR)"SetStretchBltMode",
                        WS_TILEDWINDOW,
                        20,20,400,200,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow(
    hWnd );
    /************************************************************************
    hDC = GetDC (hWnd);          /* Get a handle to the Display Context */

    /* Set the stretching mode for the StretchBlt function and return the
     * previous stretching mode in a (short) variable. */
    nOldStretchMode = SetStretchBltMode ( hDC, WHITEONBLACK);

    ReleaseDC (hWnd, hDC);        /* Release handle to Display Context */
    /************************************************************************

    /* return codes for SetStretchBltMode routine */
    if (nOldStretchMode == WHITEONBLACK)
      {  MessageBox (hWnd, (LPSTR)"The stretching mode is set. The previous m
         (LPSTR)"Done", MB_OK);
      }
    else if (nOldStretchMode == BLACKONWHITE)
     {  MessageBox (hWnd, (LPSTR)"The stretching mode is changed. The previou
        (LPSTR)"Done", MB_OK);
     }
    else if (nOldStretchMode == COLORONCOLOR)
    {   MessageBox (hWnd, (LPSTR)"The stretching mode is changed. The previou
        (LPSTR)"Done", MB_OK);
    }
    return 0;
}


SETCAPOS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CARET\SETCAPOS.C

/*
 *  SetCaretPos
 *  setcapos.c
 *
 *  This program demonstrates the use of the function SetCaretPos.
 *  It moves the caret to the position specified by the parameters. The
 *  movement applies to the caret whether it is visible or hidden.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setcapos";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND         hWnd;                /* Handle to the parent window    */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setcapos",
                        (LPSTR)"Setting Caret Position",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Create a caret before showing */
    CreateCaret (hWnd, NULL, 8, 12);
    SetCaretPos (50,50);
    ShowCaret (hWnd);
    /* Message Box will make the parent window inactive */
    MessageBox (hWnd, (LPSTR)"This is the current caret position",
                (LPSTR)"Before", MB_OK);

    /* move the caret to a new location */
    SetCaretPos (50,125);
    MessageBox (hWnd, (LPSTR)"Now the caret is moved to a new position",
                (LPSTR)"After", MB_OK);

    return 0;
}


SETCAPT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\SETCAPT.C

/*
 *  SetCapture() & ReleaseCapture()
 *  setcapt.c
 *
 *  This program demonstrates the use of the functions SetCapture()
 *  and ReleaseCapture(). It causes all subsequent mouse input to be
 *  sent to the specified window, regardless of the position of the
 *  mouse cursor. Capture can be released by pressing the right
 *  mouse button.
 *
 */

#include "windows.h"
#include "stdio.h"
#include "string.h"

long FAR PASCAL SampleWindowProc (HWND, unsigned, WORD, LONG);

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setcapt";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = SampleWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND   hWnd;                /* Handle to the parent window    */
    MSG    msg;                 /* Window messages                */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setcapt",
                        (LPSTR)"Setting Mouse Capture",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* All mouse input will be sent to this window */
    MessageBox (hWnd, (LPSTR)"Press OK to capture the mouse", (LPSTR)"Start",
    SetCapture (hWnd);

    /* The window message loop */
    while (GetMessage ((LPMSG)&msg, NULL, 0, 0))
      {
         TranslateMessage ((LPMSG)&msg);
         DispatchMessage  ((LPMSG)&msg);
      }

    return (int)msg.wParam;
}


/* The window procedure */
long FAR PASCAL SampleWindowProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
{
    POINT ptMousePos;      /* The location of the current mouse position */
    HDC   hDC;             /* Handle to the display context              */
    char  szBuffer[40];    /* String buffer used for output              */
    short nBytes;          /* Number of character in the string buffer   */

    switch (message)
      {
        case WM_PAINT:
          hDC = GetDC (hWnd);
          TextOut (hDC, 10, 10, (LPSTR)"Even when the mouse is out of this wi
          TextOut (hDC, 10, 20, (LPSTR)"the mouse input is still sent to this
          TextOut (hDC, 10, 30, (LPSTR)"Press the right mouse button to relea
          ValidateRect (hWnd, (LPRECT)NULL);
          ReleaseDC (hWnd, hDC);
          break;

        /* All the mouse messages will come through this window procedure
         * after the mouse is captured, even if the mouse is outside of
         * this window.
         */
        case WM_MOUSEMOVE:
          hDC = GetDC (hWnd);
          ptMousePos = MAKEPOINT (lParam);
          nBytes = sprintf (szBuffer, "The Mouse is now at: X = %d, Y = %d
                            ptMousePos.x, ptMousePos.y);
          TextOut (hDC, 50, 50, (LPSTR)szBuffer, nBytes);
          ReleaseDC (hWnd, hDC);
          break;

        /* The mouse must be released before you can exit this program */
        case WM_RBUTTONDOWN:
          ReleaseCapture();
          MessageBox (hWnd, (LPSTR)"Mouse is released",
                      (LPSTR)"ReleaseCapture()", MB_OK);
          break;

        default:
          return (DefWindowProc (hWnd, message, wParam, lParam));
          break;
      }
    return 0L;
}


SETCARBT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CARET\SETCARBT.C

/*
 *  SetCaretBlinkTime
 *  setcarbt.c
 *
 *  This program demonstrates the use of the function SetCaretBlinkTime.
 *  It establishes the caret flash rate for the client area.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setcarbt";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND         hWnd;                /* Handle to the parent window    */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setcarbt",
                        (LPSTR)"Setting Caret Blink Time",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* create a caret before showing it */
    CreateCaret (hWnd, NULL, 8, 12);
    SetCaretPos (50,50);
    ShowCaret (hWnd);
    /* Message Box will make the parent window inactive */
    MessageBox (hWnd, (LPSTR)"This is a slower caret blink time",
                (LPSTR)"Before", MB_OK);

    /* make the caret blink faster by decreasing the delay time */
    SetCaretBlinkTime (GetCaretBlinkTime()/2);
    MessageBox (hWnd, (LPSTR)"Now the caret is twice as fast",
                (LPSTR)"After", MB_OK);

    return 0;
}


SETCL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLASS\SETCL.C

/*

Function(s) demonstrated in this program: SetClassLong

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:   This function replaces the long value in the window class
   structure corresponding to the window handle parameter, with the
   respective new value.

Additional Comments:  This program requests 4 extra bytes when it registers
   its class structure.  These 4 extra bytes are used to store a long
   value corresponding to the number of instances of windows in this class.
   This value is updated using GetClassLong and SetClassLong and an upper
   bound of 3 windows of this class is enforced.


*/

#define NOMINMAX
#include <stdlib.h>
#include <windows.h>
#include "SetCl.h"
#include "string.h"
#include "stdio.h"

       char         szAppName             [] = "SetCl"             ;
       HANDLE       hInstMain                                      ;
       HWND         hWndMain                                       ;
       char         szOutputBuffer1       [70]                     ;
       char         szOutputBuffer2       [500]                    ;
       HBITMAP      hBitmapHelp                                    ;


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About",
"     This is a sample application to demonstrate the\n\
use  of  the  SetClassLong  Windows function.",

"Help Message",
"     This program uses GetClassLong and\n\
SetClassLong to keep track of the number of windows\n\
of this class.  In order to do this four bytes must\n\
be reserved in the class structure using the\n\
cbClsExtra field in the class the first time it is\n\
initialized.  To test this program try to run more\n\
than three instances.  When trying to run a fourth\n\
instance, the program will state that the limit has\n\
been reached and automatically terminate.",

"Warning",
"     Only Three windows of this class are allowed\n\
at any one time.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
    HANDLE  hInstance, hPrevInstance;
    LPSTR  lpszCmdLine;
    int   nCmdShow;
    {
    HWND  hWnd;
    MSG   msg;
    WNDCLASS  wndclass;
    LONG    WindowCount;


    if (!hPrevInstance)
  {
  wndclass.style           = CS_HREDRAW | CS_VREDRAW | CS_SAVEBITS;
  wndclass.lpfnWndProc    = WndProc;
  wndclass.cbClsExtra     = 4;
  wndclass.cbWndExtra     = 0;
  wndclass.hInstance      = hInstance;
  wndclass.hIcon           = NULL;
   wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
  wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
  wndclass.lpszMenuName  = szAppName;
  wndclass.lpszClassName  = szAppName;

    if (!RegisterClass (&wndclass) )
        return FALSE;
    }

    hWnd = CreateWindow (szAppName, "SetClassLong Main",
           WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
           NULL, NULL, hInstance, NULL);

    ShowWindow (hWnd, nCmdShow);
    UpdateWindow (hWnd);

    WindowCount = GetClassLong (hWnd, 0);
    sprintf (szOutputBuffer1,
             "     Number of windows with this class currently running = %i."
             WindowCount + 1);
    MessageBox (hWnd, szOutputBuffer1, "SetClassLong", MB_OK);

    if (WindowCount < MAXWINDOWS) {
       WindowCount += 1;
       SetClassLong (hWnd, 0, WindowCount);
    }
    else {
       ProcessMessage (hWnd, 4);
       SendMessage (hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
    }

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
   HWND      hWnd;
   unsigned  iMessage;
   WORD      wParam;
   LONG      lParam;
   {
   HMENU     hMenu;

   switch (iMessage)
       {
       case WM_CREATE:
            hMenu = GetSystemMenu (hWnd, FALSE);

            ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                        MF_APPEND | MF_STRING);
            break;

       case WM_SIZE:
            break;

       case WM_SYSCOMMAND:
            switch (wParam) {
               case IDM_ABOUT:
                    ProcessMessage (hWnd, 0);
                    break;
               default:
                    return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
            }
            break;


       case WM_COMMAND:
            switch (wParam) {
               case IDM_HELP:
                    ProcessMessage (hWnd, 2);
                    break;
           }
            break;

       case WM_DESTROY:
            PostQuitMessage (0);
            break;

      default:
            return DefWindowProc( hWnd, iMessage, wParam, lParam );
       }
  return 0L;
}



SETCLSWD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLASS\SETCLSWD.C

/*
 *  SetClassWord
 *  setclswd.c
 *
 *  This program demonstrates the use of the function SetClassWord.
 *  It replaces the word at the specified index in the WNDCLASS structure
 *  of the window. It is used to change the attributes of the window class
 *  after the window class has been registered.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setclswd";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND    hWnd;              /* Handle to the parent window    */
    HCURSOR hCursor;           /* Handle to the brushes          */
    MSG     msg;               /* Window messages                */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setclswd",
                        (LPSTR)"Changing Window Class Information",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* SetClassWord is used here to change the cursor in the window class
     * structure. It can be used also to change the icon, window style, and
     * other attributes of the window class.
     */
    MessageBox (hWnd, (LPSTR)"This is the old cursor", (LPSTR)"Before", MB_OK
    hCursor = LoadCursor (NULL, IDC_CROSS);
    SetClassWord (hWnd, GCW_HCURSOR, hCursor);
    MessageBox (hWnd, (LPSTR)"Press OK to see the new cursor", (LPSTR)"After"

    /* the message loop */
    while (GetMessage ((LPMSG) &msg, NULL, 0, 0))
      {
         TranslateMessage ((LPMSG) &msg);
         DispatchMessage ((LPMSG) &msg);
      }

    return (int) msg.wParam;
}


SETCOMMS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\SETCOMMS.C

/*
 *  SetCommState
 *  setcomms.c
 *
 *  This program demonstrates the use of the function SetCommState.
 *  It sets a communication device to the state specified by the
 *  device control block (DCB) . This function call is necessary
 *  to set the communication to the desired configurations before
 *  any communication should take place.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setcomms";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;            /* Handle to the parent window               */
    short nCid;            /* Short integer identifying the opened
                            * communication device                      */
    short nFlag;           /* Result of the SetCommState function call  */
    DCB   dcb;             /* The device control block                  */

    WinInit( hInstance );

    hWnd = CreateWindow((LPSTR)"Setcomms",
                        (LPSTR)"Setting Communication Device",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* attempt to open the com1 port */
    nCid = OpenComm ((LPSTR)"COM1", 20, 20);
    if (nCid < 0)
      {
        MessageBox (hWnd, (LPSTR)"Com port not opened!!",(LPSTR)NULL,MB_OK);
        return 0;
      }


    /* Get the current setting of the communication device and then
     * made modifications to each field of the device control block.
     */
    if (GetCommState (nCid, (DCB FAR *) &dcb) >= 0)
      { dcb.BaudRate = 9600;
        dcb.ByteSize = 8;
        dcb.StopBits = ONESTOPBIT;
        dcb.Parity   = NOPARITY;
        dcb.fRtsflow = FALSE;
        dcb.fDtrflow = FALSE;
        dcb.fOutX    = FALSE;
        dcb.fInX     = FALSE;
        dcb.fNull    = FALSE;
        dcb.XonLim   = 1;
        dcb.XoffLim  = 20;
      }

    nFlag = SetCommState ((DCB FAR *) &dcb);

    /* Check the return value of SetCommState to see if the function
     * was successful
     */
    if (nFlag == 0)
      MessageBox (hWnd, (LPSTR)"Communication device set successfully",
                  (LPSTR)"OK", MB_OK);

    if (nFlag < 0)
      MessageBox (hWnd, (LPSTR)"Communication device not set",
                  (LPSTR)NULL, MB_OK);


    /* must close the communication device before leaving the program */
    CloseComm (nCid);

    return 0;
}


SETCSRPS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CURSOR\SETCSRPS.C

/*
 *  SetCursorPos
 *  setcsrps.c
 *
 *  This program demonstrates the use of the function SetCursorPos.
 *  It moves the system cursor to the coordinates specified by the
 *  X and Y parameters.
 *
 */

#include "windows.h"

/*************************** GLOBAL VARIABLES *************************/
static  HWND  hWnd;
static  RECT  rect;
/******************** WINMAIN -- Main Windows Procedure ***************/
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance;
HANDLE    hPrevInstance;
LPSTR    lpszCmdLine;
int    cmdShow;
{
    MSG  msg;
    int  xCoord;
    int  yCoord;

  if (!hPrevInstance) {
    /* ensure that windows know where to find parts of this
     * task on disk by Registering a window class.  Registering
     * a class binds an executable name to an internal name,
     * known to Windows. */
    WNDCLASS  rClass;

    rClass.lpszClassName  = (LPSTR)"SetCursorPos";
    rClass.hInstance  = hInstance;
    rClass.lpfnWndProc  = DefWindowProc;
    rClass.hCursor    = LoadCursor (NULL, IDC_ARROW);
    rClass.hIcon    = LoadIcon (hInstance, (LPSTR)"SetCursorPos");
    rClass.lpszMenuName  = (LPSTR) NULL;
    rClass.hbrBackground  = GetStockObject (WHITE_BRUSH);
    rClass.style    = CS_HREDRAW | CS_VREDRAW;
    rClass.cbClsExtra  = 0;
    rClass.cbWndExtra  = 0;

    RegisterClass ((LPWNDCLASS) &rClass);
    } /* end if this is the 1st task/instance of this program */

  hWnd = CreateWindow (  (LPSTR) "SetCursorPos", /* Window class name */
        (LPSTR) "SetCursorPos", /* Window title */
        WS_OVERLAPPEDWINDOW,
          /* stlye -- WIN 2.x or later */
        CW_USEDEFAULT,  /* x -  WIN 2.x or later */
        CW_USEDEFAULT,  /* y -  WIN 2.x or later */
        CW_USEDEFAULT,  /* cx - WIN 2.x or later */
        CW_USEDEFAULT,  /* cy - WIN 2.x or later */
        (HWND)NULL,  /* No parent */
        (HMENU)NULL,  /* Use the class menu */
        (HANDLE)hInstance, /* .EXE file for Class */
        (LPSTR)NULL  /* No Params */
           );
  ShowWindow (hWnd, cmdShow);     /* Allocate room for window     */
  UpdateWindow (hWnd);            /* Paint the client area        */

  MessageBox (hWnd, (LPSTR) "Moving the Cursor to the Top-Left Corner", (LPST
  GetClientRect (hWnd, (LPRECT)&rect);
  xCoord = rect.left;
  yCoord = rect.top;

  /* SetCursorPos is used here to move the cursor to the top-left
   * corner of the screen.  */
  SetCursorPos (xCoord, yCoord);

  MessageBox (hWnd, (LPSTR) "Demonstration Finished", (LPSTR) " ",MB_OK);
  exit (0);
} /* WINMAIN */


SETCURSO.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CURSOR\SETCURSO.C

/*
 *
 *  SetCursor
 *  setcurso.c
 *
 *  This program demonstrates the use of the function SetCursor.
 *  It sets the cursor shape to the cursor specified by hCursor. HCursor
 *  is a handle to a cursor resource, which must have been loaded
 *  previously using the LoadCursor function. The cursor is set only if the
 *  new shape is different from the existing shape. If hCursor is NULL, the
 *  cursor is removed from the screen. To change the cursor while it is in
 *  a window, the class cursor for the given window's class must be set to
 *  NULL. If the class cursor is not null, Windows restores the old shape
 *  each time the mouse moves.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = (HCURSOR)NULL;
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setcurso";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND    hWnd;              /* Handle to the parent window    */
    HCURSOR hCursor;           /* Handle to the cursor           */
    MSG     msg;               /* Window messages                */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setcurso",
                        (LPSTR)"Changing Cursor",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Setting the new cursor */
    MessageBox (hWnd, (LPSTR)"This is the old cursor", (LPSTR)"Before", MB_OK
    hCursor = LoadCursor (NULL, IDC_CROSS);
    MessageBox (hWnd, (LPSTR)"Press OK to see the new cursor",
                (LPSTR)"After", MB_OK);
    SetCursor (hCursor);

    /* Window message loop */
    while (GetMessage ((LPMSG) &msg, NULL, 0, 0))
      {
         TranslateMessage ((LPMSG) &msg);
         DispatchMessage ((LPMSG) &msg);
      }

    return (int) msg.wParam;
}


SETDBLCK.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MOUSE\SETDBLCK.C

/*
 *  SetDoubleClickTime
 *  setdblck.c
 *
 *  This program demonstrates the use of the function SetDoubleClickTime.
 *  This function changes the range of time Windows will wait to
 *  acknowledge a double-click from the mouse.
 *
 */

#include "windows.h"

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE          hInstance;
HANDLE          hPrevInstance;
LPSTR           lpszCmdLine;
int             cmdShow;
{
                static WORD     wTime;
                static WORD     NewDblCkTime = 1000;
                static char     szbuff[80];

        wTime = GetDoubleClickTime ();
        sprintf ( szbuff, "%s%ld", "Current Double click time in milliseconds
        MessageBox (NULL, (LPSTR)szbuff, (LPSTR)"SetDoubleClickTime", MB_OK);

        SetDoubleClickTime (NewDblCkTime);

        wTime = GetDoubleClickTime ();
        sprintf ( szbuff, "%s%ld", "New Double click time in milliseconds is
        MessageBox (NULL, (LPSTR)szbuff, (LPSTR)"Program Finished", MB_OK);

        exit (0);
}


SETENV.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\ENVIRON\SETENV.C

/*
 *  SetEnvironment
 *  Setenv.c
 *
 *  This program demonstrates the use of the function SetEnvironment.
 *  This function copies the contents of the buffer specified by the second
 *  parameter into the environment associated with the device attached to
 *  the system port specified by the first parameter.
 *
 */

#include <windows.h>
#include "setenv.h"

LPSTR far PASCAL lstrcpy( LPSTR, LPSTR );

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  short nCopied;
  DEVMODE devmode;

  lstrcpy ( (LPSTR) devmode.DeviceName, (LPSTR) "HP LaserJet Series II" );
  devmode.orient = PORTRAIT;
  devmode.cartridge = DEFAULT_CTG + CARTRIDGE;
  devmode.paper = LETTER;

  MessageBox ( NULL, (LPSTR) "Setting environment", (LPSTR) "SetEnvironment",
     MB_OK );

  nCopied = SetEnvironment ( (LPSTR) "LPT1:", (LPSTR) &devmode,
     sizeof (DEVMODE) );

  if ( nCopied == 0 )
     MessageBox (NULL, (LPSTR)"Environment not set!", (LPSTR)"SetEnvironment"
        MB_OK|MB_ICONEXCLAMATION);
  else
     MessageBox (NULL, (LPSTR)"Environment set", (LPSTR)"SetEnvironment",
        MB_OK);

  return 0;
}


SETMSGQU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\SETMSGQU.C

/*
Windows Version 2.03 function demonstration application

Function(s) demonstrated in this program: SetMessageQueue

Compiler version: 5.01

Description:

This program calls SetMessageQueue to destroy the old message queue
and create a new message queue which can hold up to ten messages. The
default message queue can hold only eight messages.  The results of
the call to SetMessageQueue are displayed on the screen.  If the call
works then a new message queue is created and the old message queue
is destroyed, along with any messages it might contain.  If the call
fails then the old message queue is still destroyed but a new message
queue has not been created.  In the latter case the application must
continue calling SetMessageQueue with a smaller queue size until the
function returns a nonzero value.


****************************************************************************/

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

long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "SetMessageQueue" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWnd = CreateWindow (szAppName,            /* window class name       */
                    "SetMessageQueue",          /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWnd, nCmdShow) ;

     UpdateWindow (hWnd) ;

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 PAINTSTRUCT     ps;
 HDC             hDC;
 TEXTMETRIC      tm;
 static short    xChar,
                 yChar;
 short           iRow; /* An index to keep track of the current row *
                        * for text output
                       */

 switch(iMessage)
 {
  case WM_CREATE:
  {
   hDC = GetDC (hWnd);
   GetTextMetrics (hDC, &tm);
   xChar = tm.tmAveCharWidth;
   yChar = tm.tmHeight + tm.tmExternalLeading;
   ReleaseDC (hWnd, hDC);
   break;
  }
  case WM_PAINT:
  {
   hDC = BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);

   iRow = 1;

LOOP:
   if (SetMessageQueue(10) == 0)
      {
       TextOut (hDC,
               xChar,
               yChar * iRow,
               (LPSTR)"SetMessageQueue has failed.  The application has no me
               strlen("SetMessageQueue has failed.  The application has no me
              );

      iRow++;
      goto LOOP;
      }
   else
      {
       TextOut (hDC,
               xChar,
               yChar * iRow,
               (LPSTR)"SetMessageQueue works.",
               strlen("SetMessageQueue works.")
              );

       TextOut (hDC,
               xChar,
               yChar * ++iRow,
               (LPSTR)"The message queue for this application will now hold t
               strlen("The message queue for this application will now hold t
              );

       TextOut (hDC,
               xChar,
               yChar * ++iRow,
               (LPSTR)"Before the SetMessageQueue call it only held eight mes
               strlen("Before the SetMessageQueue call it only held eight mes
              );

      }
   EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
   break;
  }
  case WM_DESTROY:
  {
   PostQuitMessage(0);
   break;
  }
  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}


SETPAR.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SPAWN\SETPAR.C

/*

Function(s) demonstrated in this program: SetParent

Description:  This function changes the parent of the respective child
    window.

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "SetPar.h"


HWND     hWndParent1, hWndParent2, hWndChild1, hWndChild2;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use  of  the  SetParent Windows function.",

"Help Message",
"     This program uses the SetParent Windows\n\
function to change the parent of the child windows.\n\
Use the menu to choose the parent."

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "SetPar" ;
     static char szChildClass [] = "SetParChild" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;
     short       xScreen, yScreen ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;

          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = ChildWndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = NULL ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_CROSS) ;
          wndclass.hbrBackground = GetStockObject (LTGRAY_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szChildClass ;

          if (!RegisterClass (&wndclass))
               return FALSE ;

          }

     xScreen = GetSystemMetrics (SM_CXSCREEN) ;
     yScreen = GetSystemMetrics (SM_CYSCREEN) ;

     hWndParent1 = CreateWindow (szAppName,     /* window class name       */
                    "Parent 1",                 /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    xScreen / 9,                /* initial x position      */
                    yScreen / 7,                /* initial y position      */
                    xScreen * 3 / 9,            /* initial x size          */
                    yScreen * 6 / 9,            /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent1, nCmdShow) ;
     UpdateWindow (hWndParent1) ;

     hWndParent2 = CreateWindow (szAppName,     /* window class name       */
                    "Parent 2",                 /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    xScreen * 5 / 9,            /* initial x position      */
                    yScreen / 7,                /* initial y position      */
                    xScreen * 3 / 9,            /* initial x size          */
                    yScreen * 6 / 9,            /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndParent2, nCmdShow) ;
     UpdateWindow (hWndParent2) ;

     hInstMain = hInstance;

     hWndChild1 = CreateWindow (szChildClass, "Child 1", WS_CHILD |
                    WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX
                    WS_CLIPSIBLINGS,
                    0, 0, xScreen / 8, yScreen / 6,
                    hWndParent1, 1, hInstance, NULL) ;

     ShowWindow (hWndChild1, SW_SHOWNORMAL) ;
     UpdateWindow (hWndChild1) ;

     hWndChild2 = CreateWindow (szChildClass, "Child 2", WS_CHILD |
                    WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MAXIMIZEBOX
                    WS_CLIPSIBLINGS,
                    0, yScreen / 5, xScreen / 8, yScreen / 6,
                    hWndParent1, 1, hInstance, NULL) ;

     ShowWindow (hWndChild2, SW_SHOWNORMAL) ;
     UpdateWindow (hWndChild2) ;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 PAINTSTRUCT ps;
 static int  xClient, yClient;
 static int  xDevisor, yDevisor, randNum, Index;
 char        szOutputBuffer [40];

 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_SETPARENT1:
               SetParent (hWndChild1, hWndParent1);
               SetParent (hWndChild2, hWndParent1);
               break;

          case IDM_SETPARENT2:
               SetParent (hWndChild1, hWndParent2);
               SetParent (hWndChild2, hWndParent2);
               break;

          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}

/****************************************************************************

long FAR PASCAL ChildWndProc (hWnd, iMessage, wParam, lParam)
     HWND     hWnd ;
     unsigned iMessage ;
     WORD     wParam ;
     LONG     lParam ;
     {
     return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
     }



SETPIXEL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\SETPIXEL.C

/*
 *  SetPixel
 *  setpixel.c
 *
 *  This program demonstrates the use of the function SetPixel.
 *  It sets the pixel at the point specified by the X and Y coordinates
 *  to the closest approxmiation to the color specified by the rgbcolor.
 *  The point must be in the clipping region. If the point is not in the
 *  clipping region, the function is ignored.
 *
 */

#include "windows.h"

/* Registering the parent window class */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setpixel";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS) &wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;                   /* Handles to the windows        */
    HDC   hDC;                    /* Display context of the window */
    short nPos;                   /* X-coordinate of the pixel     */
    LONG  nResult;                /* return value of SetPixel      */

    WinInit (hInstance);

    /* creating the window */
    hWnd = CreateWindow((LPSTR)"Setpixel",
                        (LPSTR)"Setting Pixel",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Getting the display context and draw a line by setting a series of
     * pixels in the client area. The rgbcolor is set by using RGB macro.
     */
    hDC = GetDC (hWnd);

    for (nPos = 50; nPos < 550; nPos++)
      {
        nResult = SetPixel (hDC, nPos, 50, RGB (0,0,0));
        if (nResult == -1)
          MessageBox (hWnd, (LPSTR)"SetPixel Function Failed",
                      (LPSTR)"ERROR!", MB_OK);
      }

    ReleaseDC (hWnd, hDC);

    MessageBox (hWnd, (LPSTR)"Using SetPixel to draw a line",
                (LPSTR)"Done", MB_OK);

    return 0;
}


SETPRI.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\SETPRI.C

/*
 *  SetPriority
 *  setpri.c
 *
 *  This program modifies its priority using the SetPriority function.  It
 *  has two menu items.  One to set the priority high and the other to set
 *  it low.
 *
 */

 "windows.h"      /* required for all Windows applications */
 "setpri.h"       /* specific to this program              */

HANDLE hInst;             /* current instance                      */

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;         /* current instance             */
HANDLE hPrevInstance;     /* previous instance            */
LPSTR lpCmdLine;          /* command line                 */
int nCmdShow;             /* show-window type (open/icon) */
{
    HWND hWnd;            /* window handle       */
    MSG msg;              /* message             */
    HANDLE hMenu;         /* Handle to the menu  */

    if (!hPrevInstance)              /* Has application been initialized? */
        if (!SetPriInit(hInstance))
            return (NULL);           /* Exits if unable to initialize     */

    hInst = hInstance;               /* Saves the current instance        */

    hMenu = LoadMenu( hInst, (LPSTR)"SetPriMenu" );
                                     /*  Load the menu    */

    hWnd = CreateWindow("SetPri",   /* window class      */
        "SetPri Sample Application",  /* window name       */
        WS_OVERLAPPEDWINDOW,         /* window style      */
        CW_USEDEFAULT,               /* x position        */
        CW_USEDEFAULT,               /* y position        */
        CW_USEDEFAULT,               /* width             */
        CW_USEDEFAULT,               /* height            */
        NULL,                        /* parent handle     */
        hMenu,                       /* menu or child ID  */
        hInstance,                   /* instance          */
        NULL);                       /* additional info   */

    if (!hWnd)                       /* Was the window created? */
        return (NULL);

    ShowWindow(hWnd, nCmdShow);      /* Shows the window        */
    UpdateWindow(hWnd);              /* Sends WM_PAINT message  */

    while (GetMessage(&msg,     /* message structure                      */
            NULL,               /* handle of window receiving the message */
            NULL,               /* lowest message to examine              */
            NULL))              /* highest message to examine             */
        {
        TranslateMessage(&msg);  /* Translates virtual key codes           */
        DispatchMessage(&msg);   /* Dispatches message to window           */
    }
    return (msg.wParam);         /* Returns the value from PostSetPriMessage
}

BOOL SetPriInit(hInstance)
HANDLE hInstance;                /* current instance           */
{
    HANDLE hMemory;              /* handle to allocated memory */
    PWNDCLASS pWndClass;         /* structure pointer          */
    BOOL bSuccess;               /* RegisterClass() result     */

    hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
    pWndClass = (PWNDCLASS) LocalLock(hMemory);

    pWndClass->style = NULL;
    pWndClass->lpfnWndProc = SetPriWndProc;
    pWndClass->hInstance = hInstance;
    pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION);
    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
    pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
    pWndClass->lpszMenuName = (LPSTR) "SetPriMenu";
    pWndClass->lpszClassName = (LPSTR) "SetPri";

    bSuccess = RegisterClass(pWndClass);

    LocalUnlock(hMemory);     /* Unlocks the memory    */
    LocalFree(hMemory);       /* Returns it to Windows */

    return (bSuccess);        /* Returns result of registering the window */
}

long FAR PASCAL SetPriWndProc(hWnd, message, wParam, lParam)
HWND hWnd;                    /* window handle                   */
unsigned message;             /* type of message                 */
WORD wParam;                  /* additional information          */
LONG lParam;                  /* additional information          */
{
    FARPROC lpProcAbout;      /* pointer to the "About" function */
    HMENU hMenu;              /* handle to the System menu       */

    switch (message) {
        case WM_SYSCOMMAND:   /* message: command from system menu */
            if (wParam == ID_ABOUT) {
                lpProcAbout = MakeProcInstance(About, hInst);

                DialogBox(hInst,         /* current instance         */
                    "AboutBox",          /* resource to use          */
                    hWnd,                /* parent handle            */
                    lpProcAbout);        /* About() instance address */

                FreeProcInstance(lpProcAbout);
                break;
            }

            else                         /* Lets Windows process it       */
                return (DefWindowProc(hWnd, message, wParam, lParam));

        case WM_CREATE:                  /* message: window being created */

            /* Get the handle of the System menu */

            hMenu = GetSystemMenu(hWnd, FALSE);

            /* Add a separator to the menu */

            ChangeMenu(hMenu,                    /* menu handle         */
                NULL,                            /* menu item to change */
                NULL,                            /* new menu item       */
                NULL,                            /* menu identifier     */
                MF_APPEND | MF_SEPARATOR);       /* type of change      */

            /* Add new menu item to the System menu */

            ChangeMenu(hMenu,                    /* menu handle         */
                NULL,                            /* menu item to change */
                "A&bout SetPri...",             /* new menu item       */
                ID_ABOUT,                        /* menu identifier     */
                MF_APPEND | MF_STRING);          /* type of change      */
            break;

        case WM_COMMAND:
            if ( wParam == IDM_HIGH )
              SetPriority( GetCurrentTask(),  /*  Priority of current task  *
                           -15 );  /*  -15 is the highest priority  */
            if ( wParam == IDM_LOW )
              SetPriority( GetCurrentTask(),  /*  Again, the current task  */
                           15 );  /*  15 is the lowest priority  */

/*  The default value for the priority is zero  */

            break;

        case WM_DESTROY:             /* message: window being destroyed */
            PostQuitMessage(0);
            break;

        default:                     /* Passes it on if unproccessed    */
            return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (NULL);
}

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:              /* message: initialize dialog box */
            return (TRUE);

        case WM_COMMAND:                 /* message: received a command */
            if (wParam == IDOK) {        /* "OK" box selected?          */
                EndDialog(hDlg, NULL);   /* Exits the dialog box        */
                return (TRUE);
            }
            break;
    }
    return (FALSE);                      /* Didn't process a message    */
}


SETPROP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\SETPROP.C

/*
 *  SetProp
 *  setprop.c
 *
 *  This program demonstrates the use of the function SetProp.
 *  It copies the character string and a data handle to the property
 *  list of the window. The string serves as a label for the data handle.
 *  The data handle can be retrieved from the property list at any time
 *  by using the GetProp function and specifying the string.
 *
 */

#include "windows.h"
#include "stdio.h"

/* This is the structure that is used to put into the property list.
 * It is just a sample structure.
 */
struct Data
  {  short nRow, nSeat;
     char  szName[20];
  } strSeatings = { 2, 4, "John Smith" };



/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setprop";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND         hWnd;          /* Handle to the parent window    */
    BOOL         bSet;          /* Boolean flag                   */
    struct Data *hData;         /* Handle to the data in the
                                 * property list
                                 */
    char         szbuffer[50];  /* String buffer for output       */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setprop",
                        (LPSTR)"Setting the Property List",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );


    /* Putting the structure into the property list of the window
     * If it is successful, retrieve it to check if the correct structure
     * is put into the property list
     */
    bSet = SetProp (hWnd, (LPSTR)"Smith", (HANDLE) &strSeatings);
    if (bSet)
      {
        MessageBox (hWnd, (LPSTR)"Property Set", (LPSTR)"OK", MB_OK);
        hData = GetProp (hWnd, (LPSTR)"Smith");
        sprintf (szbuffer, "%s at row %d, seat# %d",
                 hData->szName, hData->nRow, hData->nSeat);
        MessageBox (hWnd, (LPSTR)szbuffer, (LPSTR)"Retrieved", MB_OK);
      }
    else
      MessageBox (hWnd, (LPSTR)"Property Not Set", (LPSTR)"FAIL", MB_OK);

    return 0;
}


SETRECT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\SETRECT.C

/*
 *  SetRect
 *  setrect.c
 *
 *  This program demonstrates the use of the function SetRect.
 *  The SetRect functions creates a new RECT structure with the values
 *  given by the last four parameters.
 *
 */

#include "windows.h"

/*************************** GLOBAL VARIABLES *************************/
static  HWND    hWnd;

/************************** FORWARD REFERENCES ************************/
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL SetRectTestPaint ();
RECT            NewRect ();

/******************** WINMAIN -- Main Windows Procedure ***************/
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE          hInstance;
HANDLE          hPrevInstance;
LPSTR           lpszCmdLine;
int             cmdShow;
{
                MSG  msg;

        if (!hPrevInstance) {
                /* ensure that windows know where to find parts of this
                 * task on disk by Registering a window class.  Registering
                 * a class binds an executable name to an internal name,
                 * known to Windows. */
                WNDCLASS        rClass;

                rClass.lpszClassName    = (LPSTR)"setrect";
                rClass.hInstance        = hInstance;
                rClass.lpfnWndProc      = WindowProc;
                rClass.hCursor          = LoadCursor (NULL, IDC_ARROW);
                rClass.hIcon            = LoadIcon (hInstance, (LPSTR)"setrec
                rClass.lpszMenuName     = (LPSTR) NULL;
    rClass.hbrBackground    = GetStockObject (WHITE_BRUSH);
                rClass.style            = CS_HREDRAW | CS_VREDRAW;
                rClass.cbClsExtra       = 0;
                rClass.cbWndExtra       = 0;

                RegisterClass ((LPWNDCLASS) &rClass);
                } /* end if this is the 1st task/instance of this program */

        hWnd = CreateWindow (   (LPSTR) "setrect", /* Window class name */
                                (LPSTR) "setrect", /* Window title */
                                WS_OVERLAPPEDWINDOW,
                                        /* stlye -- WIN 2.x or later */
                                CW_USEDEFAULT,  /* x -  WIN 2.x or later */
                                CW_USEDEFAULT,  /* y -  WIN 2.x or later */
                                CW_USEDEFAULT,  /* cx - WIN 2.x or later */
                                CW_USEDEFAULT,  /* cy - WIN 2.x or later */
                                (HWND)NULL,     /* No parent */
                                (HMENU)NULL,    /* Use the class menu */
                                (HANDLE)hInstance, /* .EXE file for Class */
                                (LPSTR)NULL     /* No Params */
                             );

  MessageBox (NULL,
    (LPSTR)"This is a demostration of the SetRect Function",
    (LPSTR)"SetRect",
    MB_OK);

        ShowWindow (hWnd, cmdShow);  /* Allocate room for the window  */
        UpdateWindow (hWnd);    /* Paint the client area */

        while (GetMessage ((LPMSG)&msg, NULL, 0, 0)) {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
                } /* end while more messages */
        exit (msg.wParam);
} /* WINMAIN */
/***************************** WINDOWPROC *****************************/
/*      Every message dispatched to any window of type "setrect" will
 *      result in a call to this procedure.
 */
long FAR PASCAL WindowProc (hWnd, identifier, wParam, lParam)
HWND            hWnd;           /* Intended window */
unsigned        identifier;     /* Message Number */
WORD            wParam;         /* 16 bit param */
LONG            lParam;         /* 32 bit param */
{

        switch (identifier) {
    case WM_PAINT:
      SetRectTestPaint ();
      break;
                default:
                        return (DefWindowProc
                                (hWnd, identifier, wParam, lParam));
                        break;
                } /* end switch */
        return (0L);
} /* windowproc */
/************************** PAINTING PROCEDURE *****************************/
/* This function will paint the new rectangle in the client area with a
 * newly created brush. */
BOOL FAR PASCAL SetRectTestPaint ()
{
    PAINTSTRUCT     ps;
    RECT            rect;
    HDC             hDC;
    HBRUSH          hBrush;

  hDC = BeginPaint (hWnd, (LPPAINTSTRUCT) &ps);

  /* Create a new brush to paint the new rectangle with */
  hBrush = CreateSolidBrush (RGB (0, 0, 0)); /* BLACK = 0,0,0 */

  rect = NewRect ();      /* get the new rectangle */
  FillRect (hDC, (LPRECT)&rect, hBrush);  /* color rectangle  */

  ValidateRect (hWnd, (LPRECT)NULL);  /* confirm paint  */
  EndPaint (hWnd, (LPPAINTSTRUCT) &ps);
  return TRUE;
}
/********************** SET NEW RECTANGLE - SETRECT *********************/
/* Gets the current coordinates of the client area and returns a
 * smaller rectangle of that will be centered in the client area.
 */
RECT    NewRect ()
{
    RECT  rect;
    int     left;
    int     top;
    int     right;
    int     bottom;

  GetClientRect (hWnd, (LPRECT)&rect); /* Get Client Area Coordinates */

  left = rect.left + 15;         /* values for smaller rect. */
  top = rect.top + 15;
  right = rect.right - 15;
  bottom = rect.bottom - 15;

  /* Create new rectangle with the above coordinates
   * into the rect struct */
  SetRect ((LPRECT)&rect, left, top, right, bottom);

  return (rect);
}


SETROP2.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\SETROP2.C

/*
 *  SetROP2
 *  setrop2.c
 *
 *  This program demonstrates the use of the function SetROP2.
 *  It sets the current drawing mode of the display context. GDI uses the
 *  drawing mode to combine pens and interior of filled objects with color
 *  already on the display surface. The mode specifies how the color of
 *  the pen or interior and the color already on the display surface are
 *  combined to yield a new color. In this program, a rectangle is drawn on
 *  the client area with different drawing mode. It will show how the pen
 *  (which is used to draw the border) and the brush (which is used to fill
 *  the rectangle) combine with the color already on the screen.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setrop2";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( LTGRAY_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;                 /* Handle to the parent window    */
    HDC   hDC;                  /* Display context of client area */
    MSG   msg;                  /* Window messages                */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setrop2",
                        (LPSTR)"Setting Drawing Mode",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Get a DC before writing to the client area */
    hDC = GetDC (hWnd);

    /* Using the default drawing mode of R2_COPYPEN from the display
     * context, where the pixel is the color of the pen and brush,
     * regardless of what is on the screen
     */
    Rectangle (hDC, 50, 50, 150, 100);
    MessageBox (hWnd, (LPSTR)"The ROP2 is R2_COPYPEN", (LPSTR)"R2_COPYPEN", M

    /* The pixel is always white with R2_WHITE */
    SetROP2 (hDC, R2_WHITE);
    Rectangle (hDC, 60, 60, 160, 110);
    MessageBox (hWnd, (LPSTR)"The ROP2 is R2_WHITE", (LPSTR)"R2_WHITE", MB_OK

    /* The pixel is a combination of colors in the pen/brush and display,
     * but not in both witj R2_XORPEN
     */
    SetROP2 (hDC, R2_XORPEN);
    Rectangle (hDC, 70, 70, 170, 120);
    MessageBox (hWnd, (LPSTR)"The ROP2 is R2_XORPEN", (LPSTR)"R2_XORPEN", MB_

    /* The pixel is the inverse of the display color with R2_NOT */
    SetROP2 (hDC, R2_NOT);
    Rectangle (hDC, 80, 80, 180, 130);
    MessageBox (hWnd, (LPSTR)"The ROP2 is R2_NOT", (LPSTR)"R2_NOT", MB_OK);

    /* return the display context when everything is done */
    ReleaseDC (hWnd, hDC);

    /* Window message loop */
    while (GetMessage ((LPMSG)&msg, NULL, 0, 0))
      {
         TranslateMessage ((LPMSG)&msg);
         DispatchMessage  ((LPMSG)&msg);
      }

    return (int)msg.wParam;
}


SETSCPOS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SCROLL\SETSCPOS.C

/*
 *  SetScrollPos
 *  setscpos.c
 *
 *  This program demonstrates the use of the function SetScrollPos.
 *  It sets the current position of a scroll bar elevator to a specified
 *  position and redraws the scroll bar to reflect the new position, if
 *  requested.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setscpos";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND         hWnd;                /* Handle to the parent window    */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setscpos",
                        (LPSTR)"Setting Scroll Position",
                        WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Setting up the vertical and horizontal scroll bars range */
    SetScrollRange (hWnd, SB_VERT, 1, 10, (BOOL)TRUE);
    SetScrollRange (hWnd, SB_HORZ, 1, 10, (BOOL)TRUE);

    /* initial position on a vertical scroll bar */
    SetScrollPos   (hWnd, SB_VERT, 2, (BOOL)TRUE);
    MessageBox (hWnd, (LPSTR)"The scroll bar elevator is near the top",
                (LPSTR)"Vertical", MB_OK);

    /* moved to a new location */
    SetScrollPos (hWnd, SB_VERT, 9, (BOOL)TRUE);
    MessageBox (hWnd, (LPSTR)"Now the scroll bar elevator is set to another l
                (LPSTR)"Vertical", MB_OK);

    /* initial position on a vertical scroll bar */
    SetScrollPos   (hWnd, SB_HORZ, 2, (BOOL)TRUE);
    MessageBox (hWnd, (LPSTR)"The scroll bar elevator is near the left",
                (LPSTR)"Horizontal", MB_OK);

    /* moved to a new location */
    SetScrollPos (hWnd, SB_HORZ, 9, (BOOL)TRUE);
    MessageBox (hWnd, (LPSTR)"Now the scroll bar elevator is set to another l
                (LPSTR)"Horizontal", MB_OK);

    return 0;
}


SETSCRNG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SCROLL\SETSCRNG.C

/*
 *  SetScrollRange
 *  setscpos.c
 *
 *  This program demonstrates the use of the function SetScrollRange.
 *  It sets the minimum and maximum position values for the scroll bar
 *  of a window. If the minimum position equals the maximum position,
 *  then the scroll bar is removed.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Setscrng";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND         hWnd;                /* Handle to the parent window    */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Setscrng",
                        (LPSTR)"Setting Scroll Range",
                        WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Setting up the vertical and horizontal scroll bars range */
    SetScrollRange (hWnd, SB_VERT, 1, 10, (BOOL)TRUE);
    MessageBox (hWnd, (LPSTR)"The new range is set for the vertical scroll ba
                (LPSTR)"Vertical", MB_OK);

    SetScrollRange (hWnd, SB_HORZ, 1, 20, (BOOL)TRUE);
    MessageBox (hWnd, (LPSTR)"The new range is set for the horizontal scroll
                (LPSTR)"Horizontal", MB_OK);

    /* removing the vertical scroll bar */
    SetScrollRange (hWnd, SB_VERT, 0, 0, (BOOL)TRUE);
    MessageBox (hWnd, (LPSTR)"The vertical scroll bar is now removed",
                (LPSTR)"Vertical", MB_OK);

    return 0;
}


SETSNDNS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SOUND\SETSNDNS.C

/*
 *  SetSoundNoise
 *  setsndns
 *
 *  SetSoundNoise(nSource, nDuration) sets the source and duration of a
 *  noise in the noise hardware of the play device.  nSource is a short
 *  integer specifying the noise source.  nDuration is a short integer value
 *  specifying the duration of the noise in clock tics.
 *
 *  This program demonstrates the use of the function SetSoundNoise.
 *  As shown below, OpenSound must be invoked before SetSoundNoise can
 *  be called.  SetSoundNoise(nSource, nDuration) returns zero if the
 *  function is successful.  If the source is invalid, it returns S_SERDSR.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pClass;

    pClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    /* registering the parent window class */
    pClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pClass->lpszMenuName   = (LPSTR)NULL;
    pClass->lpszClassName  = (LPSTR)"Window";
    pClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pClass->hInstance      = hInstance;
    pClass->style          = CS_HREDRAW | CS_VREDRAW;
    pClass->lpfnWndProc    = DefWindowProc;

    if (!RegisterClass( (LPWNDCLASS)pClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE) pClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;      /* Handle to the parent window */
    short nResult;   /* Contains return value for SetSoundNoise function */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Window",
      (LPSTR)"SetSoundNoise",
                        WS_TILEDWINDOW,
                        20,20,400,200,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the application is activated
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    OpenSound ();   /* Must open access to the play device before
         * SetSoundNoise can be invoked */

    /*********************************************************************/
    /* S_PERIOD512 is the noise source (high pitch hiss).  3000 is the
     * duration of the noise in clock tics. */

    nResult = SetSoundNoise(S_PERIOD512,3000); /* nResult = 0 if successful *

    /*********************************************************************/

    CloseSound();   /* Close access to play device */

    /* return code for SetSoundNoise routine */

    if (nResult==0)
  MessageBox (hWnd, (LPSTR)"SetSoundNoise worked",
       (LPSTR)"Done", MB_OK);

    else if (nResult == S_SERDSR)
  MessageBox (hWnd, (LPSTR)"The noise source parameter is invalid",
       (LPSTR)NULL, MB_OK);

    return 0;
}


SETVCQUE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SOUND\SETVCQUE.C

/*
 *  SetVoiceQueueSize
 *  setvcque
 *
 *  SetVoiceQueueSize(nVoice,nBytes) allocates nBytes bytes for the voice
 *  queue specified by nVoice.  If the queue size is not set, the default
 *  is 192 bytes, room for about 32 notes.  All voice queues are locked in
 *  memory.  The queues cannot be set while music is playing.
 *
 *  This program demonstrates the use of the function SetVoiceQueueSize.
 *  As shown below, OpenSound must be invoked before SetVoiceQueueSize can
 *  be called.  SetVoiceQueueSize returns one of three possible values -
 *  one success value and two error values.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pClass;

    pClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    /* registering the parent window class */
    pClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pClass->lpszMenuName   = (LPSTR)NULL;
    pClass->lpszClassName  = (LPSTR)"Window";
    pClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pClass->hInstance      = hInstance;
    pClass->style          = CS_HREDRAW | CS_VREDRAW;
    pClass->lpfnWndProc    = DefWindowProc;

    if (!RegisterClass( (LPWNDCLASS)pClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE) pClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;             /* Handle to the parent window            */
    short nResult;          /* Returned by SetVoiceQueueSize function */
    short nVoice;           /* Specifies the voice queue              */
    short nVoices;          /* Specifies the number of voices available */
    short nBytes;           /* Specifies the number of bytes to be
                             * allocated to the voice queue           */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Window",
                        (LPSTR)"SetVoiceQueueSize",
                        WS_TILEDWINDOW,
                        20,20,400,200,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the application is activated
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );
    /*********************************************************************/

    nVoices = OpenSound ();   /* Must open access to the play device before
             * SetVoiceQueueSize can be invoked */

    /* Allocate nBytes for the voice queue specified by nVoice */
    nVoice = 1;
    nBytes = 300;   /* Default is 192 bytes, room for about 32 notes */
    nResult = SetVoiceQueueSize (nVoice, nBytes);
     /* The return value is zero if the function is successful.  On error
      * it is one of the following:
      *      S_SEROFM  Out of memory
      *      S_SERMACT  Music active   */

    CloseSound(); /* CloseSound must be invoked to allow other applications
       * access to the play device */

    /*********************************************************************/
    /* return code for SetVoiceQueueSize routine */
    if (nResult == 0)                           /* Function is successful */
      {  MessageBox (hWnd, (LPSTR)"300 bytes are allocated to voice queue num
                    (LPSTR)"Done", MB_OK);
      }
    else if (nResult == S_SEROFM)     /* If nResult == S_SERTOFM then out of
      {  MessageBox (hWnd, (LPSTR)"Out of memory",
                    (LPSTR)NULL, MB_OK);
      }
    else
      {  MessageBox (hWnd, (LPSTR)"Music active", /* If nResult = S_SERMACT t
                    (LPSTR)NULL, MB_OK);
      }
    return 0;
}


SETVIEW.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\SETVIEW.C

/*
 *  SetViewportExt
 *  setview.c
 *
 *  This function demonstrates the use of the SetViewportExt function.  It wi
 *  create a window, and procede to draw a triangle in the window in
 *  the MM_ANISOTROPIC mapping mode.
 *
 */

#include <windows.h>

/* Forward Declarations  */

BOOL FAR PASCAL InitSetViewportExt ( HANDLE , HANDLE , int );
long FAR PASCAL SetViewportExtWindowProc ( HANDLE , unsigned , WORD , LONG );

/*
 *  MAIN PROCEDURE
 */

int PASCAL WinMain  (hInstance , hPrevInstance , lpszCmdLine , cmdShow )

HANDLE hInstance , hPrevInstance;
LPSTR  lpszCmdLine;
int cmdShow;
  {
  MSG  msg;          /*  Temp buffer to hold message  */

  InitSetViewportExt (hInstance, hPrevInstance, cmdShow );  /*  Init Routine

  while ( GetMessage((LPMSG)&msg, NULL, 0 , 0 ))
    {
    TranslateMessage((LPMSG)&msg);
    DispatchMessage((LPMSG)&msg);     /*  Give Your windowproc the  */
    }              /*  message        */

  exit(msg.wParam);
  }

BOOL FAR PASCAL InitSetViewportExt (hInstance , hPrevInstance , cmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
int cmdShow;

  {
  WNDCLASS  wcSetViewportExtClass;
  HWND  hWnd;

  wcSetViewportExtClass.lpszClassName = (LPSTR) "SetViewportExt";
  wcSetViewportExtClass.hInstance     = hInstance;
  wcSetViewportExtClass.lpfnWndProc   = SetViewportExtWindowProc;
  wcSetViewportExtClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
  wcSetViewportExtClass.hIcon        = NULL;
  wcSetViewportExtClass.lpszMenuName  = (LPSTR) NULL;
  wcSetViewportExtClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcSetViewportExtClass.style        = CS_HREDRAW | CS_VREDRAW;
  wcSetViewportExtClass.cbClsExtra    = 0;
  wcSetViewportExtClass.cbWndExtra    = 0;

  RegisterClass ((LPWNDCLASS) &wcSetViewportExtClass);

  hWnd = CreateWindow((LPSTR) "SetViewportExt",   /*  Window class name
          (LPSTR) "SetViewportExt",   /*  Window title        */
          WS_OVERLAPPEDWINDOW,  /*  Type of window    */
          CW_USEDEFAULT,      /*  x      */
          CW_USEDEFAULT,      /*  y      */
          CW_USEDEFAULT,      /*  cx      */
          CW_USEDEFAULT,      /*  cy      */
          (HWND)NULL,      /*  No parent for this wind */
          (HMENU)NULL,      /*  Use the Class menu  */
          (HANDLE)hInstance,    /*  Who created this window */
          (LPSTR)NULL      /*  No params. to pass on.  */
         );

  ShowWindow (hWnd , cmdShow);   /*  Display this window on the screen  */
  UpdateWindow (hWnd);     /*  Cause a paint message    */

  return TRUE;
  }

/*
 *  THE WINDOW PROCEDURE - Process messages
 */

long FAR PASCAL SetViewportExtWindowProc (hWnd , message , wParam , lParam)

HWND      hWnd;        /*  Handle of the window  */
unsigned    message;        /*  Message type    */
WORD      wParam;        /*  Message 16-bit param  */
LONG      lParam;        /*  Message 32-bit param  */
  {
  switch (message)        /*  Check the message type  */
    {
    case WM_PAINT:        /*  Process the Paint  */
  PaintSetViewportExtWindow (hWnd); /*  message          */
  break;

    case WM_DESTROY:        /*  If close requested  */
  PostQuitMessage(0);      /*    send yourself a quit  */
  break;          /*    message    */

    default:
  return( DefWindowProc( hWnd , message , wParam , lParam ) );
  break;
    }
  return( 0L );
  }

/*
 *  THE PAINT PROCEDURE
 */

PaintSetViewportExtWindow (hWnd)

HWND  hWnd;             /*  Handle of the window  */
  {
  PAINTSTRUCT  ps;
  HDC    hDC;
  POINT   lpTriangle[4];
  HANDLE  hOldBrush , hBrush;        /*  For loading new brushes  */
  RECT    rRect;            /*  Will hold the client     */
                /*  Rectangle       */

  BeginPaint (hWnd , (LPPAINTSTRUCT) &ps);    /*  Prepare the client area  */
  hDC = ps.hdc;             /*  Get the Display Context  */

  hBrush = GetStockObject ( GRAY_BRUSH );     /*  Get a gray brush     */
  hOldBrush = SelectObject ( hDC , hBrush );  /*  Select the new brush     */

  lpTriangle[0].x = 150;    /*  The values of the points  */
  lpTriangle[0].y = 100;
  lpTriangle[1].x = 100;
  lpTriangle[1].y = 200;
  lpTriangle[2].x = 200;
  lpTriangle[2].y = 200;

  SetMapMode ( hDC , MM_ANISOTROPIC );   /*  Set the mapping mode        */

  SetWindowExt ( hDC , 300 , 300 );   /*  Set the extent of the drawing
            *  area.  This is the area that
            *  holds graphics that you create
            *  with GDI functions.  Do not
            *  confuse this function with
            *  the actual window.  The
            *  SetViewportExt sets the
            *  extent of the area to be mapped
            *  to which is the actual window
            */

  GetClientRect ( hWnd , (LPRECT) &rRect );
           /*  Get the size of the client area
            *  so that we can set the viewport
            *  extent
            */

  SetViewportExt ( hDC , rRect.right , rRect.bottom );
           /*  Set the Extent of the viewport   */

  Polygon ( hDC , lpTriangle , 3 );   /*  Draw the triangle          */

  ValidateRect (hWnd , (LPRECT) NULL);   /*  Disable any more paint messages
  EndPaint (hWnd, (LPPAINTSTRUCT) &ps );

  SelectObject( hDC , hOldBrush );   /*  Replace the old brush  */
  return TRUE;
  }


SETWINEX.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\SETWINEX.C

/*
 *  SetWindowExt
 *  setwinex.c
 *
 *  This function demonstrates the use of the SetWindowExt function.  It will
 *  create a window, and procede to draw a triangle in the window in
 *  the MM_ANISOTROPIC mapping mode.
 *
 */

#include <windows.h>

/* Forward Declarations  */

BOOL FAR PASCAL InitSetWindowExt ( HANDLE , HANDLE , int );
long FAR PASCAL SetWindowExtWindowProc ( HANDLE , unsigned , WORD , LONG );

/*
 *  MAIN PROCEDURE
 */

int PASCAL WinMain  (hInstance , hPrevInstance , lpszCmdLine , cmdShow )

HANDLE hInstance , hPrevInstance;
LPSTR  lpszCmdLine;
int cmdShow;
  {
  MSG  msg;          /*  Temp buffer to hold message  */

  InitSetWindowExt (hInstance, hPrevInstance, cmdShow );  /*  Init Routine  *

  while ( GetMessage((LPMSG)&msg, NULL, 0 , 0 ))
    {
    TranslateMessage((LPMSG)&msg);
    DispatchMessage((LPMSG)&msg);     /*  Give Your windowproc the  */
    }              /*  message        */

  exit(msg.wParam);
  }

BOOL FAR PASCAL InitSetWindowExt (hInstance , hPrevInstance , cmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
int cmdShow;

  {
  WNDCLASS  wcSetWindowExtClass;
  HWND  hWnd;

  wcSetWindowExtClass.lpszClassName = (LPSTR) "SetWindowExt";
  wcSetWindowExtClass.hInstance     = hInstance;
  wcSetWindowExtClass.lpfnWndProc   = SetWindowExtWindowProc;
  wcSetWindowExtClass.hCursor      = LoadCursor ( NULL , IDC_ARROW );
  wcSetWindowExtClass.hIcon      = NULL;
  wcSetWindowExtClass.lpszMenuName  = (LPSTR) NULL;
  wcSetWindowExtClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcSetWindowExtClass.style      = CS_HREDRAW | CS_VREDRAW;
  wcSetWindowExtClass.cbClsExtra    = 0;
  wcSetWindowExtClass.cbWndExtra    = 0;

  RegisterClass ((LPWNDCLASS) &wcSetWindowExtClass);

  hWnd = CreateWindow((LPSTR) "SetWindowExt",  /*  Window class name      */
          (LPSTR) "SetWindowExt",  /*  Window title      */
          WS_OVERLAPPEDWINDOW,  /*  Type of window    */
          CW_USEDEFAULT,      /*  x      */
          CW_USEDEFAULT,      /*  y      */
          CW_USEDEFAULT,      /*  cx      */
          CW_USEDEFAULT,      /*  cy      */
          (HWND)NULL,      /*  No parent for this wind */
          (HMENU)NULL,      /*  Use the Class menu  */
          (HANDLE)hInstance,    /*  Who created this window */
          (LPSTR)NULL      /*  No params. to pass on.  */
         );

  ShowWindow (hWnd , cmdShow);   /*  Display this window on the screen  */
  UpdateWindow (hWnd);     /*  Cause a paint message    */

  return TRUE;
  }

/*
 *  THE WINDOW PROCEDURE - Process messages
 */

long FAR PASCAL SetWindowExtWindowProc (hWnd , message , wParam , lParam)

HWND      hWnd;        /*  Handle of the window  */
unsigned    message;        /*  Message type    */
WORD      wParam;        /*  Message 16-bit param  */
LONG      lParam;        /*  Message 32-bit param  */
  {
  switch (message)        /*  Check the message type  */
    {
    case WM_PAINT:        /*  Process the Paint  */
  PaintSetWindowExtWindow (hWnd); /*  message        */
  break;

    case WM_DESTROY:        /*  If close requested  */
  PostQuitMessage(0);      /*    send yourself a quit  */
  break;          /*    message    */

    default:
  return( DefWindowProc( hWnd , message , wParam , lParam ) );
  break;
    }
  return( 0L );
  }

/*
 *  THE PAINT PROCEDURE
 */

PaintSetWindowExtWindow (hWnd)

HWND  hWnd;             /*  Handle of the window  */
  {
  PAINTSTRUCT  ps;
  HDC    hDC;
  POINT   lpTriangle[4];
  HANDLE  hOldBrush , hBrush;        /*  For loading new brushes  */
  RECT    rRect;            /*  Will hold the client     */
                /*  Rectangle       */

  BeginPaint (hWnd , (LPPAINTSTRUCT) &ps);    /*  Prepare the client area  */
  hDC = ps.hdc;             /*  Get the Display Context  */

  hBrush = GetStockObject ( GRAY_BRUSH );     /*  Get a gray brush     */
  hOldBrush = SelectObject ( hDC , hBrush );  /*  Select the new brush     */

  lpTriangle[0].x = 150;    /*  The values of the points  */
  lpTriangle[0].y = 100;
  lpTriangle[1].x = 100;
  lpTriangle[1].y = 200;
  lpTriangle[2].x = 200;
  lpTriangle[2].y = 200;

  SetMapMode ( hDC , MM_ANISOTROPIC );   /*  Set the mapping mode        */

  SetWindowExt ( hDC , 300 , 300 );   /*  Set the extent of the drawing
            *  area.  This is the area that
            *  holds graphics that you create
            *  with GDI functions.  Do not
            *  confuse this function with
            *  the actual window.  The
            *  SetViewportExt sets the
            *  extent of the area to be mapped
            *  to which is the actual window
            */

  GetClientRect ( hWnd , (LPRECT) &rRect );
           /*  Get the size of the client area
            *  so that we can set the viewport
            *  extent
            */

  SetViewportExt ( hDC , rRect.right , rRect.bottom );
           /*  Set the Extent of the viewport   */

  Polygon ( hDC , lpTriangle , 3 );   /*  Draw the triangle          */

  ValidateRect (hWnd , (LPRECT) NULL);   /*  Disable any more paint messages
  EndPaint (hWnd, (LPPAINTSTRUCT) &ps );

  SelectObject( hDC , hOldBrush );   /*  Replace the old brush  */
  return TRUE;
  }


SETWL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CLASS\SETWL.C

/*

Function(s) demonstrated in this program: SetWindowLong

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:   This function replaces the long value in the window class
   structure corresponding to the window handle parameter, with the
   respective new value.

Additional Comments:  This program requests 4 extra bytes when it registers
   its window structure.  These 4 extra bytes are used to store a long
   value corresponding to the number of left mouse button clicks.
   This value is updated using GetWindowLong and SetWindowLong.


*/

#define NOMINMAX
#include <stdlib.h>
#include <windows.h>
#include "SetWl.h"
#include "string.h"
#include "stdio.h"

       char         szAppName             [] = "SetWl"             ;
       HANDLE       hInstMain                                      ;
       HWND         hWndMain                                       ;
       char         szOutputBuffer1       [70]                     ;
       char         szOutputBuffer2       [500]                    ;
       HBITMAP      hBitmapHelp                                    ;


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About",
"     This is a sample application to demonstrate the\n\
use  of  the  SetWindowLong  Windows function.",

"Help Message",
"     This program uses GetWindowLong and\n\
SetWindowLong to keep track of the number of left\n\
button mouse click message.  A message box shows\n\
how many every time one is sent.  Click the left\n\
mouse button to test this function.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
    HANDLE  hInstance, hPrevInstance;
    LPSTR  lpszCmdLine;
    int   nCmdShow;
    {
    HWND  hWnd;
    MSG   msg;
    WNDCLASS  wndclass;
    LONG    WindowCount;


    if (!hPrevInstance)
  {
  wndclass.style           = CS_HREDRAW | CS_VREDRAW | CS_SAVEBITS;
  wndclass.lpfnWndProc    = WndProc;
  wndclass.cbClsExtra     = 0;
  wndclass.cbWndExtra     = 4;
  wndclass.hInstance      = hInstance;
  wndclass.hIcon           = NULL;
   wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW) ;
  wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
  wndclass.lpszMenuName  = szAppName;
  wndclass.lpszClassName  = szAppName;

    if (!RegisterClass (&wndclass) )
        return FALSE;
    }

    hWnd = CreateWindow (szAppName, "SetWindowLong",
           WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
           NULL, NULL, hInstance, NULL);

    ShowWindow (hWnd, nCmdShow);
    UpdateWindow (hWnd);

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
   HWND      hWnd;
   unsigned  iMessage;
   WORD      wParam;
   LONG      lParam;
   {
   HMENU     hMenu;

   switch (iMessage)
       {
       case WM_CREATE:
            hMenu = GetSystemMenu (hWnd, FALSE);

            ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                        MF_APPEND | MF_STRING);
            break;

       case WM_LBUTTONUP:
            SetWindowLong (hWnd, 0, GetWindowLong (hWnd, 0) + 1);
            sprintf (szOutputBuffer1,
                     "Number of left mouse button double clicks = %i",
                      GetWindowLong (hWnd, 0));
            MessageBox (hWnd, szOutputBuffer1, "SetWindowLong", MB_OK);
            break;

       case WM_SYSCOMMAND:
            switch (wParam) {
               case IDM_ABOUT:
                    ProcessMessage (hWnd, 0);
                    break;
               default:
                    return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
            }
            break;


       case WM_COMMAND:
            switch (wParam) {
               case IDM_HELP:
                    ProcessMessage (hWnd, 2);
                    break;
           }
            break;

       case WM_DESTROY:
            PostQuitMessage (0);
            break;

      default:
            return DefWindowProc( hWnd, iMessage, wParam, lParam );
       }
  return 0L;
}



SETWNPOS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\SETWNPOS.C

/*
 *   SetWindowPos
 *   setwnpos.c
 *
 *   This function changes the size, position, and ordering of child,
 *   popup, and top-level windows.  Child, pop-up, and top-level windows
 *   are ordered according to their appearance on the screen; the topmost
 *   window receives the highest rank, and it is the first window in the
 *   list.  This ordering is recorded in a window list.
 *
 */

#include "windows.h"

/* Forward references */

BOOL FAR PASCAL SetWnPosInit( HANDLE );

long FAR PASCAL SetWnPosWndProc(HWND, unsigned, WORD, LONG);

/* ---------------------------------------------------------------------- */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, CmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int CmdShow;
{
    MSG   msg;
    HWND  hParent, hPopup;
    HMENU hMenu;

    SetWnPosInit( hInstance );
    hParent = CreateWindow((LPSTR)"ShowOwnedPopups",
      (LPSTR)"ShowOwnedPopups",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
         (HWND)NULL,        /* no parent */
         (HMENU)NULL,       /* use class menu */
         (HANDLE)hInstance, /* handle to window instance */
         (LPSTR)NULL        /* no params to pass on */
         );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hParent, CmdShow );
    UpdateWindow( hParent );

/* Create the popup window */

    hPopup = CreateWindow((LPSTR)"ShowOwnedPopups",
                       (LPSTR)"Popup",
                        WS_POPUP|WS_CAPTION|WS_VISIBLE,
                      50,
                      50,
                      200,
                      100,
                         (HWND)hParent,     /* parent */
                         (HMENU)NULL,       /* use class menu */
                         (HANDLE)hInstance, /* handle to window instance */
                         (LPSTR)NULL        /* no params to pass on */
                        );
/****************************************************************************
/* Begin SetWindowPos */
/* I am about to move and resize the parent window */

    MessageBox (hParent, (LPSTR)"Move and resize the SetWindowPos window",
               (LPSTR)"I'm about to ...", MB_OK);
    SetWindowPos(hParent, hPopup, 100, 100, 200, 200, SWP_NOACTIVATE);

/* End of SetWindowPos section */
/****************************************************************************

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* ---------------------------------------------------------------------- */
/* Procedure called when the application is loaded for the first time */

BOOL FAR PASCAL SetWnPosInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pSetWnPosClass;

    pSetWnPosClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pSetWnPosClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pSetWnPosClass->hIcon          = LoadIcon( hInstance,NULL);
    pSetWnPosClass->lpszMenuName   = (LPSTR)NULL;
    pSetWnPosClass->lpszClassName  = (LPSTR)"ShowOwnedPopups";
    pSetWnPosClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pSetWnPosClass->hInstance      = hInstance;
    pSetWnPosClass->style          = CS_HREDRAW | CS_VREDRAW;
    pSetWnPosClass->lpfnWndProc    = SetWnPosWndProc;

    if (!RegisterClass( (LPWNDCLASS)pSetWnPosClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pSetWnPosClass );
    return TRUE;        /* Initialization succeeded */
}


/* ---------------------------------------------------------------------- */
/* Every message for this window will be delevered right here.         */

long FAR PASCAL SetWnPosWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

/*    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break; */

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


SETWNTXT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TEXT\SETWNTXT.C

/*
 *  SetWindowText
 *  setwntxt.c
 *
 *  This program demonstrates the use of the function SetWindowText.
 *  First a message box is shown which says that the window text caption
 *  is about to change.  After the caption changes then a message box pops
 *  up which gives the user a chance to look at the change.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pClass;

    pClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    /* registering the parent window class */
    pClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pClass->lpszMenuName   = (LPSTR)NULL;
    pClass->lpszClassName  = (LPSTR)"Window";
    pClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pClass->hInstance      = hInstance;
    pClass->style          = CS_HREDRAW | CS_VREDRAW;
    pClass->lpfnWndProc    = DefWindowProc;

    if (!RegisterClass( (LPWNDCLASS)pClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE) pClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;         /* Handle to the parent window  */
    HDC   hDC;          /* Handle to the display context of client area */
    char szBuffer[80];        /* Contains the new caption title */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Window",
      (LPSTR)"SetWindowText",  /* Window caption title */
                        WS_TILEDWINDOW,
                        20,20,400,200,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow (hWnd, cmdShow);
    UpdateWindow (hWnd);

    MessageBox (hWnd, (LPSTR)"Press ENTER to change the caption title",
    (LPSTR)"Done", MB_OK);
    sprintf (szBuffer,"%s","New Caption Title to demonstrate SetWindowText");
/**************************************************************************/
/* This function will set the window caption title to the string pointed
 * to by szBuffer.  SetWindowText has no return value. */

    SetWindowText (hWnd, (LPSTR)szBuffer);

/**************************************************************************/

    MessageBox (hWnd, (LPSTR)"The caption title has been changed",
    (LPSTR)"Done", MB_OK);

    return 0;
}


SETWNWRD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\SETWNWRD.C

/*
 *   SetWindowWord
 *   setwnwrd.c
 *
 *   This program demonstrates the use of the function SetWindowWord.
 *   SetWindowWord changes an attribute of a window.  The attribute
 *   can be one of the following options: the instance handle of the
 *   module that owns the window, the window handle of the parent window
 *   if one exists, the control ID of the child window.
 *
 */

#include "windows.h"

/* Forward references */

BOOL FAR PASCAL SampleInit( HANDLE );

long FAR PASCAL SampleWndProc(HWND, unsigned, WORD, LONG);

/* ---------------------------------------------------------------------- */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, CmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int CmdShow;
{
    MSG   msg;
    HWND  hParent1, hParent2, hPopup;
    HMENU hMenu;

    SampleInit( hInstance );

/* Create the first parent window */

    hParent1 = CreateWindow((LPSTR)"SetWindowWord",
      (LPSTR)"SetWindowWord - Parent1",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      400,
       20,
         (HWND)NULL,        /* no parent */
         (HMENU)NULL,       /* use class menu */
         (HANDLE)hInstance, /* handle to window instance */
         (LPSTR)NULL        /* no params to pass on */
         );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hParent1, CmdShow );
    UpdateWindow( hParent1 );

    MessageBox (hParent1, (LPSTR)"create a popup window for parent1",
               (LPSTR)"I'm about to ...", MB_OK);

/* Create the popup window */

    hPopup = CreateWindow((LPSTR)"SetWindowWord",
                       (LPSTR)"Popup",
                        WS_POPUP|WS_CAPTION|WS_VISIBLE,
                      10,
                      50,
                      200,
                      100,
                         (HWND)hParent1,     /* parent */
                         (HMENU)NULL,       /* use class menu */
                         (HANDLE)hInstance, /* handle to window instance */
                         (LPSTR)NULL        /* no params to pass on */
                        );


    MessageBox (hParent1, (LPSTR)"create a second window called parent2",
               (LPSTR)"I'm about to ...", MB_OK);

/* Create the second parent window */

    hParent2 = CreateWindow((LPSTR)"SetWindowWord",
      (LPSTR)"SetWindowWord - Parent2",
      WS_OVERLAPPEDWINDOW,
      100,
      100,
      400,
      20,
         (HWND)NULL,        /* no parent */
         (HMENU)NULL,       /* use class menu */
         (HANDLE)hInstance, /* handle to window instance */
         (LPSTR)NULL        /* no params to pass on */
         );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hParent2, CmdShow );
    UpdateWindow( hParent2 );

/****************************************************************************
/* Begin SetWindowWord */
/* I have set up this function to change the parent of the popup window */

    MessageBox (hParent1, (LPSTR)"make the Parent2 the parent of Popup, and \
iconize Parent1.  Notice that Parent2 is currently in front of Popup .",
               (LPSTR)"I'm about to ...", MB_OK);

    SetWindowWord(hPopup, GWW_HWNDPARENT, hParent2);
    ShowWindow( hParent1, SW_SHOWMINIMIZED );

    MessageBox (hParent1, (LPSTR)"move Parent2 in front of the Popup.  \
You can't do it because Parent2 is now the parent of Popup!",
               (LPSTR)"Now try to ...", MB_OK);

/* End of SetWindowWord section */
/****************************************************************************

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* ---------------------------------------------------------------------- */
/* Procedure called when the application is loaded for the first time */

BOOL FAR PASCAL SampleInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pSampleClass;

    pSampleClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pSampleClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pSampleClass->hIcon          = LoadIcon( hInstance,NULL);
    pSampleClass->lpszMenuName   = (LPSTR)NULL;
    pSampleClass->lpszClassName  = (LPSTR)"SetWindowWord";
    pSampleClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pSampleClass->hInstance      = hInstance;
    pSampleClass->style          = CS_HREDRAW | CS_VREDRAW;
    pSampleClass->lpfnWndProc    = SampleWndProc;

    if (!RegisterClass( (LPWNDCLASS)pSampleClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pSampleClass );
    return TRUE;        /* Initialization succeeded */
}


/* ---------------------------------------------------------------------- */
/* Every message for this window will be delevered right here.         */

long FAR PASCAL SampleWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

/*    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break; */

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


SHOWCURS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CURSOR\SHOWCURS.C

/*
Function(s) demonstrated in this program:  ShowCursor

Compiler version:  5.10

Description:  Use ShowCursor to hide the cursor each time the right mouse
        button is pressed, and display it again when the button is
        released.

Additional Comments:



****************************************************************************/

#include <windows.h>

long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "SampleWindow" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG   msg;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
    wndclass.hCursor   = LoadCursor (NULL, IDC_CROSS);
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWnd = CreateWindow (szAppName,            /* window class name       */
        "Using the ShowCursor function",  /* window caption    */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWnd, nCmdShow) ;

     UpdateWindow (hWnd) ;

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG   lParam ;
    {
    PAINTSTRUCT ps;
    HDC   hDC;
    switch(iMessage)
  {
  case WM_CREATE:
      {
      break;
      }
  case WM_PAINT:
      {
      hDC = BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
      EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
      break;
      }
  case WM_RBUTTONDOWN:
      {
      ShowCursor(0);
      break;
      }
  case WM_RBUTTONUP:
      {
      ShowCursor(1);
      break;
      }
  case WM_DESTROY:
      {
      PostQuitMessage(0);
      break;
      }
  default:
      {
      return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
      }
  }
    return (0L);
    }


SHOWPOPS.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\SHOWPOPS.C

/*
 *   ShowOwnedPopups
 *   showpops.c
 *
 *   This program demonstrates the use of the function ShowOwnedPopups.
 *   A pop-up window is initially shown visible.   At the same time a
 *   message box appears.  When the message box is acknowledged then
 *   the pop-up window becomes invisible.  Another message box appears.
 *   When the second message box is acknowledged then the pop-up window
 *   becomes visible again.
 *
 */

#include "windows.h"

/* Forward references */

BOOL FAR PASCAL SampleInit( HANDLE );

long FAR PASCAL SampleWndProc(HWND, unsigned, WORD, LONG);

/* ---------------------------------------------------------------------- */

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, CmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int CmdShow;
{
    MSG   msg;
    HWND  hParent,hPopup;
    HMENU hMenu;

    SampleInit( hInstance );
    hParent = CreateWindow((LPSTR)"ShowOwnedPopups",
      (LPSTR)"ShowOwnedPopups",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
         (HWND)NULL,        /* no parent */
         (HMENU)NULL,       /* use class menu */
         (HANDLE)hInstance, /* handle to window instance */
         (LPSTR)NULL        /* no params to pass on */
         );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hParent, CmdShow );
    UpdateWindow( hParent );

/* Create the popup window */

    hPopup = CreateWindow((LPSTR)"ShowOwnedPopups",
                       (LPSTR)"Popup",
                        WS_POPUP|WS_CAPTION|WS_VISIBLE,
                      50,
                      50,
                      200,
                      100,
                         (HWND)hParent,     /* parent */
                         (HMENU)NULL,       /* use class menu */
                         (HANDLE)hInstance, /* handle to window instance */
                         (LPSTR)NULL        /* no params to pass on */
                        );
/****************************************************************************
/* Begging of ShowOwnedPopups section */

/* void ShowOwnedPopups( hWnd, fShow )
 *
 * The first parameter 'hWnd' is the handle to the parent window that
 * owns the pop-up.  The second parameter 'fShow' is nonzero if all
 * hidden pop-up windows should be shown; it is zero if all visible
 * pop-up windows should be hidden                                          *

    MessageBox (hParent, (LPSTR)"Hide the popup.",
               (LPSTR)"Done", MB_OK);

    ShowOwnedPopups(hParent,FALSE);                /* Hide the popup */

    MessageBox (hParent, (LPSTR)"Show the popup.",
             (LPSTR)"Done", MB_OK);

    ShowOwnedPopups(hParent,TRUE);                /* Show the popup */

/* End of ShowOwnedPopups section */
/****************************************************************************

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* ---------------------------------------------------------------------- */
/* Procedure called when the application is loaded for the first time */

BOOL FAR PASCAL SampleInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pSampleClass;

    pSampleClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pSampleClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pSampleClass->hIcon          = LoadIcon( hInstance,NULL);
    pSampleClass->lpszMenuName   = (LPSTR)NULL;
    pSampleClass->lpszClassName  = (LPSTR)"ShowOwnedPopups";
    pSampleClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pSampleClass->hInstance      = hInstance;
    pSampleClass->style          = CS_HREDRAW | CS_VREDRAW;
    pSampleClass->lpfnWndProc    = SampleWndProc;

    if (!RegisterClass( (LPWNDCLASS)pSampleClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pSampleClass );
    return TRUE;        /* Initialization succeeded */
}


/* ---------------------------------------------------------------------- */
/* Every message for this window will be delevered right here.         */

long FAR PASCAL SampleWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

/*    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break; */

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


SHOWSB.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SCROLL\SHOWSB.C

/*

Function(s) demonstrated in this program: ShowScrollBar

Description:  This function displays or hides a scroll bar, depending on the
   value of the the parameters.

*/

#include <windows.h>
#include <stdio.h>
#include "ShowSB.h"
char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];

/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About",
"     This is a sample  application to demonstrate\n\
the use of the ShowScrollBar Windows function.",

"Help Message",
"     This program uses the ShowScrollBar Windows\n\
function to change status of the Scroll bars of the\n\
window.  Use the menu to choose the status (show or\n\
hide)."

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE   hInstance, hPrevInstance ;
     LPSTR    lpszCmdLine ;
     int      nCmdShow ;
     {
     WNDCLASS wndclass ;
     HWND     hWnd ;
     MSG      msg ;
     static   char szAppName [] = "ShowSB" ;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWnd = CreateWindow (szAppName, "Show Scroll Bar",
                         WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
                         CW_USEDEFAULT, 0,
                         CW_USEDEFAULT, 0,
                         NULL, NULL, hInstance, NULL) ;

     ShowWindow (hWnd, nCmdShow) ;
     UpdateWindow (hWnd) ;

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

/****************************************************************************


long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
     HWND         hWnd ;
     unsigned     iMessage ;
     WORD         wParam ;
     LONG         lParam ;
     {
     PAINTSTRUCT  ps ;
     HMENU        hMenu;

     switch (iMessage)
          {
          case WM_CREATE:
               hMenu = GetSystemMenu (hWnd, FALSE);
               ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                           MF_APPEND | MF_STRING);
               break ;

          case WM_SYSCOMMAND:
               switch (wParam) {
                  case IDM_ABOUT:
                       ProcessMessage (hWnd, 0);
                       break;
                  default:
                       return DefWindowProc (hWnd, iMessage, wParam, lParam)
               }
               break;

          case WM_COMMAND:
               switch (wParam) {
                  case IDM_ABOUT:
                       ProcessMessage (hWnd, 0);
                       break;

                  case IDM_SHOW:
                       ShowScrollBar (hWnd, SB_BOTH, TRUE);
                       break;

                  case IDM_HIDE:
                       ShowScrollBar (hWnd, SB_BOTH, FALSE);
                       break;

                  case IDM_HELP:
                       ProcessMessage (hWnd, 2);
                       break;
               }
               break;

          case WM_PAINT:
               BeginPaint (hWnd, &ps) ;
               EndPaint (hWnd, &ps) ;
               break ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               break ;

          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
          }
     return 0L ;
     }


SHOWWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\WINDOW\SHOWWIN.C

/*
 *  ShowWindow
 *  showwin.c
 *
 *  This function demonstrates the use of the ShowWindow function.  It will
 *  create a window, show the window using the ShowWindow command and procede
 *  to draw a triangle in the window in the MM_ANISOTROPIC mapping mode.
 *
 */

#include <windows.h>

/* Forward Declarations  */

BOOL FAR PASCAL InitShowWindow ( HANDLE , HANDLE , int );
long FAR PASCAL ShowWindowWindowProc ( HANDLE , unsigned , WORD , LONG );

/*
 *  MAIN PROCEDURE
 */

int PASCAL WinMain  (hInstance , hPrevInstance , lpszCmdLine , nCmdShow )

HANDLE hInstance , hPrevInstance;
LPSTR  lpszCmdLine;
int nCmdShow;
  {
  MSG  msg;          /*  Temp buffer to hold message  */

  InitShowWindow (hInstance, hPrevInstance, nCmdShow );  /*  Init Routine  */

  while ( GetMessage((LPMSG)&msg, NULL, 0 , 0 ))
    {
    TranslateMessage((LPMSG)&msg);
    DispatchMessage((LPMSG)&msg);     /*  Give Your windowproc the  */
    }              /*  message        */

  exit(msg.wParam);
  }

BOOL FAR PASCAL InitShowWindow (hInstance , hPrevInstance , nCmdShow)

HANDLE hInstance;
HANDLE hPrevInstance;
int nCmdShow;

  {
  WNDCLASS  wcShowWindowClass;
  HWND  hWnd;

  wcShowWindowClass.lpszClassName = (LPSTR) "ShowWindow";
  wcShowWindowClass.hInstance    = hInstance;
  wcShowWindowClass.lpfnWndProc   = ShowWindowWindowProc;
  wcShowWindowClass.hCursor    = LoadCursor ( NULL , IDC_ARROW );
  wcShowWindowClass.hIcon    = NULL;
  wcShowWindowClass.lpszMenuName  = (LPSTR) NULL;
  wcShowWindowClass.hbrBackground = GetStockObject (WHITE_BRUSH);
  wcShowWindowClass.style    = CS_HREDRAW | CS_VREDRAW;
  wcShowWindowClass.cbClsExtra    = 0;
  wcShowWindowClass.cbWndExtra    = 0;

  RegisterClass ((LPWNDCLASS) &wcShowWindowClass);

  hWnd = CreateWindow((LPSTR) "ShowWindow",   /*  Window class name    */
          (LPSTR) "ShowWindow",   /*  Window title      */
          WS_OVERLAPPEDWINDOW,  /*  Type of window    */
          CW_USEDEFAULT,      /*  x      */
          CW_USEDEFAULT,      /*  y      */
          CW_USEDEFAULT,      /*  cx      */
          CW_USEDEFAULT,      /*  cy      */
          (HWND)NULL,      /*  No parent for this wind */
          (HMENU)NULL,      /*  Use the Class menu  */
          (HANDLE)hInstance,    /*  Who created this window */
          (LPSTR)NULL      /*  No params. to pass on.  */
         );

  ShowWindow (hWnd , nCmdShow);   /*  Display this window on the screen
           *  nCmdShow is passed in by WinMain, and
           *  should only be used with ShowWindow
           *  once during a program.  Any further
           *  calls to ShowWindow will need to have
           *  certain values.  See entry in manual
           *  for ShowWindow for further details
           */

  UpdateWindow (hWnd);     /*  Cause a paint message    */

  return TRUE;
  }

/*
 *  THE WINDOW PROCEDURE - Process messages
 */

long FAR PASCAL ShowWindowWindowProc (hWnd , message , wParam , lParam)

HWND      hWnd;        /*  Handle of the window  */
unsigned    message;        /*  Message type    */
WORD      wParam;        /*  Message 16-bit param  */
LONG      lParam;        /*  Message 32-bit param  */
  {
  switch (message)        /*  Check the message type  */
    {
    case WM_PAINT:        /*  Process the Paint  */
  PaintShowWindowWindow (hWnd); /*  message      */
  break;

    case WM_DESTROY:        /*  If close requested  */
  PostQuitMessage(0);      /*    send yourself a quit  */
  break;          /*    message    */

    default:
  return( DefWindowProc( hWnd , message , wParam , lParam ) );
  break;
    }
  return( 0L );
  }

/*
 *  THE PAINT PROCEDURE
 */

PaintShowWindowWindow (hWnd)

HWND  hWnd;             /*  Handle of the window  */
  {
  PAINTSTRUCT  ps;
  HDC    hDC;
  POINT   lpTriangle[4];
  HANDLE  hOldBrush , hBrush;        /*  For loading new brushes  */
  RECT    rRect;            /*  Will hold the client     */
                /*  Rectangle       */

  BeginPaint (hWnd , (LPPAINTSTRUCT) &ps);    /*  Prepare the client area  */
  hDC = ps.hdc;             /*  Get the Display Context  */

  hBrush = GetStockObject ( GRAY_BRUSH );     /*  Get a gray brush     */
  hOldBrush = SelectObject ( hDC , hBrush );  /*  Select the new brush     */

  lpTriangle[0].x = 150;    /*  The values of the points  */
  lpTriangle[0].y = 100;
  lpTriangle[1].x = 100;
  lpTriangle[1].y = 200;
  lpTriangle[2].x = 200;
  lpTriangle[2].y = 200;

  SetMapMode ( hDC , MM_ANISOTROPIC );   /*  Set the mapping mode        */

  SetWindowExt ( hDC , 300 , 300 );   /*  Set the extent of the drawing
            *  area.  This is the area that
            *  holds graphics that you create
            *  with GDI functions.  Do not
            *  confuse this function with
            *  the actual window.  The
            *  SetViewportExt sets the
            *  extent of the area to be mapped
            *  to which is the actual window
            */

  GetClientRect ( hWnd , (LPRECT) &rRect );
           /*  Get the size of the client area
            *  so that we can set the viewport
            *  extent
            */

  SetViewportExt ( hDC , rRect.right , rRect.bottom );
           /*  Set the Extent of the viewport   */

  Polygon ( hDC , lpTriangle , 3 );   /*  Draw the triangle          */

  ValidateRect (hWnd , (LPRECT) NULL);   /*  Disable any more paint messages
  EndPaint (hWnd, (LPPAINTSTRUCT) &ps );

  SelectObject( hDC , hOldBrush );   /*  Replace the old brush  */
  return TRUE;
  }


SHWCARET.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\CARET\SHWCARET.C

/*
 *  ShowCaret
 *  shwcaret.c
 *
 *  This program demonstrates the use of the function ShowCaret.
 *  This function shows the system caret on the display at the
 *  caret's current position.  Once shown, the caret begins flashing
 *  automatically.
 *
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pClass;

    pClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    /* registering the parent window class */
    pClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pClass->lpszMenuName   = (LPSTR)NULL;
    pClass->lpszClassName  = (LPSTR)"Window";
    pClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pClass->hInstance      = hInstance;
    pClass->style          = CS_HREDRAW | CS_VREDRAW;
    pClass->lpfnWndProc    = DefWindowProc;

    if (!RegisterClass( (LPWNDCLASS)pClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE) pClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND         hWnd;                /* Handle to the parent window    */

    WinInit (hInstance);

    hWnd = CreateWindow((LPSTR)"Window",
      (LPSTR)"ShowCaret",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,     /* x         */
                        CW_USEDEFAULT,     /* y         */
                        CW_USEDEFAULT,     /* width     */
                        CW_USEDEFAULT,     /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                       );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

/*************************************************************************/

    CreateCaret (hWnd, NULL, 8, 12); /* Create a caret before showing */
    SetCaretPos (50,50);
    ShowCaret (hWnd);         /* ShowCaret doesn't return a value */

/*************************************************************************/

    /* Message Box will make the parent window inactive */
    MessageBox (hWnd, (LPSTR)"The flashing black box is the caret",
    (LPSTR)"ShowCaret", MB_OK);


    return 0;
}


SIZEOFRE.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\RESOURCE\SIZEOFRE.C

/*

Name: Sizeofre.c

Description        :
        FindResource is used first to locate and identify the resource
        item.  SizeofResource is used to determine how many bytes need
        to be read to obtain the resource item, and finally
        AccessResource() is used to get the handle and set the file
        pointer to the beginning of the selected resource.  AccessResource()
        opens the file (resource) as a result, so it must be explicitely
        closed.  In this case, "It works!" is displayed in a MessageBox()
        upon successful completion, "It failed" displays if unsuccessful.


Additional Comments: Note that _lclose() must be used to close the file
(resource).

*/

#include <windows.h>
#include "sizeofre.h"

long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;
int sprintf(PSTR, PSTR, int);
int FAR PASCAL _lclose(int);
int FAR PASCAL _lread(HANDLE, LPSTR, short);

static char szBuffer[8];
static int ErrorCheck;
static char szResName [] = "HotStuff";

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "Resources" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWnd = CreateWindow (szAppName,            /* window class name       */
                    "The Joy of Resources",     /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWnd, nCmdShow) ;

     UpdateWindow (hWnd) ;

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 static HANDLE hInstance, hResource;
 int hFile;

 PAINTSTRUCT ps;
 char szStuff[20], szSuccess[20];
 short sRes;
 HMENU hMenu;
 switch(iMessage)
 {
  case WM_CREATE:
  {
   hInstance = GetWindowWord(hWnd, GWW_HINSTANCE);
   hMenu = LoadMenu(hInstance, "ResMenu");
   SetMenu(hWnd, hMenu);
   DrawMenuBar(hWnd);
   break;
  }
  case WM_PAINT:
  {
   BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
   EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
   break;
  }
  case WM_COMMAND:
  {
   switch(wParam)
   {
    case IDM_EXECUTE:
    {
     /* FindResource is used first to locate and identify the resource
        item.  SizeofResource is used to determine how many bytes need
        to be read to obtain the resource item, and finally
        AccessResource() is used to get the handle and set the file
        pointer to the beginning of the selected resource.  AccessResource()
        opens the file (resource) as a result, so it must be explicitely
        closed.
     */
     hResource = FindResource(hInstance, "HotStuff", RT_RCDATA);
     sRes = SizeofResource(hInstance, hResource);
     hFile = AccessResource(hInstance, hResource);
     ErrorCheck = _lread(hFile, (LPSTR)szStuff, sRes);
     ErrorCheck = _lclose(hFile);
     if (hFile<1)
     {
      ErrorCheck = sprintf(szStuff, "It failed");
      ErrorCheck = sprintf(szSuccess, "Error");
     } else
     {
      ErrorCheck = sprintf(szSuccess, "Item read");
     }
     MessageBox(GetFocus(), szStuff, szSuccess, MB_OK);
    }
   }
   break;
  }
  case WM_DESTROY:
  {
   PostQuitMessage(0);
   break;
  }
  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}


SMAPFLAG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\FONTS\SMAPFLAG.C

/*
 *  SetMapperFlags
 *  smapflag.c
 *
 *  This program demonstrates the use of the function SetMapperFlags.
 *  This function alters the algorithm that the font mapper uses when it
 *  maps logical fonts to physical fonts.  When the first bit in the first
 *  parameter is set to one, the mapper will only select fonts whose aspect
 *  ratios match those of the specified device.  If no fonts exit with a
 *  matching aspect ratio, GDI chooses an aspect ratio and select fonts
 *  with aspect ratios that match the one by GDI.
 *
 */

#include "windows.h"

static HANDLE hWnd;

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
  HDC hDC;
  PAINTSTRUCT ps;
  DWORD ptAspectRatio;
  DWORD ptMapperFlags;
  char szbuff[160];

  if ( !hPrevInstance )
     {
     WNDCLASS rClass;

     rClass.lpszClassName = ( LPSTR ) "smapflag";
     rClass.hInstance     = hInstance;
     rClass.lpfnWndProc   = DefWindowProc;
     rClass.hCursor       = LoadCursor ( NULL , IDC_ARROW );
     rClass.hIcon         = LoadIcon ( hInstance, IDI_APPLICATION );
     rClass.lpszMenuName  = ( LPSTR ) NULL;
     rClass.hbrBackground = GetStockObject ( WHITE_BRUSH );
     rClass.style         = CS_HREDRAW | CS_VREDRAW;
     rClass.cbClsExtra    = 0;
     rClass.cbWndExtra    = 0;

     RegisterClass ( ( LPWNDCLASS ) &rClass );
     }

  hWnd = CreateWindow ( ( LPSTR ) "smapflag", ( LPSTR ) "SetMapperFlags",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      CW_USEDEFAULT, CW_USEDEFAULT,
                      ( HWND ) NULL, ( HMENU ) NULL,
                      ( HANDLE ) hInstance, ( LPSTR ) NULL );

  ShowWindow ( hWnd , cmdShow );
  BeginPaint ( hWnd, ( LPPAINTSTRUCT ) &ps );
  hDC = ps.hdc;

  MessageBox (NULL, (LPSTR)"Setting font-mapper flag",
     (LPSTR)"SetMapperFlags", MB_OK);

  ptMapperFlags = SetMapperFlags( hDC, (long) 1 );

  ptAspectRatio = GetAspectRatioFilter ( hDC );

  sprintf ( szbuff, "%s%d%s%d\n%s%d%s%d\0", "Old aspect ratio is: x= ",
           HIWORD(ptMapperFlags), " y= ", LOWORD(ptMapperFlags),
           "New aspect ratio is: x= ", HIWORD(ptAspectRatio), " y= ",
           LOWORD(ptAspectRatio));

  MessageBox (NULL, (LPSTR) szbuff, (LPSTR)"SetMapperFlags", MB_OK);

  return 0;
}


SMETAFB.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\METAFILE\SMETAFB.C

/*
 * This application demonstrates the SetMetaFile() Windows function.
 * The result is demonstrated on the screen.
 *
 */
#include "windows.h"

static HANDLE hInst;
HANDLE hMF;
HANDLE hMem;
HANDLE hMetaDC;
HANDLE hSetMF;

long FAR PASCAL SetMetaWndProc(HWND, unsigned, WORD, LONG);

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    if (!hPrevInstance) {
       PWNDCLASS   pSetMetaClass;

       pSetMetaClass = (PWNDCLASS)LocalAlloc(LPTR, sizeof(WNDCLASS));

       pSetMetaClass->hCursor        = LoadCursor(NULL, IDC_ARROW);
       pSetMetaClass->hIcon          = NULL;
       pSetMetaClass->lpszMenuName   = (LPSTR)NULL;
       pSetMetaClass->lpszClassName  = (LPSTR)"SetMetaFileBits";
       pSetMetaClass->hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
       pSetMetaClass->hInstance      = hInstance;
       pSetMetaClass->style          = CS_HREDRAW | CS_VREDRAW;
       pSetMetaClass->lpfnWndProc    = SetMetaWndProc;

       if (!RegisterClass((LPWNDCLASS)pSetMetaClass))
           return FALSE;

       LocalFree((HANDLE)pSetMetaClass);
       }

    hWnd = CreateWindow((LPSTR)"SetMetaFileBits",
                        (LPSTR)"SetMetaFileBits() Demo",
                        WS_TILEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,
                        (HMENU)NULL,
                        (HANDLE)hInstance,
                        (LPSTR)NULL
                        );

    hInst = hInstance;

    hMetaDC = CreateMetaFile(NULL);
    if (hMetaDC == NULL)
       MessageBox(GetFocus(),
                  (LPSTR)"Error in Creating Memory Metafile",
                  (LPSTR)"CreateMetaFile() Error!",
                  MB_OK | MB_ICONEXCLAMATION);
    else {
       Rectangle(hMetaDC, 10, 10, 200, 200);
       Rectangle(hMetaDC, 201, 10, 401, 200);
       LineTo(hMetaDC, 100, 250);
       Ellipse(hMetaDC, 0, 0, 100, 100);
       hMF = CloseMetaFile(hMetaDC);
       if (hMF == NULL)
          MessageBox(GetFocus(),
                     (LPSTR)"Error Closing Meta File.",
                     (LPSTR)"CloseMetaFile() Error!",
                     MB_OK | MB_ICONEXCLAMATION);
       else {
          hMem = GetMetaFileBits(hMF);
          if (hMem == NULL)
             MessageBox (GetFocus(),
                         (LPSTR)"Error in Obtaining Metafile Bit Handle",
                         (LPSTR)"GetMetaFileBits() Error!!!",
                         MB_OK | MB_ICONEXCLAMATION);
          else {
             hSetMF = SetMetaFileBits(hMem);
             if (hSetMF == NULL)
                MessageBox(GetFocus(),
                           (LPSTR)"Error in Setting Meta File Bits!",
                           (LPSTR)"SetMetaFileBits() Error!!!",
                           MB_OK | MB_ICONEXCLAMATION);
             }
          }
       }

    ShowWindow(hWnd, cmdShow);
    UpdateWindow(hWnd);

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

long FAR PASCAL SetMetaWndProc(hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
{
   PAINTSTRUCT ps;
   HDC         hDC;

   switch (iMessage) {
      case WM_PAINT:
         hDC = BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
         PlayMetaFile(hDC, hSetMF);
         EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
         break;

      default:
         return DefWindowProc(hWnd, iMessage, wParam, lParam);
      }
   return(0L);
}



SOUNDX.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SOUND\SOUNDX.C

/***********************************************************************
 *** Functions demonstrated: (all of them...)
 ***      CloseSound, OpenSound,
 ***      StartSound, StopSound,
 ***      CountVoiceNotes, SetVoiceNote,
 ***      SetVoiceSound, SetSoundNoise,
 ***      SetVoiceQueueSize, SetVoiceAccent,
 ***      SetVoiceEnvelope, SetVoiceThreshold,
 ***      GetThresholdEvent, GetThresholdStatus,
 ***      SyncAllVoices, WaitSoundState.
 ***
 *** Note that the files are not named SOUND.  This is because
 *** Windows has an internal driver named sound and will not accept
 *** sound as an application name.
 ************************************************************************/

#include <windows.h>
#include <stdio.h>
#include "soundx.h"

long FAR PASCAL SoundWndProc (HWND, unsigned, WORD, LONG);

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
    HANDLE  hInstance, hPrevInstance;
    LPSTR  lpszCmdLine;
    int   nCmdShow;
    {
    HWND  hWnd;
    MSG   msg;
    WNDCLASS  wndclass;

    if (!hPrevInstance)
  {
  wndclass.style    = CS_HREDRAW | CS_VREDRAW;
  wndclass.lpfnWndProc  = SoundWndProc;
  wndclass.cbClsExtra  = 0;
  wndclass.cbWndExtra  = 0;
  wndclass.hInstance  = hInstance;
  wndclass.hIcon    = LoadIcon(NULL, IDI_ASTERISK);
  wndclass.hCursor  = LoadCursor(NULL,  IDC_ARROW);
  wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
  wndclass.lpszMenuName  = "SoundMenu";
  wndclass.lpszClassName  = "Sound";

  if (!RegisterClass(&wndclass) )
      return FALSE;
  }

    hWnd = CreateWindow("Sound", "Sound Window",
    WS_MINIMIZEBOX | WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU,
    270, 130, 40, 54, NULL, NULL, hInstance, NULL);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

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

    return msg.wParam;
    }

long FAR PASCAL SoundWndProc (hWnd, iMessage, wParam, lParam)
    HWND    hWnd;
    unsigned    iMessage;
    WORD    wParam;
    LONG    lParam;
    {
    char   szJunk[40];    /* Buffer fo MessageBoxes    */
    unsigned int nIndex;    /* Generic index counter    */
    static int   nNoise=0,    /* Noise parameter      */
     nCount=0;    /* Number returned from GetVoiceNotes */
    static BOOL  bThresh=FALSE,   /* SetVoiceThreshold flag    */
     bEnv=FALSE;    /* SetVoiceEnvelope flag    */

    /* Notes from The Appassionata          */
    static int   nNotes[60]={45,42,38,45,38,47,43,38,45,42,38,45,
           38,45,40,47,45,40,38,40,37,45,40,37,
           45,42,38,45,42,50,45,42,50,45,42,50,
           43,50,47,43,50,45,42,50,42,50,44,50,
           40,49,45,40,49,45,40,49,50,45,40,33};

    switch (iMessage)
  {
  case WM_DESTROY:
      PostQuitMessage(0);
      /* fall through */

  /* Release resources if focus is lost or window is iconized  */
  /* or ended.  Remove these and a constant sound will continue  */
  /* for a time even if the window is no longer around.  The bad  */
  /* part is that sound resources are not released and that can  */
  /* screw up DOS as well as Windows.        */
  case WM_KILLFOCUS:
  case WM_SETVISIBLE:
      CloseSound();
      StopSound();
      break;

  /* Open sound resources if window is opened or obtains the focus*/
  case WM_SETFOCUS:
      OpenSound();
      break;

  case WM_COMMAND:
      /* Set number of notes in queue.  Windows only has multiple */
      /* voice capability if the computer has sound hardware.  */
      SetVoiceQueueSize(1, 600);

      switch (wParam)
    {
    case ID_NOTES:
        /* Set temp, volume, and style of notes.  For the  */
        /* most part, the tempo parameter (2nd) is the only */
        /* effective value on machines without additional  */
        /* sound hardware (volume is ineffective).    */
        SetVoiceAccent(1, 220, 20, S_NORMAL, 0);

        /* Set the number of notes in threshold to 30.  This*/
        /* causes the threshold flag to be set when the  */
        /* number of remaining notes falls below 30.  */
        if (bThresh)
      SetVoiceThreshold(1, 30);

        /* Set an envelope          */
        SetVoiceEnvelope(1, bEnv, 3);

        /* Set notes in queue.  Note 0 is a rest, note 1 is */
        /* two octaves below middle C.  Concert A (440Hz) is*/
        /* 34.  To prove this, do SetVoiceNote(1,34,1,0)  */
        /* and SetVoiceSound(1,440L*65536L, 300).  The tones*/
        /* are equivalent.          */
        for (nIndex=84; nIndex > 0; nIndex -=1 )
      SetVoiceNote(1, nIndex, 250, 0);

        /* Play the sound          */
        StartSound();

        /* Retain the count of notes      */
        nCount=CountVoiceNotes(1);
        break;

    case ID_SOUND:
        /* Set sounds in queue.  Second parameter to  */
        /* SetVoiceSound is a LONG, not an int as stated in */
        /* the documentation. Also, the documentation states*/
        /* that the high-order word of the second parameter */
        /* is the frequency in Kilohertz.  However, it is  */
        /* actually in Hertz.  Otherwise, this routine would*/
        /* produce very minimal audible sound.    */

        for (nIndex=750; nIndex >=1; nIndex -=3)
      SetVoiceSound(1, (unsigned long)(nIndex*65536L), 3);

        StartSound();
        nCount=0;

        /* Wait until all sounds have been played    */
        WaitSoundState(S_QUEUEEMPTY);
        break;

    case ID_NOISE:
        /* Start noise. Must StartSound after SetSoundNoise.*/
        /* Full use of this function requires other sound  */
        /* drivers not available on standard machines.  */
        StopSound();
        SetSoundNoise(nNoise++, 100);
        StartSound();
        nCount=0;
        for (nIndex=0; nIndex < 65535; nIndex++); /* pause  */
        StopSound();
        nNoise &=7;
        break;

    case LUDWIG:
        /* Play beginning of second movement to the Andante */
        /* in Beethoven's Appassionata.                     */
        StopSound();
        SetVoiceAccent(1, 70, 120, S_LEGATO, 0);
        SetVoiceEnvelope(1, bEnv, 3);
        if (bThresh)
      SetVoiceThreshold(1, 30);

        /* Set notes from the data array.      */
        for (nIndex=0; nIndex<60; nIndex++)
      SetVoiceNote(1, nNotes[nIndex], 16, 0);

        SetVoiceNote(1,50,4,0); /* Longer final note.  */

        /* Start sound.  Continues playing until it done,  */
        /* the window is detroyed, loses the input focus,  */
        /* or iconized.  WaitSoundState can be used to wait */
        /* until the sound is finished.      */
        StartSound();
        nCount=CountVoiceNotes(1);
        break;

    case ID_COUNT:
        /* Show the current value of nCount. GetVoiceNotes  */
        /* only counts notes, not sounds, envelopes, etc.  */
        sprintf(szJunk, "Notes=%d", nCount);
        MessageBox(hWnd, szJunk, "CountVoiceNotes", MB_OK);
        break;

    case ID_SYNC:
        /* SyncAllVoices is really only effective with  */
        /* multivoice support. On standard machines this  */
        /* function is not successful.      */
        if (SyncAllVoices())
      MessageBox(hWnd, "SyncAllVoices successful.",
           "SyncAllVoices", MB_OK);
        else
      MessageBox(hWnd, "SyncAllVoices unsuccessful.",
           "SyncAllVoices", MB_OK);
        break;

    case ID_ENV:
        bEnv=!bEnv;
        if(bEnv)
      MessageBox(hWnd, "Envelope ON",
           "SetVoiceThreshold", MB_OK);
        else
      MessageBox(hWnd, "Envelope OFF",
           "SetVoiceThreshold", MB_OK);

        break;

    case ID_EVENT:
        /* Returns a pointer to an int      */
        sprintf(szJunk, "returns: %d", *(GetThresholdEvent()));
        MessageBox(hWnd, szJunk, "GetThresholdEvent", MB_OK);
        break;

    case ID_STATUS:
        /* GetThresholdStatus retrieves an int.  Each bit  */
        /* has the status for each voice.      */
        /* If a bit is set, the the threshold level for  */
        /* that voice has been reached.      */
        if (GetThresholdStatus())
      MessageBox(hWnd, "Threshold reached.",
           "GetThresholdStatus", MB_OK);
        else
      MessageBox(hWnd, "Threshold not reached.",
           "GetThresholdStatus", MB_OK);

        break;

    case ID_SETVT:
        /* Here a flag is toggled for NOTES and LUDWIG.  */
        bThresh=!bThresh;
        if(bThresh)
      MessageBox(hWnd, "Threshold ON",
           "SetVoiceThreshold", MB_OK);
        else
      MessageBox(hWnd, "Threshold OFF",
           "SetVoiceThreshold", MB_OK);
        break;
    }
  default:
      return (DefWindowProc(hWnd, iMessage, wParam, lParam));
  }
    return 0L;
    }


STJUST.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\STJUST.C

/*
Function(s) demonstrated in this program: SetTextJustification
Compiler version: 5.1
Description: This program removes leading spaces from the given string,
             counts the number of spaces left, removes and subtracts the
             trailing spaces, and then justifies the remaining string to
             zero and eighty.
*/

#include <windows.h>

long FAR PASCAL WndProc ( HWND, unsigned, WORD, LONG );
extern LPSTR FAR PASCAL lstrcpy ( LPSTR, LPSTR );
extern int   FAR PASCAL lstrlen ( LPSTR );
void Justify ( HDC );

static char szAppName [] = "STJUST" ;
static char szFuncName [] = "SetTextJustification" ;

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance;
HANDLE      hPrevInstance;
LPSTR       lpszCmdLine;
int         nCmdShow;
{
     HWND        hWnd;
     WNDCLASS    wndclass;
     MSG         msg;

     if (!hPrevInstance) {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWnd = CreateWindow (szAppName,            /* window class name       */
                    szFuncName,                 /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWnd, nCmdShow) ;
     UpdateWindow (hWnd) ;

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd;
unsigned iMessage;
WORD     wParam;
LONG     lParam;
{
   HDC         hDC;
   PAINTSTRUCT ps;

   switch(iMessage)
      {
      case WM_PAINT:
         hDC = BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
         Justify ( hDC );
         EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
         break;
      case WM_DESTROY:
         PostQuitMessage(0);
         break;
      default:
         return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
      }
   return (0L);
}

void Justify ( hDC )
HDC   hDC;
{
   TEXTMETRIC  tmText;
   DWORD       dwExtent;
   char        szJustifyString [80];
   int         nBreakCount;
   int         nElement;
   int         nIndex;

   lstrcpy ( (LPSTR)szJustifyString,
      (LPSTR)"    This string is justified between 0 and 80.   \0" );

   GetTextMetrics ( hDC, (LPTEXTMETRIC)&tmText );

   nBreakCount = 0;
   nElement = 0;

                                                 /* Removing leading spaces *
   while ( szJustifyString [ nElement ]  == ' ' &&
      szJustifyString [ nElement ] != '\0' )
      {
      for ( nIndex = 0; nIndex < lstrlen ( (LPSTR)szJustifyString );
       nIndex++ )
         szJustifyString [ nIndex ] = szJustifyString [ nIndex + 1 ];
      }

                                               /* Counting remaining spaces *
   do
      {
      while ( szJustifyString [ nElement ] != '\0' &&
         szJustifyString [ nElement++ ] != ' ');
      if ( szJustifyString [ nElement ] == '\0' )
         break;

      nBreakCount++;
                                          /* Clearing error out of dwExtent *
      SetTextJustification ( hDC, 0, 0 );
      dwExtent = GetTextExtent ( hDC, (LPSTR)szJustifyString,
         lstrlen ( (LPSTR)szJustifyString ) - 1 );
      }
   while ( LOWORD ( dwExtent ) < tmText.tmAveCharWidth * 80 );

                                                /* Removing trailing spaces *
   nBreakCount--;
   nElement = lstrlen ( (LPSTR)szJustifyString );
   while ( szJustifyString [ nElement ]  == ' ' && nElement != 0 )
      {
      nElement--;
      nBreakCount--;
      }
                                          /* Clearing error out of dwExtent *
   SetTextJustification ( hDC, 0, 0 );
                                        /* Justifing string szJustifyString *
   dwExtent = GetTextExtent ( hDC, (LPSTR)szJustifyString,
      lstrlen ( (LPSTR)szJustifyString ) - 1 );
   SetTextJustification ( hDC, tmText.tmAveCharWidth * 80 -
      (int)LOWORD ( dwExtent ), nBreakCount );

   TextOut ( hDC, 0 , 0 + (int)HIWORD ( dwExtent ), (LPSTR)szJustifyString,
      lstrlen ( (LPSTR)szJustifyString ) );
}


STMENU.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MENU\STMENU.C

/*
 *  Program Name:    stmenu.c
 *
 *  Description:
 *   The program below creates a menu and sets it in the window.
 *
 */

#include "windows.h"

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

/***********************************************************************/

void CALL_SetMenu(hWnd, hDC)
HWND hWnd;
HDC hDC;
{
  HMENU         hCurrentWindowMenu;
  unsigned      wIDItem;
  BOOL          bSet;

  hCurrentWindowMenu = CreateMenu();
  ChangeMenu (hCurrentWindowMenu, NULL, (LPSTR) "Heading", wIDItem,
              MF_APPEND | MF_BYCOMMAND | MF_STRING);

  bSet = SetMenu(hWnd, hCurrentWindowMenu);  /* menu set and displayed */

  if (bSet == FALSE)
    MessageBox(hWnd, (LPSTR)"SetMenu failed", (LPSTR)"ERROR", MB_ICONHAND);

  return;
}

/**************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = WndProc;
    wcClass.cbClsExtra     =0;
    wcClass.cbWndExtra     =0;
    wcClass.hInstance      = hInstance;
    wcClass.hIcon          = LoadIcon( hInstance,NULL );
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"SetMenu";

    if (!RegisterClass( (LPWNDCLASS)&wcClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;

    if (!hPrevInstance)
        {
        /* Call initialization procedure if this is the first instance */
        if (!WinInit( hInstance ))
            return FALSE;
        }

    hWnd = CreateWindow((LPSTR)"SetMenu",
                        (LPSTR)"SetMenu()",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0))
        {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/* Procedures which make up the window class. */
long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        CALL_SetMenu(hWnd, ps.hdc);
        ValidateRect(hWnd, (LPRECT) NULL);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


STSYSCOL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\STSYSCOL.C

/*
 * This program demonstrates the use of SetSysColor(). In this example,
 * the background desktop color of the current windows session is changed
 * to black. This change is not permanent. If the background is already
 * set to black, no change will be visible.
 */

#include <windows.h>

#define MAXCOLORS         13

DWORD lpColorValues[MAXCOLORS];
int lpSysColor[MAXCOLORS] = { COLOR_SCROLLBAR,
                              COLOR_BACKGROUND,
                              COLOR_ACTIVECAPTION,
                              COLOR_INACTIVECAPTION,
                              COLOR_MENU,
                              COLOR_WINDOW,
                              COLOR_WINDOWFRAME,
                              COLOR_MENUTEXT,
                              COLOR_WINDOWTEXT,
                              COLOR_CAPTIONTEXT,
                              COLOR_ACTIVEBORDER,
                              COLOR_INACTIVEBORDER,
                              COLOR_APPWORKSPACE };

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    nCmdShow;
{
   int         i;

   MessageBox(GetFocus(), (LPSTR)"Setting Background Color to Black.",
              (LPSTR)"SetSysColors()", MB_OK);

   for (i = 0; i < MAXCOLORS; i++)
      lpColorValues[i] = GetSysColor(lpSysColor[i]);

   lpColorValues[COLOR_BACKGROUND] = RGB(0, 0, 0);
   SetSysColors(MAXCOLORS, (int far *)lpSysColor, (long far *)lpColorValues);

   MessageBox(GetFocus(), (LPSTR)"Background Set For Current Session Only.",
              (LPSTR)"SetSysColors()", MB_OK);

   return(0);

}


STXTCHX.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TEXT\STXTCHX.C

/*
 * SetTextCharacterExtra
 * gtxtchx.c
 *
 * This program registers a window and creates it on the screen.  The
 *  program then creates the window, shows the window, and then updates
 *  the window.  If the user couble clicks the right mouse button, the
 *  SetTextCharacterExtra function is executed.  The intercharacter
 *  spacing is returned and displayed in a message box.
 *
 */

#include "windows.h"

/* Global Variables */
static HANDLE hInst;
static HWND hWnd;

/* FORWARD REFERENCES */
long FAR PASCAL WindowProc (HWND, unsigned, WORD, LONG);

/* WINMAIN */
int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
  MSG msg;

  if (!hPrevInstance)  {

     WNDCLASS rClass;

     rClass.lpszClassName = (LPSTR)"stxtchx";
     rClass.hInstance    = hInstance;
     rClass.lpfnWndProc   = WindowProc;
     rClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
     rClass.hIcon        = LoadIcon(hInstance, IDI_APPLICATION);
     rClass.lpszMenuName  = (LPSTR)NULL;
     rClass.hbrBackground = GetStockObject(WHITE_BRUSH);
     rClass.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
     rClass.cbClsExtra    = 0;       /* Add double click capabilities. */
     rClass.cbWndExtra    = 0;

     RegisterClass((LPWNDCLASS)&rClass);

     }
   else
      ;

   hInst = hInstance;

   hWnd = CreateWindow((LPSTR) "stxtchx",
           (LPSTR) "SetTextCharacterExtra", /* Create a window.         */
           WS_OVERLAPPEDWINDOW,             /* Make it overlapped.      */
           CW_USEDEFAULT,                   /* Use default coordinates. */
           CW_USEDEFAULT,                   /* Use default coordinates. */
           CW_USEDEFAULT,                   /* Use default coordinates. */
           CW_USEDEFAULT,                   /* Use default coordinates. */
           (HWND)NULL,
           (HMENU)NULL,
           (HANDLE)hInstance,
           (LPSTR)NULL
         );

   ShowWindow(hWnd, cmdShow);

   UpdateWindow(hWnd);

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

   exit(msg.wParam);

} /* WinMain */

/* WINDOWPROC */

long FAR PASCAL WindowProc(hWnd, identifier, wParam, lParam)
HWND  hWnd;
unsigned identifier;
WORD   wParam;
LONG   lParam;

{

   switch (identifier) {

     case WM_PAINT: {

         PAINTSTRUCT ps;
        RECT      rRect;
       HDC      hDC;

       hDC=BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       SetMapMode(hDC, MM_ANISOTROPIC);
       SetWindowOrg(hDC, 0, 0);
       SetWindowExt(hDC, 110, 110);
       GetClientRect(hWnd, (LPRECT)&rRect);
       SetViewportOrg(hDC, 0, 0);
       SetViewportExt(hDC, rRect.right, rRect.bottom);
       DrawText(hDC,
                (LPSTR)"Double Click Right Mouse Button To Set Intercharacter
                62, (LPRECT)&rRect, DT_SINGLELINE);  /* Place text to    */
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);          /* prompt for test. */

    }
      break;

     case WM_RBUTTONDBLCLK:                    /* If the user double    */
       {                                       /* clicks on the right   */
       char szbuf[80];   /* Output buffer       | mouse button, then    */
       short sIntSpacing; /* Interchar spacing. | variables and call    */
       short sOldIntSpacing; /* Old spacing.  */
       HDC hDC; /* Handle to display Context. */

       hDC = GetDC(hWnd);                      /* (after getting DC)    */
       sIntSpacing = GetTextCharacterExtra(hDC); /* GetTextCharacterExtra */
                                               /* (with the display     */
                                               /* context of the top    */
                                               /* level window.         */
      sprintf(szbuf,                          /* Capture the interchar */
          "%s%i%s\0",                          /* spacing information   */
          "Current Intercharacter Spacing = ", /* in a zero terminated  */
         (int)sIntSpacing, ".");              /* buffer.               */
      MessageBox(hWnd,                        /* Output the buffer in  */
                  (LPSTR)szbuf,                /* a message box format  */
                  (LPSTR)"SetTextCharacterExtra", /* so that the user   */
                 MB_OK);                      /* can have a readable   */
                                               /* and useful format.    */

       sOldIntSpacing = SetTextCharacterExtra(hDC, 10);
                                               /* Set the new spacing   */
                                               /* to 10.                */

       if (sIntSpacing != sOldIntSpacing)
          {                                    /* Issue error if fails. */
          MessageBox(hWnd, (LPSTR)"SetTextCharacterExtra Failed!!!",
                     (LPSTR)"ERROR!!!",
                     MB_OK | MB_ICONEXCLAMATION);
          break;
          };
                                               /* Output confirmation.  */
       MessageBox(hWnd, (LPSTR)"Set the Intercharacter Spacing to 10.",
                  (LPSTR)"Setting = 10",
                  MB_OK);
                                               /* Get new spacing.      */
       sIntSpacing = GetTextCharacterExtra(hDC);

       sprintf(szbuf,
          "%s%i%s\0",
          "New Intercharacter Spacing = ",
         (int)sIntSpacing, ".");
      MessageBox(hWnd,                        /* Show that Set worked. */
                  (LPSTR)szbuf,
                  (LPSTR)"SetTextCharacterExtra",
                 MB_OK);
       }
       break;

     case WM_CLOSE: {

        DestroyWindow(hWnd);
       }
     break;

    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    default:
      return(DefWindowProc(hWnd, identifier, wParam, lParam));
      break;

   }

   return(0L);

}


SWAPAREA.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\SWAPAREA.C

/*
Name               : swaparea.c
Date               : 07-05-88
Function(s)
demonstrated in
this program       : SetSwapAreaSize(), GlobalCompact().
Windows version    : 2.03
Compiler version   : 5.1
Description        : SetSwapAreaSize() increases the amount of memory that
                     an application uses for its code segment.  The memory
                     used for this application may not be allocated for
                     data.
*/

#include <windows.h>
#include "swaparea.h"

long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;
int sprintf(PSTR, PSTR, int);

static int ErrorCheck;
static char szResName [] = "ResMenu";

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "swaparea" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWnd = CreateWindow (szAppName,            /* window class name       */
                    "The Joy of Swapping",       /* window caption          *
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWnd, nCmdShow) ;

     UpdateWindow (hWnd) ;

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 static HANDLE hInstance;
 DWORD TotalFree;
 PAINTSTRUCT ps;
 char szBuf[50];
 HMENU hMenu;
 switch(iMessage)
 {
  case WM_CREATE:
  {
   hInstance = GetWindowWord(hWnd, GWW_HINSTANCE);
   hMenu = LoadMenu(hInstance, "ResMenu");
   SetMenu(hWnd, hMenu);
   DrawMenuBar(hWnd);
   break;
  }
  case WM_PAINT:
  {
   BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
   EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
   break;
  }
  case WM_COMMAND:
  {
   switch(wParam)
   {
    case IDM_EXECUTE:
    {
     /* Compact the memory to maximize the amount of free space, then
        allocate 1/2 the total available for this applications code
        segment.  This can only be done once.
     */
     TotalFree = (GlobalCompact(NULL)/(16*1024))/2;
     ErrorCheck = SetSwapAreaSize((WORD)TotalFree);
     sprintf(szBuf, "%i paragraphs that have been obtained for code segment u
     MessageBox(GetFocus(), szBuf, "There are", MB_OK);
    }
   }
   break;
  }
  case WM_DESTROY:
  {
   PostQuitMessage(0);
   break;
  }
  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}


SWAPBTN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MOUSE\SWAPBTN.C

/*
 *   SwapMouseButton
 *   swapbtn
 *
 *   This program demonstrates the use of the function SwapMouseButton.
 *   First, a message box opens and only the left mouse button will close
 *   it.  The functionality of the mouse buttons are switched using
 *   SetMouseButton and another message box is displayed.  This time only
 *   the right mouse button will close the message box.  The mouse buttons
 *   are finally reset before closing.
 *
 */

#include "windows.h"

/* Forward References */

BOOL FAR PASCAL SampleInit(HANDLE);

long FAR PASCAL SampleWndProc(HWND, unsigned, WORD, LONG);

/***************************************************************************/

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;

    SampleInit( hInstance );
    hWnd = CreateWindow((LPSTR)"SwapMouseButton",
      (LPSTR)"SwapMouseButton",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );
/************************************************************************/
/* Beginning of SwapMouseButton section */

MessageBox (hWnd, (LPSTR)"The functionality of the mouse buttons will be swit
            (LPSTR)"Done", MB_OK);

SwapMouseButton(FALSE);                  /* Initialize the mouse buttons */

MessageBox (hWnd, (LPSTR)"Only the left mouse button will close this message
            (LPSTR)"Done", MB_OK);

SwapMouseButton(TRUE);                   /* Switch the mouse buttons */

MessageBox (hWnd, (LPSTR)"Only the right mouse button will close this message
            (LPSTR)"Done", MB_OK);

SwapMouseButton(FALSE);                  /* Reset the mouse buttons */

MessageBox (hWnd, (LPSTR)"The mouse buttons are now reset.",
            (LPSTR)"Done", MB_OK);

/************************************************************************/

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}

/***************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL FAR PASCAL SampleInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pSampleClass;

    pSampleClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pSampleClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pSampleClass->hIcon          = LoadIcon( hInstance,NULL);
    pSampleClass->lpszMenuName   = (LPSTR)NULL;
    pSampleClass->lpszClassName  = (LPSTR)"SwapMouseButton";
    pSampleClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pSampleClass->hInstance      = hInstance;
    pSampleClass->style          = CS_HREDRAW | CS_VREDRAW;
    pSampleClass->lpfnWndProc    = SampleWndProc;

    if (!RegisterClass( (LPWNDCLASS)pSampleClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pSampleClass );
    return TRUE;        /* Initialization succeeded */
}


/**************************************************************************/
/* Every message for this window will be delevered right here.         */

long FAR PASCAL SampleWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message)
    {
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


TEXTALGN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\TEXTALGN.C

/*
 * This application demonstrates the GetTextAlign() and SetTextAlign()
 * Windows functions. This program is a subset of the SHOWFONT learning
 * guide application. See that program for a more comprehensive example.
 *
 * In this application, a vertical and/or horizontal alignment is
 * selected via the "Options..." menu (or the defaults are used),
 * and the left mouse button is clicked in the client area of this
 * demo application.
 *
 */

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

/* Function Prototypes */

void SetMyDC(HDC);
short StringOut(HDC, short, short, PSTR, HFONT);
void ShowString(HWND);
long FAR PASCAL TextAlgnWndProc(HWND, unsigned, WORD, LONG);

HANDLE  hInst;
HFONT   hSFont, hFont;
char    line[4][64];
LOGFONT LogFont;
POINT   ptCurrent = {0, 0};
short   nBkMode = OPAQUE;
DWORD   rgbBkColor = RGB(255, 255, 255);
DWORD   rgbTextColor = RGB(0, 0, 0);
short   nAlignLCR = TA_LEFT;
short   nAlignTBB = TA_TOP;
WORD    wPrevVAlign = IDM_ALIGNBASE;
WORD    wPrevHAlign = IDM_ALIGNLEFT;
char    AppName[] = "Get/SetTextAlign() Demo";
char    WindowTitle[80];


int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;
HANDLE hPrevInstance;
LPSTR  lpCmdLine;
int    nCmdShow;
{
    HWND hWnd;
    PWNDCLASS pWndClass;
    MSG msg;

    if (!hPrevInstance) {
       pWndClass->hCursor       = LoadCursor(NULL, IDC_ARROW);
       pWndClass->hIcon         = NULL;
       pWndClass->lpszMenuName  = (LPSTR) "TextAlgn";
       pWndClass->lpszClassName = (LPSTR) "TextAlgn";
       pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
       pWndClass->hInstance     = hInstance;
       pWndClass->style         = NULL;
       pWndClass->lpfnWndProc   = TextAlgnWndProc;
       RegisterClass((LPWNDCLASS) pWndClass);
       }

    hInst = hInstance;

    hWnd = CreateWindow((LPSTR)"TextAlgn",
                        (LPSTR)"TextAlgn",
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        NULL,
                        NULL,
                        hInstance,
                        NULL);

    if (!hWnd)
        return (FALSE);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    while (GetMessage(&msg, NULL, NULL, NULL)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return (msg.wParam);
}


/****************************************************************************

    FUNCTION: SetMyDC(HDC)

    PURPOSE: Initializes the DC

****************************************************************************/

void SetMyDC(hDC)
HDC hDC;
{
    SetBkMode(hDC, nBkMode);
    SetBkColor(hDC, rgbBkColor);
    SetTextColor(hDC, rgbTextColor);
    SetTextAlign(hDC, nAlignLCR | nAlignTBB);
}

/****************************************************************************

    FUNCTION: StringOut(HDC, short, short, PSTR, HFONT)

    PURPOSE: Outputs a string to application's window

****************************************************************************/

short StringOut(hDC, X, Y, pString, hFont)
HDC   hDC;
short X;
short Y;
PSTR  pString;
HFONT hFont;
{
    HFONT hOldFont;
    DWORD dwExtent;

    hOldFont = SelectObject(hDC, hFont);
    if (hOldFont != NULL) {
        dwExtent = GetTextExtent(hDC, pString, strlen(pString));
        TextOut(hDC, X, Y, pString, strlen(pString));
        SelectObject(hDC, hOldFont);
    }
    return (LOWORD(dwExtent));
}

/****************************************************************************

    FUNCTION: ShowString(HWND)

    PURPOSE: Show string in current font

****************************************************************************/

void ShowString(hWnd)
HWND hWnd;
{
    HFONT hItalicFont;
    HFONT hBoldFont;
    HFONT hUnderlineFont;
    HFONT hStrikeOutFont;
    HDC   hDC;
    short X, tmpX;
    short Y;
    short nAlign;

    GetObject(hFont, sizeof(LOGFONT), (LPSTR) &LogFont);
    LogFont.lfItalic    = TRUE;
    hItalicFont         = CreateFontIndirect(&LogFont);
    LogFont.lfItalic    = FALSE;
    LogFont.lfUnderline = TRUE;
    hUnderlineFont      = CreateFontIndirect(&LogFont);
    LogFont.lfUnderline = FALSE;
    LogFont.lfStrikeOut = TRUE;
    hStrikeOutFont      = CreateFontIndirect(&LogFont);
    LogFont.lfStrikeOut = FALSE;
    LogFont.lfWeight    = FW_BOLD;
    hBoldFont           = CreateFontIndirect(&LogFont);

    hDC = GetDC(hWnd);
    SetMyDC(hDC);
    X = ptCurrent.x;
    Y = ptCurrent.y;
    nAlign = nAlignLCR | nAlignTBB;                 /* GetTextAlign(hDC); */
    if ((nAlign & TA_CENTER) == TA_CENTER) {
        tmpX = X;
        nAlignLCR = TA_LEFT;
        SetTextAlign(hDC, nAlignLCR | nAlignTBB);
        X += StringOut(hDC, X, Y, ", and ", hFont);
        X += StringOut(hDC, X, Y, "strikeout", hStrikeOutFont);
        X += StringOut(hDC, X, Y, " in a single line.", hFont);
        X = tmpX;
        nAlignLCR = TA_RIGHT;
        SetTextAlign(hDC, nAlignLCR | nAlignTBB);
        X -= StringOut(hDC, X, Y, "underline", hUnderlineFont);
        X -= StringOut(hDC, X, Y, ", ", hFont);
        X -= StringOut(hDC, X, Y, "italic", hItalicFont);
        X -= StringOut(hDC, X, Y, ", ", hFont);
        X -= StringOut(hDC, X, Y, "bold", hBoldFont);
        X -= StringOut(hDC, X, Y, "You can use ", hFont);
        nAlignLCR = TA_CENTER;
    }
    else if ((nAlign & TA_CENTER) == TA_RIGHT) {
        X -= StringOut(hDC, X, Y, " in a single line.", hFont);
        X -= StringOut(hDC, X, Y, "strikeout", hStrikeOutFont);
        X -= StringOut(hDC, X, Y, ", and ", hFont);
        X -= StringOut(hDC, X, Y, "underline", hUnderlineFont);
        X -= StringOut(hDC, X, Y, ", ", hFont);
        X -= StringOut(hDC, X, Y, "italic", hItalicFont);
        X -= StringOut(hDC, X, Y, ", ", hFont);
        X -= StringOut(hDC, X, Y, "bold", hBoldFont);
        X -= StringOut(hDC, X, Y, "You can use ", hFont);
    }
    else  {
        X += StringOut(hDC, X, Y, "You can use ", hFont);
        X += StringOut(hDC, X, Y, "bold", hBoldFont);
        X += StringOut(hDC, X, Y, ", ", hFont);
        X += StringOut(hDC, X, Y, "italic", hItalicFont);
        X += StringOut(hDC, X, Y, ", ", hFont);
        X += StringOut(hDC, X, Y, "underline", hUnderlineFont);
        X += StringOut(hDC, X, Y, ", and ", hFont);
        X += StringOut(hDC, X, Y, "strikeout", hStrikeOutFont);
        X += StringOut(hDC, X, Y, " in a single line.", hFont);
    }
    ReleaseDC(hWnd, hDC);

    DeleteObject(hItalicFont);
    DeleteObject(hUnderlineFont);
    DeleteObject(hStrikeOutFont);
    DeleteObject(hBoldFont);
}

/****************************************************************************

    FUNCTION: TextAlgnWndProc(HWND, unsigned, WORD, LONG)

    PURPOSE: Processes messages

****************************************************************************/

long FAR PASCAL TextAlgnWndProc(hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
{
    HDC         hDC;
    PAINTSTRUCT ps;
    int         i;

    switch(message) {
        case WM_CREATE:
            hSFont = GetStockObject(SYSTEM_FONT);
            hFont  = hSFont;
            GetObject(hFont, sizeof(LOGFONT), (LPSTR) &LogFont);

            for (i=0; i<64; i++) {
                line[0][i] = (char)i;
                line[1][i] = (char)i+64;
                line[2][i] = (char)i+128;
                line[3][i] = (char)i+192;
            }
            break;

        case WM_PAINT:
            hDC = BeginPaint(hWnd, &ps);
            SetMyDC(hDC);
            EndPaint(hWnd, &ps);
            break;

        case WM_COMMAND:
            switch (wParam) {
                case IDM_CLEAR:
                    InvalidateRect(hWnd, (LPRECT)NULL, TRUE);
                    break;

                case IDM_ALIGNLEFT:
                    nAlignLCR = TA_LEFT;
                    CheckMenuItem(GetMenu(hWnd), wPrevHAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevHAlign = wParam;
                    break;

                case IDM_ALIGNCENTER:
                    nAlignLCR = TA_CENTER;
                    CheckMenuItem(GetMenu(hWnd), wPrevHAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevHAlign = wParam;
                    break;

                case IDM_ALIGNRIGHT:
                    nAlignLCR = TA_RIGHT;
                    CheckMenuItem(GetMenu(hWnd), wPrevHAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevHAlign = wParam;
                    break;

                case IDM_ALIGNTOP:
                    nAlignTBB = TA_TOP;
                    CheckMenuItem(GetMenu(hWnd), wPrevVAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevVAlign = wParam;
                    break;

                case IDM_ALIGNBASE:
                    nAlignTBB = TA_BASELINE;
                    CheckMenuItem(GetMenu(hWnd), wPrevVAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevVAlign = wParam;
                    break;

                case IDM_ALIGNBOTTOM:
                    nAlignTBB = TA_BOTTOM;
                    CheckMenuItem(GetMenu(hWnd), wPrevVAlign, MF_UNCHECKED);
                    CheckMenuItem(GetMenu(hWnd), wParam, MF_CHECKED);
                    wPrevVAlign = wParam;
                    break;
            }
            break;

        case WM_LBUTTONUP:
            ptCurrent.x = LOWORD(lParam);
            ptCurrent.y = HIWORD(lParam);
            ShowString(hWnd);
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (0L);
}


TEXTCOL.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TEXT\TEXTCOL.C

/*
 *  SetTextColor
 *  TEXTCOL.C,
 *
 *  This program demonstrates the use of the function SetTextColor.
 *  SetTextColor changes the color of future text output.
 *  This program gets a DC and outputs black text on a white backround.
 *  Next the text backround is changed to black.  The text is changed to
 *  white using the function SetTextColor.  Finally, the white text is
 *  output to the screen.
 *
 */

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

char  *szMessage = "This is the text color before invoking SetTextColor.";
char  *szWhite = "The text color is now white.";

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  HWND       hWnd;
  HDC        hDC;
  DWORD      rgbcolor;
  DWORD      dwblack = RGB (0x00, 0x00, 0x00);
  DWORD      dwwhite = RGB (0xff, 0xff, 0xff);
  WNDCLASS   Class;

  Class.hCursor        = LoadCursor (NULL, IDC_ARROW);
  Class.lpszMenuName   = (LPSTR)NULL;
  Class.lpszClassName  = (LPSTR)"Window";
  Class.hbrBackground  = (HBRUSH)GetStockObject (BLACK_BRUSH);
  Class.hInstance      = hInstance;
  Class.style          = CS_HREDRAW | CS_VREDRAW;
  Class.lpfnWndProc    = DefWindowProc;

  if (!RegisterClass ( (LPWNDCLASS)&Class))
    return FALSE;

  hWnd = CreateWindow ( (LPSTR)"Window",
                      (LPSTR)"SetTextColor",
                      WS_TILEDWINDOW,
                      20, 20, 400, 200,
                      (HWND)NULL,        /* no parent */
                      (HMENU)NULL,       /* use class menu */
                      (HANDLE)hInstance, /* handle to window instance */
                      (LPSTR)NULL);      /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  hDC = GetDC (hWnd);

  TextOut (hDC, 0, 0, (LPSTR)szMessage, strlen (szMessage));

  SetBkColor (hDC, dwblack);

  rgbcolor = SetTextColor (hDC, dwwhite);

  TextOut (hDC, 0, 15, (LPSTR)szWhite, strlen (szWhite));
  ReleaseDC (hWnd, hDC);

  MessageBox (GetFocus (), (LPSTR)"Program Finished",
      (LPSTR)"SetTextColor", MB_OK);

  return 0;
  }


TEXTOUT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TEXT\TEXTOUT.C

/*
 *  TextOut
 *  textout.c
 *
 *  This Program outputs text to the upper left hand corner of the client
 *  area using the TextOut function. The TextOut function outputs a character
 *  string on the specified display, using the currently selected font.
 *  The starting position of the string is given by the X and Y parameters.
 *
 */

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

char  *szTextOutMsg = "The TextOut function wrote this text.";


int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
  {
  HWND  hWnd;         /* Handle to the parent window */
  HDC   hDC;          /* Display context of client area */
  BOOL  flag;         /* Return value for TextOut function*/
  WNDCLASS   Class;

  Class.hCursor        = LoadCursor (NULL, IDC_ARROW);
  Class.lpszMenuName   = (LPSTR)NULL;
  Class.lpszClassName  = (LPSTR)"Window";
  Class.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  Class.hInstance      = hInstance;
  Class.style          = CS_HREDRAW | CS_VREDRAW;
  Class.lpfnWndProc    = DefWindowProc;

  if (!RegisterClass ( (LPWNDCLASS)&Class))
    return FALSE;

  hWnd = CreateWindow ( (LPSTR)"Window",
                      (LPSTR)"TextOut",
                      WS_TILEDWINDOW,
                      20, 20, 400, 200,
                      (HWND)NULL,
                      (HMENU)NULL,
                      (HANDLE)hInstance,
                      (LPSTR)NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  hDC = GetDC (hWnd);

  flag = TextOut (hDC, 0, 0, (LPSTR)szTextOutMsg, strlen (szTextOutMsg));

  ReleaseDC (hWnd, hDC);

  if (flag == TRUE)
    MessageBox (hWnd, (LPSTR)"The TextOut fuction returns TRUE",
        (LPSTR)"Done", MB_OK);
  return 0;
  }


TRANSACC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\ACCELL\TRANSACC.C

/*
 *  TranslateAccelerator
 *  transacc.c
 *
 * This program demonstrates the use of the function TranslateAccelerator.
 * When the function keys F9 or F10 are pressed then a message box appears
 * which notifies the user that the TranslateAccelerator function has
 * successfully converted and dispatched an accelerator message.
 *
 * All messages to this application are first passed to the
 * TranslateAccelerator function.  TranslateAccelerator will compare
 * the message to a predefined accelerator to see if they match.  If
 * the message doesn't match then TranslateAccelerator returns a 0,
 * and the message will be processed normally using TranslateMessage
 * and DispatchMessage.  If they do match, the message is an accelerator,
 * and the routine translates the message into a WM_COMMAND or
 * WM_SYSCOMMAND message.
 */

#include <windows.h>
#include "transacc.h"

static HANDLE hInst;

int     PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE    hInstance, hPrevInstance;
LPSTR     lpszCmdLine;
int       cmdShow;
  {
  MSG       msg;
  HWND      hWnd;
  BOOL      bDecrementDisplayCount = 0;
  BOOL      bIncrementDisplayCount = 1;
  short     nResult;
  WNDCLASS  Class;

  Class.lpfnWndProc    = TransAccelWindowProc;
  Class.hCursor        = LoadCursor (NULL, IDC_ARROW);
  Class.lpszMenuName   = MAKEINTRESOURCE (TRANSACCELMENU1);
  Class.lpszClassName  = (LPSTR)"Window";
  Class.hbrBackground  = (HBRUSH)GetStockObject (WHITE_BRUSH);
  Class.hInstance      = hInstance;
  Class.style          = CS_HREDRAW | CS_VREDRAW;

  if (!RegisterClass ( (LPWNDCLASS)&Class))
    return FALSE;

  hInst = hInstance;

  hWnd = CreateWindow ( (LPSTR)"Window",
                     (LPSTR)"ShowCaret",
                     WS_OVERLAPPEDWINDOW,
                     CW_USEDEFAULT,          /* x         */
                     CW_USEDEFAULT,          /* y         */
                     CW_USEDEFAULT,          /* width     */
                     CW_USEDEFAULT,          /* height    */
                     (HWND)NULL,             /* no parent */
                     (HMENU)NULL,            /* use class menu */
                     (HANDLE)hInstance,      /* handle to window instance */
                     (LPSTR)NULL);           /* no params to pass on */

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  while (GetMessage ( (LPMSG) & msg, NULL, 0, 0))
    if (TranslateAccelerator (msg.hwnd, LoadAccelerators (hInstance,
        MAKEINTRESOURCE (TRANSACCELMENU1)), (LPMSG) & msg) == 1)
      MessageBox (hWnd, (LPSTR)"TranslateAccelerator processed a message",
          (LPSTR)"Done", MB_OK);
    else
      {
      TranslateMessage ( (LPMSG) & msg);
      DispatchMessage ( (LPMSG) & msg);
      }

  return TRUE;
  }

long    FAR PASCAL TransAccelWindowProc (hWnd, message, wParam, lParam)
HWND     hWnd;
unsigned message;
WORD     wParam;
LONG     lParam;
  {
  switch (message)
    {
    case WM_COMMAND:
      TransAccelMenuProc (hWnd, wParam);
      break;

    default:
      return (DefWindowProc (hWnd, message, wParam, lParam));
      break;
    }
  return (0L);
  }

void TransAccelMenuProc (hWnd, wId)
HWND hWnd;
WORD wId;
  {
  HMENU hMenu;

  switch (wId)
    {
    case ID_NEXT:
      hMenu = GetMenu (hWnd);  /*  Get the old menu  */
      DestroyMenu (hMenu);     /*  Get rid of it  */
      hMenu = LoadMenu (hInst, MAKEINTRESOURCE (TRANSACCELMENU2));
      SetMenu (hWnd, hMenu);
      DrawMenuBar (hWnd);
      break;

    case ID_PREV:
      hMenu = GetMenu (hWnd);  /*  Get the old menu  */
      DestroyMenu (hMenu);     /*  Get rid of it  */
      hMenu = LoadMenu (hInst, MAKEINTRESOURCE (TRANSACCELMENU1));
      SetMenu (hWnd, hMenu);
      DrawMenuBar (hWnd);
      break;
    }
  }


TRNCOMCH.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\TRNCOMCH.C

/*
 *  TransmitCommChar
 *  trncomch.c
 *
 *  This program demonstrates the use of the function TransmitCommChar.
 *  It puts the specified character at the header of the transmit queue
 *  of the communication device for immediate transmission.
 *
 *  Note: Depending on how com1 is set up, this may have unusual side
 *  effects.
 *
 */

#include <windows.h>
#include <stdio.h>

int  PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  cmdShow;
{
  HWND  hWnd;
  short  nCid;            /* identifer for open com device */
  short  nFlag;           /* Result of the TransmitCommChar function */
  DCB   dcb;             /* The device control block */
  BYTE  nChar;           /* Byte value of the char transmitted */
  char  szBuffer[40];
  WNDCLASS   wcClass;

  wcClass.hCursor        = LoadCursor (NULL, IDC_ARROW);
  wcClass.hIcon          = LoadIcon (hInstance, "WindowIcon");
  wcClass.lpszMenuName   = NULL;
  wcClass.lpszClassName  = "Trncomch";
  wcClass.hbrBackground  = GetStockObject (WHITE_BRUSH);
  wcClass.hInstance      = hInstance;
  wcClass.style          = CS_HREDRAW | CS_VREDRAW;
  wcClass.lpfnWndProc    = DefWindowProc;
  wcClass.cbClsExtra     = 0;
  wcClass.cbWndExtra     = 0;

  RegisterClass ( (LPWNDCLASS) & wcClass);

  hWnd = CreateWindow ("Trncomch", "Transmitting Characters",
      WS_OVERLAPPEDWINDOW, 50, 50, 600, 250,
      NULL, NULL, hInstance, NULL);

  ShowWindow (hWnd, cmdShow);
  UpdateWindow (hWnd);

  nCid = OpenComm ("COM1", 20, 20);

  if (nCid < 0)
  {
    MessageBox (hWnd, "Com port not opened!!", "OpenComm", MB_OK);
    return 0;
  }

/* set the device control block of the communication device */
  if (GetCommState (nCid, (DCB FAR * ) & dcb) >= 0)
  {
    dcb.BaudRate = 9600;
    dcb.ByteSize = 8;
    dcb.StopBits = ONESTOPBIT;
    dcb.Parity   = NOPARITY;
    dcb.fRtsflow = FALSE;
    dcb.fDtrflow = FALSE;
    dcb.fOutX    = FALSE;
    dcb.fInX     = FALSE;
    dcb.fNull    = FALSE;
    dcb.XonLim   = 1;
    dcb.XoffLim  = 20;
  }

  SetCommState ( (DCB FAR * ) & dcb);

  MessageBox (hWnd, "Ready to transmit char", "Ready?", MB_OK);

/* Sending the alphabets over to a dumb terminal immediately. nFlag
   * is negative if the character cannot be transmitted.
   */
  for (nChar = 65; nChar <= 90; nChar++)
  {
    nFlag = TransmitCommChar (nCid, nChar);
    if (!nFlag)
    {
      sprintf (szBuffer, "Character %c transmitted", nChar);
      MessageBox (hWnd, szBuffer, "OK", MB_OK);
    }
    else
    {
      sprintf (szBuffer, "Character %c not transmitted", nChar);
      MessageBox (hWnd, szBuffer, "FAIL", MB_OK);
    }
  }

/* must close the communication device before leaving the program */
  CloseComm (nCid);
  return 0;
}




TRNSLTMG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\TRNSLTMG.C

/*
 *   TranslateMessage
 *   trnsltmg.c
 *
 *   This program demonstrates the function TranslateMessage.  A virtual-
 *   keystroke message is translated into an ascii character message and
 *   posted to the application queue, to be read the next time the
 *   application calls the GetMessage function.  The character is finally
 *   displayed on the screen.  This sequence is repeated until a
 *   WM_DESTROY message is received (the window is closed by the user).
 *
 *   After testing this program, try removing the TranslateMessage function.
 *   You will find that the keyboard will appear dead.  None of the
 *   virtual-keystroke messages are translated into character messages.
 *   Mouse input will still be available even Without TranslateMessage.
 *
 */

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

#define FIRST_ASCII_CHAR  0
#define LAST_ASCII_CHAR   127

/* Forward references */

int  PASCAL      WinMain(HANDLE, HANDLE, LPSTR, int);
BOOL            TranslateMsgInit(HANDLE);
void PASCAL     PaintCharacter(HWND);
long  FAR PASCAL TranslateMsgWndProc(HWND, unsigned, WORD, LONG);

BYTE chAsciiChar = 255;             /* Current keyboard character */

int  PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, CmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  CmdShow;
{
  MSG    msg;
  HANDLE hInst;
  HWND   hWnd;
  BOOL   bInit;

  if (!hPrevInstance)
    bInit = TranslateMsgInit(hInstance);

  hInst = hInstance;

  hWnd = CreateWindow((LPSTR)"TranslateMessage",
      (LPSTR)"TranslateMessage",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
  );

/* Make window visible */
  ShowWindow(hWnd, CmdShow);
  UpdateWindow(hWnd);

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }

  return (int)msg.wParam;
}


/* Procedure called when the application is loaded for the first time */
BOOL TranslateMsgInit(hInstance)
HANDLE hInstance;
{
  WNDCLASS   rTranslateMsgClass;

  rTranslateMsgClass.hCursor        = LoadCursor(NULL, IDC_ARROW );
  rTranslateMsgClass.hIcon          = LoadIcon(hInstance, NULL);
  rTranslateMsgClass.lpszMenuName   = (LPSTR)NULL;
  rTranslateMsgClass.lpszClassName  = (LPSTR)"TranslateMessage";
  rTranslateMsgClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
  rTranslateMsgClass.hInstance      = hInstance;
  rTranslateMsgClass.style          = CS_HREDRAW | CS_VREDRAW;
  rTranslateMsgClass.lpfnWndProc    = TranslateMsgWndProc;

  if (!RegisterClass((LPWNDCLASS) & rTranslateMsgClass))
/* Initialization failed.
     * Windows will automatically deallocate all allocated memory.
     */
    return FALSE;

  return TRUE;        /* Initialization succeeded */
}


/* Every message for this window will be delevered right here.         */
long  FAR PASCAL TranslateMsgWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  switch (message)
  {
  case WM_PAINT:
    PaintCharacter(hWnd);
    break;
  case WM_CHAR:
/* The value of the key is stored in the low order byte of wParam */
    chAsciiChar = LOBYTE(wParam);
    InvalidateRect(hWnd, (LPRECT)NULL, TRUE);
    break;
  case WM_DESTROY:
    PostQuitMessage(0);
    break;
  }
  return(0L);
}


void PASCAL PaintCharacter(hWnd)
HWND hWnd;
{
  PAINTSTRUCT ps;
  HDC         hDC;
  char  szOutBuff [80];

  hDC = BeginPaint(hWnd, (LPPAINTSTRUCT) & ps);

  if ((chAsciiChar >= FIRST_ASCII_CHAR) && (chAsciiChar <= LAST_ASCII_CHAR))
  {
    sprintf(szOutBuff, "The '%c' key was pressed.",  chAsciiChar);
    TextOut(hDC, 30, 30, (LPSTR)szOutBuff, strlen(szOutBuff));
  }
  else
    TextOut(hDC, 30, 30, (LPSTR)"Please press a key", 18);
  EndPaint(hWnd, (LPPAINTSTRUCT) & ps);
}




TTY.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TTY\TTY.C

/*  TTY.c
    a very simple sample terminal application. It demonstrates
    the basics in the use of the Windows Comm functions. It also
    shows the basic structure for a terminal program.
    Currently, there are a number of things that are hard coded,
    which could be made settable in a dialog box. These can be
    found in the Terminal data section below. They are things like
    the background and text colors, the background brush, and the
    font to be used. Also, the baud rate and other communication
    settings are hard coded. You can experiment with different
    settings, or change them just to match your available serial
    connection.

    Microsoft makes no claims to the correctness or operation of
    this code. It is provided for example and learning purposes
    only.

    Copyright (c) Microsoft 1985,1986,1987,1988,1989 */

#include "windows.h"
#include "TTY.h"

char szAppName[10];
char szAbout[10];
char szMessage[15];
int MessageLength;

/* Terminal data */
typedef char cpt[2];      // point array of char sized values

#define cpX 0
#define cpY 1

#define PortSetting  "com1"
#define CommSettings "com1:96,n,8,1"
#define BufMax 160
HWND hTTYWnd;
char MsgBuff[BufMax + 1];   // Buffer to hold incoming characters
char sScrBuff[25][81];      // Array of characters on TTY
char cLastLine;       // Index of last line on TTY in the array
char cCurrPos;        // Current TTY output position
BOOL bConnected;      // Flag to indicate if connected
int TTYCharWidth, TTYCharHeight;    // width and height of TTY font chars
DCB CommDCB;        // DCB for comm port
COMSTAT CommStat;      // COMSTAT info buffer for comm port

DWORD TTYbkRGB = RGB(0,0,0);    // background color
DWORD TTYtextRGB = RGB(255,255,255);  // text color
#define TTY_BRUSH BLACK_BRUSH    // background brush
#define TTY_FONT DEVICEDEFAULT_FONT  // font used for display

char sTemp[256];
HFONT hOldFont;

static HANDLE hInst;
FARPROC lpprocAbout;

long FAR PASCAL TTYWndProc(HWND, unsigned, WORD, LONG);

BOOL FAR PASCAL About( hDlg, message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    if (message == WM_COMMAND
  || message == WM_LBUTTONDOWN) {
        EndDialog( hDlg, TRUE );
        return TRUE;
        }
    else if (message == WM_INITDIALOG)
        return TRUE;
    else return FALSE;
}

SetupTTYDC(HWND hWnd, HDC hDC)
{
    RECT rClRect;

    hOldFont = SelectObject(hDC,GetStockObject(TTY_FONT));
    GetClientRect(hWnd,&rClRect);
    SetViewportOrg(hDC,0,rClRect.bottom-TTYCharHeight*25);
    SetTextColor(hDC,TTYtextRGB);
    SetBkColor(hDC,TTYbkRGB);
    SetBkMode(hDC,OPAQUE);

}

ResetTTYDC(HWND hWnd, HDC hDC)
{
    SelectObject(hDC,hOldFont);
}

char *GetTTYLine(char ndx)    // get ptr to text for give line
{
    char pos;

    pos = cLastLine + ndx + 1;
    pos = pos > 24 ? (pos % 24)-1 : pos;
    return(sScrBuff[pos]);
}

POINT TTYScrPos(char X, char Y)   // get window pos from TTY pos
{
    POINT ScrPos;

    ScrPos.x = X * TTYCharWidth;
    ScrPos.y = Y * TTYCharHeight;
    return(ScrPos);
}

// process incoming text to tty window - simulate tty actions
void putTTY(HWND hWnd, HDC hDC, WORD wParam, LPSTR lParam)
{
    short i,j;
    POINT ptTTYPos;
    char *sBuffer;
    char len = 0;
    RECT rClRect;
    char *psLine;
    short iLinesOut = 0;

    sBuffer = &sScrBuff[cLastLine][cCurrPos];

    for(i=0;i<wParam;i++){
  switch(lParam[i]) {

  case '\r': // return
      // move to the start of the line
      cCurrPos = 0;
      len = 0;

      break;

  case '\b': // backspace

      // (ok, so most of this should be a function since it is
      //    repeated later)
      // Note: it is easier to go ahead and display the text
      //  up to this point for things such as backspace. This
      //  will apply to other things, like arrow keys, tabs, etc.

      // scroll screen by number of lines received
      if(iLinesOut > 0) {
    // scroll iLinesOut lines
    ScrollWindow(hWnd,0,-(TTYCharHeight * iLinesOut),NULL,NULL);
    rClRect.top = TTYCharHeight * (24 - iLinesOut);
    rClRect.bottom = TTYCharHeight*25;
    rClRect.left = 0;
    rClRect.right = TTYCharWidth * 80;
    FillRect(hDC,&rClRect,GetStockObject(TTY_BRUSH));

      }

      // display lines in scrolled area previous to current line
      for(j = 1;j<=iLinesOut;j++) {
    // TextOut line cLastLine - j;
    psLine = GetTTYLine(24 - j);
    ptTTYPos = TTYScrPos(0,24 - j);
    TextOut(hDC,
      ptTTYPos.x,
      ptTTYPos.y,
      psLine,
      strlen(psLine));

      }
      iLinesOut = 0;

      if(len > 0){
    // display current line
    ptTTYPos = TTYScrPos(cCurrPos,24);
    TextOut(hDC,
        ptTTYPos.x,
        ptTTYPos.y,
        sBuffer,
        len);
    cCurrPos += len;
      }
      len = 0;

      // move back one space
      if(cCurrPos > 0) {
    --cCurrPos;
    ptTTYPos = TTYScrPos(cCurrPos,24);
    TextOut(hDC,
        ptTTYPos.x,
        ptTTYPos.y,
        " ",
        1);
      }
      break;

  case '\n': // new line

      // "scroll" the window
      ++iLinesOut; // increment lines to scroll
      ++cLastLine;
      if(cLastLine > 24) cLastLine = 0;

      // clear the new line
      sBuffer = &sScrBuff[cLastLine][0];
      for(j=0;j<80;j++) sBuffer[j] = '\0';
      len = 0;

      break;

  default:
      //add char to buffer
      if(cCurrPos < 80){
    sBuffer[len] = lParam[i];
    ++len;
      }
      break;
  }
    }

    // scroll screen by number of lines received
    if(iLinesOut > 0) {
  // scroll iLinesOut lines
  ScrollWindow(hWnd,0,-(TTYCharHeight * iLinesOut),NULL,NULL);
  rClRect.top = TTYCharHeight * (24 - iLinesOut);
  rClRect.bottom = TTYCharHeight*25;
  rClRect.left = 0;
  rClRect.right = TTYCharWidth * 80;
  FillRect(hDC,&rClRect,GetStockObject(TTY_BRUSH));

    }

    // display lines in scrolled area previous to current line
    for(j = 1;j<=iLinesOut;j++) {
  // TextOut line cLastLine - j;
  psLine = GetTTYLine(24 - j);
  ptTTYPos = TTYScrPos(0,24 - j);
  TextOut(hDC,
    ptTTYPos.x,
    ptTTYPos.y,
    psLine,
    strlen(psLine));

    }

    if(len > 0){
  // display current line
  ptTTYPos = TTYScrPos(cCurrPos,24);
  TextOut(hDC,
      ptTTYPos.x,
      ptTTYPos.y,
      sBuffer,
      len);
  cCurrPos += len;
    }
}


void TTYPaint(HDC hDC )    // repaint the text in the tty
{
    char *psLine;
    POINT ptTTYPos;
    register int i;

    for(i=0;i<25;i++){
  psLine = GetTTYLine(i);
  ptTTYPos = TTYScrPos(0,i);
  TextOut(hDC,
    ptTTYPos.x,
    ptTTYPos.y,
    psLine,
    strlen(psLine));
    }
}


/* Procedure called when the application is loaded for the first time */
BOOL TTYInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS  pTTYClass;

    /* Load strings from resource */
    LoadString( hInstance, IDSNAME, (LPSTR)szAppName, 10 );
    LoadString( hInstance, IDSABOUT, (LPSTR)szAbout, 10 );
    MessageLength = LoadString( hInstance, IDSTITLE, (LPSTR)szMessage, 15 );

    pTTYClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pTTYClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pTTYClass->hIcon        = LoadIcon( hInstance, MAKEINTRESOURCE(TTYICON) )
    pTTYClass->lpszMenuName   = (LPSTR)"TTYMENU";
    pTTYClass->lpszClassName  = (LPSTR)szAppName;
    pTTYClass->hbrBackground  = (HBRUSH)GetStockObject( TTY_BRUSH );
    pTTYClass->hInstance      = hInstance;
    pTTYClass->style        = CS_HREDRAW | CS_VREDRAW | CS_OWNDC
        | CS_BYTEALIGNCLIENT;
    pTTYClass->lpfnWndProc    = TTYWndProc;

    if (!RegisterClass( (LPWNDCLASS)pTTYClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pTTYClass );
    return TRUE;        /* Initialization succeeded */
}


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HMENU hMenu;
    RECT rClRect, rWndRect;
    short iXExtra,iYExtra;
    short iNumRead,iError;

    if (!hPrevInstance) {
        /* Call initialization procedure if this is the first instance */
  if (!TTYInit( hInstance ))
            return FALSE;
        }
    else {
        /* Copy data from previous instance */
        GetInstanceData( hPrevInstance, (PSTR)szAppName, 10 );
        GetInstanceData( hPrevInstance, (PSTR)szAbout, 10 );
        GetInstanceData( hPrevInstance, (PSTR)szMessage, 15 );
        GetInstanceData( hPrevInstance, (PSTR)&MessageLength, sizeof(int) );
        }

    hWnd = CreateWindow((LPSTR)szAppName,
                        (LPSTR)szMessage,
                        WS_TILEDWINDOW,
      CW_USEDEFAULT,    /*  x - ignored for tiled windows */
      CW_USEDEFAULT,    /*  y - ignored for tiled windows */
      CW_USEDEFAULT,    /* cx - ignored for tiled windows */
      CW_USEDEFAULT,    /* cy - ignored for tiled windows */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Save instance handle for DialogBox */
    hInst = hInstance;

    /* Bind callback function with module instance */
    lpprocAbout = MakeProcInstance( (FARPROC)About, hInstance );

    /* Insert "About..." into system menu */
    hMenu = GetSystemMenu(hWnd, FALSE);
    ChangeMenu(hMenu, 0, NULL, 999, MF_APPEND | MF_SEPARATOR);
    ChangeMenu(hMenu, 0, (LPSTR)szAbout, IDSABOUT, MF_APPEND | MF_STRING);

    /* Make window visible according to the way the app is activated */
    GetWindowRect(hWnd,&rWndRect);
    GetClientRect(hWnd,&rClRect);
    iXExtra = (rWndRect.right-rWndRect.left)-(rClRect.right-rClRect.left);
    iYExtra = (rWndRect.bottom-rWndRect.top)-(rClRect.bottom-rClRect.top);
    SetWindowPos(hWnd,NULL,0,0,
    TTYCharWidth*80 + iXExtra,
    TTYCharHeight*25 + iYExtra,
    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER);
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* Polling messages from event queue */
    while(TRUE){
  // if messages pending, process them
  if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
      if(msg.message == WM_QUIT) break;
      TranslateMessage((LPMSG)&msg);
      DispatchMessage((LPMSG)&msg);
  } else {
      // otherwise check the comm port and process any available
      // characters. you could also use a timer instead, and have
      // the timer case of the wndproc check the port.
      if(bConnected){
    // get the CommStat record and clear any error condition
    GetCommError(CommDCB.Id,&CommStat);
    // get the number of characters available
    iNumRead = CommStat.cbInQue;
    if(iNumRead > 0) {
        // get the number of characters rounded to the buffer size
        if(iNumRead > BufMax) iNumRead = BufMax;
        iNumRead = ReadComm(CommDCB.Id,MsgBuff,
          iNumRead);
        // check for errors
        if(iNumRead < 0) {
      iNumRead = abs(iNumRead);
      iError = GetCommError(CommDCB.Id,&CommStat);
      // clear the event mask
      GetCommEventMask(CommDCB.Id,0xFFFF);
      itoa(iError,sTemp,10);
      // display what the error was
      switch(iError){
      case CE_BREAK:
          MessageBox(GetFocus(), sTemp, "CE_BREAK!",MB_OK);
          break;
      case CE_CTSTO:
          MessageBox(GetFocus(), sTemp, "CE_CTSTO!",MB_OK);
          break;
      case CE_DNS:
          MessageBox(GetFocus(), sTemp, "CE_DNS!",MB_OK);
          break;
      case CE_DSRTO:
          MessageBox(GetFocus(), sTemp, "CE_DSTRO!",MB_OK);
          break;
      case CE_FRAME:
          MessageBox(GetFocus(), sTemp, "CE_FRAME!",MB_OK);
          break;
      case CE_IOE:
          MessageBox(GetFocus(), sTemp, "CE_IOE!",MB_OK);
          break;
      case CE_MODE:
          MessageBox(GetFocus(), sTemp, "CE_MODE!",MB_OK);
          break;
      case CE_OOP:
          MessageBox(GetFocus(), sTemp, "CE_OOP!",MB_OK);
          break;
      case CE_OVERRUN:
          MessageBox(GetFocus(), sTemp, "CE_OVERRUN!",MB_OK);
          break;
      case CE_PTO:
          MessageBox(GetFocus(), sTemp, "CE_PTO!",MB_OK);
          break;
      case CE_RLSDTO:
          MessageBox(GetFocus(), sTemp, "CE_RLSDTO!",MB_OK);
          break;
      case CE_RXOVER:
          MessageBox(GetFocus(), sTemp, "CE_RXOVER!",MB_OK);
          break;
      case CE_RXPARITY:
          MessageBox(GetFocus(), sTemp, "CE_RXPARITY!",MB_OK);
          break;
      case CE_TXFULL:
          MessageBox(GetFocus(), sTemp, "CE_TXFULL!",MB_OK);
          break;
      }
        }
        // send the characters to the tty window for processing
        SendMessage(hTTYWnd,COMM_CHARS,
        iNumRead,(LONG)(LPSTR)MsgBuff);
    }


      }
  }
    }

    return (int)msg.wParam;
}


/* Procedures which make up the window class. */
long FAR PASCAL TTYWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;
    register int i,j;
    TEXTMETRIC Metrics;
    HDC hDC;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        case IDSABOUT:
            DialogBox( hInst, MAKEINTRESOURCE(ABOUTBOX), hWnd, lpprocAbout );
            break;
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:  // repaint the tty window
  BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
  hDC = ps.hdc;
  SetupTTYDC(hWnd,hDC);

  TTYPaint( hDC );

  ResetTTYDC(hWnd,hDC);
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    case WM_CREATE:  // initialize the comm and tty parameters
  /* initialize screen buffer to nulls */
  for(i=0;i<25;i++)
      for(j=0;j<81;j++)
    sScrBuff[i][j] = '\0';
  /* initialize line and position to zero */
  cLastLine = 0;
  hDC = GetDC(hWnd);
  SetupTTYDC(hWnd,hDC);
  GetTextMetrics(hDC,&Metrics);
  ResetTTYDC(hWnd,hDC);
  ReleaseDC(hWnd,hDC);
  cCurrPos = 0;
  TTYCharWidth = Metrics.tmMaxCharWidth;
  TTYCharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
  bConnected = FALSE;
  hTTYWnd = hWnd;

  break;

    case WM_CLOSE:
  // disconnect if still connected
  if(bConnected)SendMessage(hWnd,WM_COMMAND,TTYCONNECT,0L);
  // go ahead and close down
  DefWindowProc( hWnd, message, wParam, lParam );
  break;

    case WM_COMMAND:
  switch(wParam){

        case IDSABOUT:
            DialogBox( hInst, MAKEINTRESOURCE(ABOUTBOX), hWnd, lpprocAbout );
            break;

  case TTYEXIT:
      PostMessage(hWnd,WM_CLOSE,0,0L);
      break;

  case TTYCONNECT:
      // connect to port if not already connected
      if(!bConnected){
    if(OpenComm(PortSetting,1024,128)) break;
    if(BuildCommDCB(CommSettings,&CommDCB)) break;

    FlushComm(CommDCB.Id,0);
    FlushComm(CommDCB.Id,1);

    CommDCB.fInX = TRUE;
    CommDCB.fOutX = FALSE;
    CommDCB.XonChar = 0x11;
    CommDCB.XoffChar = 0x13;
    CommDCB.XonLim = 50;
    CommDCB.XoffLim = 500;

    if(SetCommState(&CommDCB))break;
    bConnected = TRUE;
    MessageBox(hWnd,"Connection was successful.","",MB_OK);
      }else{
    // otherwise disconnect
    FlushComm(CommDCB.Id,0);
    FlushComm(CommDCB.Id,1);
    CloseComm(CommDCB.Id);
    MessageBox(hWnd,"Connection closed.","",MB_OK);
    bConnected = FALSE;
      }
      break;
  case TTYSETTINGS:
      // settings dialog
      i=1;  // this does nothing right now
      break;
  }
  break;

    case WM_CHAR:
  if(!bConnected) break;
  i = GetCommError(CommDCB.Id,&CommStat);
        if(i != 0) {
      itoa(i,sTemp,10);
      MessageBox(GetFocus(), sTemp, "Comm Read Error!",MB_OK);
        }

  WriteComm(CommDCB.Id,&wParam,1);
  break;

    case COMM_CHARS:
  if(wParam > 0) {
      hDC = GetDC(hWnd);
      SetupTTYDC(hWnd,hDC);

      putTTY(hWnd,hDC,wParam,(LPSTR)lParam);

      ResetTTYDC(hWnd,hDC);
      ReleaseDC(hWnd,hDC);
  }
  break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


UPDTWIN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\UPDTWIN.C

/*
 *   UpdateWindow
 *   updtwin.c
 *
 *   This program demonstrates the use of the function UpdateWindow.
 *   UpdateWindow sends a WM_PAINT message directly to the paint procedure
 *   of the given window if the update region for the window is not empty.
 *   The paint procedure invokes the TextOut function to let the operator
 *   know that the WM_PAINT message is being processed.  A message box is
 *   then shown to let the operator know that the call to UpdateWindow is
 *   complete.
 *
 */

#include "windows.h"
#include "string.h"

BOOL PASCAL SampleInit(HANDLE , HANDLE, int);
BOOL PASCAL SamplePaint(HANDLE);
long  FAR PASCAL SampleWndProc(HWND, unsigned, WORD, LONG);

static HANDLE  hInst;  /* Can be used througout the program but not normally
                        * passed to other intances */

int  PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, nCmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int  nCmdShow;
{
  HWND  hWnd;
  MSG   msg;
  HWND hWindow;    /* For use in the UpdateWindow demonstration section */

  if (!hPrevInstance)
    SampleInit(hInstance, hPrevInstance, nCmdShow);

  hInst = hInstance;                      /* So window procedures can use */
  hWnd = CreateWindow((LPSTR)"UpdateWindow",
      (LPSTR)"UpdateWindow",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,        /* no parent */
  (HMENU)NULL,       /* use class menu */
  (HANDLE)hInstance, /* handle to window instance */
  (LPSTR)NULL        /* no params to pass on */
  );

/* Make window visible according to the way the app is activated */
  ShowWindow(hWnd, nCmdShow);
  hWindow = GetActiveWindow();
  UpdateWindow( hWindow ); /* Send a WM_PAINT message directly to the
                              * window procedure, bypassing the application
                                * queue.   */
  MessageBox(hWindow,
      (LPSTR)"UpdateWindow and processed a WM_PAINT message.",
      (LPSTR)"I called ...",
      MB_OK | MB_SYSTEMMODAL );

/* Polling messages from event queue */
  while (GetMessage((LPMSG) & msg, NULL, 0, 0))
  {
    TranslateMessage((LPMSG) & msg);
    DispatchMessage((LPMSG) & msg);
  }
  return (int)msg.wParam;
}


/* Procedure called when the application is loaded for the first time */
BOOL PASCAL SampleInit( hInstance, hPrevInstance, nCmdShow )
HANDLE hInstance, hPrevInstance;
int  nCmdShow;
{
  PWNDCLASS   pSampleClass;

  pSampleClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

  pSampleClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
  pSampleClass->hIcon        = LoadIcon( hInstance, NULL);
  pSampleClass->lpszMenuName   = (LPSTR)NULL;
  pSampleClass->lpszClassName  = (LPSTR)"UpdateWindow";
  pSampleClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
  pSampleClass->hInstance      = hInstance;
  pSampleClass->style          = CS_HREDRAW | CS_VREDRAW;
  pSampleClass->lpfnWndProc    = SampleWndProc;

  if (!RegisterClass((LPWNDCLASS)pSampleClass))
/* Initialization failed.
       * Windows will automatically deallocate all allocated memory.
       */
    return FALSE;

  LocalFree((HANDLE)pSampleClass);
  return TRUE;
}


/* Every message for this window will be delevered right here.         */
long  FAR PASCAL SampleWndProc(hWnd, message, wParam, lParam)
HWND hWnd;
unsigned  message;
WORD wParam;
LONG lParam;
{
  switch (message)
  {
  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  case WM_PAINT:
    SamplePaint(hWnd);
    break;

  default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    break;
  }
  return(0L);
}


BOOL PASCAL SamplePaint(hWnd)
HWND hWnd;
{
  PAINTSTRUCT ps;
  HDC         hDC;

  BeginPaint( hWnd, (LPPAINTSTRUCT) & ps );
  hDC = ps.hdc;

  TextOut( hDC, 10, 10,
      (LPSTR)"The TextOut function is called in the paint procedure",
      strlen("The TextOut function is called in the paint procedure"));

  EndPaint( hWnd, (LPPAINTSTRUCT) & ps );

  return TRUE;
}




VALFRESP.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\VALFRESP.C

/*
Name               : valfresp.c
Function(s)
demonstrated in
this program       : ValidateFreeSpaces()
Windows version    : 2.03
Compiler version   : 5.1
Description        : ValidateFreeSpaces() checks free memory for valid
                     contents, returning the address of the first invalid
                     byte or in the event of no invalid bytes, NULL
*/

#include <windows.h>
#include "valfresp.h"

long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG) ;
int sprintf(PSTR, PSTR, int);

static int ErrorCheck;
static char szResName [] = "ResMenu";

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "valfresp" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = NULL ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWnd = CreateWindow (szAppName,            /* window class name       */
                    "ValidateFreeSpaces",       /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWnd, nCmdShow) ;

     UpdateWindow (hWnd) ;

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

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 static HANDLE hInstance;
 DWORD TotalFree;
 PAINTSTRUCT ps;
 char szBuf[50];
 LPSTR BoneBad;
 HMENU hMenu;
 switch(iMessage)
 {
  case WM_CREATE:
  {
   hInstance = GetWindowWord(hWnd, GWW_HINSTANCE);
   hMenu = LoadMenu(hInstance, "ResMenu");
   SetMenu(hWnd, hMenu);
   DrawMenuBar(hWnd);
   break;
  }
  case WM_PAINT:
  {
   BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
   EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
   break;
  }
  case WM_COMMAND:
  {
   switch(wParam)
   {
    case IDM_EXECUTE:
    {
     BoneBad = ValidateFreeSpaces();
     if (BoneBad!=NULL)
     {
      sprintf(szBuf, "address %iH contains an invalid byte",(unsigned)BoneBad
      MessageBox(GetFocus(), szBuf, "ABORTING!", MB_OK);
     } else
     {
      MessageBox(GetFocus(), "No invalid bytes encountered", "FINISHED", MB_O
     }
    }
   }
   break;
  }
  case WM_DESTROY:
  {
   PostQuitMessage(0);
   break;
  }
  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}


VALRECT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\VALRECT.C

/*
 *   ValidateRect
 *   valrect.c
 *
 *   This program demonstrates the use of the ValidateRect function. The
 *   ValidateRect function subtracts the given rectangle from the update
 *   region, which marks that rectangle for painting. ValidateRect is called
 *   once in this program to cancel the effects of the InvalidateRect
 *   function.  In effect I first set a dirty bit using the InvalidateRect
 *   function.  This dirty bit tells windows that the area containing the
 *   specified rectangle identified by the Rect parameter needs to be
 *   repainted.  I clear the dirty bit with the ValidateRect function so
 *   that the area containing the rectangle is not repainted.  InvalidateRect
 *   is called a second time to demonstrate the effects of the first
 *   ValidateRect function.
 *
 */

#include "windows.h"

long FAR PASCAL ValrectWndProc(HWND, unsigned, WORD, LONG);

/***************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL ValrectInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pValrectClass;

    pValrectClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pValrectClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pValrectClass->hIcon          = LoadIcon( hInstance,NULL);
    pValrectClass->lpszMenuName   = (LPSTR)NULL;
    pValrectClass->lpszClassName  = (LPSTR)"ValidateRect";
    pValrectClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pValrectClass->hInstance      = hInstance;
    pValrectClass->style          = CS_HREDRAW | CS_VREDRAW;
    pValrectClass->lpfnWndProc    = ValrectWndProc;

    if (!RegisterClass( (LPWNDCLASS)pValrectClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pValrectClass );
    return TRUE;        /* Initialization succeeded */
}
/***************************************************************************/

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    WORD  rectcolor = RGB(0x022,0x022,0x022);
    HDC hDC;         /* handle to display context */
    HBRUSH hMyBrush;    /* handle to brush */
    RECT Rect;         /* structure to hold rectangle coordinates */


         ValrectInit( hInstance );
    hWnd = CreateWindow((LPSTR)"ValidateRect",
                        (LPSTR)"ValidateRect",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,     /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

/* ----------------------------------------------------------------------- */
/* Begginning of the ValidateRect section */

/* create brush to fill rectangle with */
   hMyBrush = CreateSolidBrush(rectcolor);

/* get handle to display context */
   hDC = GetDC(hWnd);

/* select brush into display context */
   SelectObject(hDC,hMyBrush);

/* draw a big rectangle so we can see InvalidateRect's effects */
   Rectangle(hDC,5,5,400,200);

/* fill Rect with coordinate information for a small rectangle */
   Rect.left = 10;
   Rect.top  = 10;
   Rect.right= 50;
   Rect.bottom=50;

   MessageBox(hWnd,(LPSTR)"a small rectangle then ValidateRect the same \
small rectangle.  InvalidateRect sets a dirty bit to redraw the rectangle \
region.  ValidateRect clears the dirty bit so that a call to UpdateWindow \
will not draw the small rectangle.",
            (LPSTR)"I am about to InvalidateRect...",MB_OK);


/* invalidate the rect.identified by Rect (TRUE param. causes erase) */
   InvalidateRect(hWnd, (LPRECT)&Rect, (BOOL)TRUE);

/* Don't draw the rectangle (ie. remove it from the update region) */
   ValidateRect(hWnd, (LPRECT)&Rect);

/* call UpdateWindow so that draw will take place immediately */
   UpdateWindow(hWnd);


   MessageBox(hWnd,(LPSTR)"Notice that the small rectangle was not drawn",
            (LPSTR)"Done",MB_OK);

   MessageBox(hWnd,(LPSTR)"the small rectangle again, but this time I'm not \
going to cancel the effects of InvalidateRect with a call to ValidateRect.  \
This time my call to UpdateWindow will draw the rectangle.",
            (LPSTR)"I am about to InvalidateRect...",MB_OK);

   InvalidateRect(hWnd, (LPRECT)&Rect, (BOOL)TRUE);

   UpdateWindow(hWnd);

   ReleaseDC(hWnd, hDC);

/* End of the ValidateRect section */
/* ----------------------------------------------------------------------- */

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}
/***************************************************************************/

/* Procedures which make up the window class. */
long FAR PASCAL ValrectWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


VALRGN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\VALRGN.C

/*
 *   ValidateRgn
 *   valrgn.c
 *
 *   This program demonstrates the use of the ValidateRgn function. The
 *   ValidateRgn function subtracts the given region from the update
 *   region, which marks that region for painting. ValidateRgn is called
 *   once in this program to cancel the effects of the InvalidateRgn
 *   function.  In effect, I first set a dirty bit using the InvalidateRgn
 *   function.  This dirty bit tells Windows that the area containing the
 *   specified region identified by the hRegion parameter needs to be
 *   repainted.  I clear the dirty bit with the ValidateRgn function so
 *   that the area containing the region is not repainted.  InvalidateRgn
 *   is called a second time to demonstrate the effects of the first
 *   ValidateRgn function.
 *
 */

#include "windows.h"

long FAR PASCAL ValrgnWndProc(HWND, unsigned, WORD, LONG);

/***************************************************************************/

/* Procedure called when the application is loaded for the first time */
BOOL ValrgnInit( hInstance )
HANDLE hInstance;
{
    PWNDCLASS   pValrgnClass;

    pValrgnClass = (PWNDCLASS)LocalAlloc( LPTR, sizeof(WNDCLASS) );

    pValrgnClass->hCursor        = LoadCursor( NULL, IDC_ARROW );
    pValrgnClass->hIcon          = LoadIcon( hInstance,NULL);
    pValrgnClass->lpszMenuName   = (LPSTR)NULL;
    pValrgnClass->lpszClassName  = (LPSTR)"ValidateRgn";
    pValrgnClass->hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    pValrgnClass->hInstance      = hInstance;
    pValrgnClass->style          = CS_HREDRAW | CS_VREDRAW;
    pValrgnClass->lpfnWndProc    = ValrgnWndProc;

    if (!RegisterClass( (LPWNDCLASS)pValrgnClass ) )
        /* Initialization failed.
         * Windows will automatically deallocate all allocated memory.
         */
        return FALSE;

    LocalFree( (HANDLE)pValrgnClass );
    return TRUE;        /* Initialization succeeded */
}
/***************************************************************************/

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    MSG   msg;
    HWND  hWnd;
    HRGN  hRegion;      /* handle to elliptical region */
    HDC hDC;            /* handle to display context */
    HBRUSH hMyBrush;     /* handle to brush */
    RECT Ellipse,       /* structure to hold ellipse coordinates */
         ClearRect;     /* structure to hold client area coordinates */

    ValrgnInit( hInstance );
    hWnd = CreateWindow((LPSTR)"ValidateRgn",
                        (LPSTR)"ValidateRgn",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      (HWND)NULL,     /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

/* ----------------------------------------------------------------------- */
/* Begginning of the ValidateRgn section */

/* get handle to display context */
   hDC = GetDC(hWnd);

/* fill Ellipse with coordinate information for a small ellipse */
   Ellipse.left = 10;
   Ellipse.top  = 10;
   Ellipse.right= 50;
   Ellipse.bottom=50;

   GetClientRect(hWnd,(LPRECT)&ClearRect);
   InvertRect(hDC,(LPRECT)&ClearRect);
   hRegion = CreateEllipticRgnIndirect((LPRECT)&Ellipse);

   MessageBox(hWnd,(LPSTR)"a small ellipse, then ValidateRgn the same \
small ellipse. InvalidateRgn sets a dirty bit to redraw the ellipse \
region.  ValidateRgn clears the dirty bit so that a call to UpdateWindow \
will not draw the small ellipse.",
            (LPSTR)"I am about to InvalidateRgn...",MB_OK);


/* invalidate the ellipse identified by hRegion (TRUE param. causes erase) */
   InvalidateRgn(hWnd, (HRGN)hRegion, (BOOL)TRUE);

/* Don't draw the ellipse (ie. remove it from the update region) */
   ValidateRgn(hWnd, (HRGN)hRegion);

/* call UpdateWindow so that draw will take place immediately */
   UpdateWindow(hWnd);


   MessageBox(hWnd,(LPSTR)"Notice that the small ellipse was not drawn",
            (LPSTR)"Done",MB_OK);

   MessageBox(hWnd,(LPSTR)"the small ellipse again, but this time I'm not \
going to cancel the effects of InvalidateRgn with a call to ValidateRgn.  \
This time my call to UpdateWindow will draw the ellipse.",
            (LPSTR)"I am about to InvalidateRgn...",MB_OK);

   InvalidateRgn(hWnd, (HRGN)hRegion, (BOOL)TRUE);

   UpdateWindow(hWnd);

   ReleaseDC(hWnd, hDC);

/* End of the ValidateRgn section */
/* ----------------------------------------------------------------------- */

    /* Polling messages from event queue */
    while (GetMessage((LPMSG)&msg, NULL, 0, 0)) {
        TranslateMessage((LPMSG)&msg);
        DispatchMessage((LPMSG)&msg);
        }

    return (int)msg.wParam;
}
/***************************************************************************/

/* Procedures which make up the window class. */
long FAR PASCAL ValrgnWndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    PAINTSTRUCT ps;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );
        EndPaint( hWnd, (LPPAINTSTRUCT)&ps );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}


VERSION.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\VERSION.C

/*
 *  GetVersion
 *  version.c
 *
 *  This function returns the current version of windows in an unsigned
 *   short integer.  The low byte corresponding to the major version
 *   number and the high byte corresponding to the minor version number.
 *  This function calls the GetVersion function and places the version
 *   number in a message box with the appropriate bytes to convey the
 *   actual current version number.
 *
 */

#include <windows.h>

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, cmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;

{
   unsigned short version;     /* The Current Version Number.    */
   unsigned short majvers;     /* The Major Version Number.      */
   unsigned short minvers;     /* The Minor Version Number.      */
   char szbuf[14];          /* The Version Number Buffer.     */

   version = GetVersion();     /* Get the Current Version.      */
   majvers = LOBYTE(version);  /* Cast Major Version.            */
   minvers = HIBYTE(version);  /* Cast the Minor Version.         */
   sprintf(szbuf,             /* Place the version number in    */
           "%9s%1d%1s%02d",   /*  the output buffer along with  */
           " Version ",       /*  some explatitory text.        */
           majvers,
           ".",
           minvers);

           /* Create Version Number Message. */

   MessageBox(NULL, (LPSTR)szbuf, (LPSTR)"MS-Windows", MB_OK);

           /* Print Out Version Message.     */

   return 0;         /* Exit With a Successful Return. */

}


VIEWPORT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\GRAPHICS\VIEWPORT.C

/*

Function(s) demonstrated in this program: GetViewportExt, GetWindowExt,
    OffsetViewportOrg, OffsetWindowOrg, SetViewportExt, SetWindowExt,
   ScaleViewportExt, ScaleWindowExt, SetViewportOrg, SetWindowOrg

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  These functions modify the interface between screen pixels and
    the screen viewport.

Additional Comments:  The Scale functions (ScaleViewportExt, ScaleWindowExt),
    both take 5 parameters the first is a handle to a display context and
    the next 4 are the numerators and denominators of the fractions that
    will be used to scale the x and y extents.

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "ViewPort.h"

#define PI 3.14159265


char    szRadius  [15];
HANDLE  hInstMain;
FARPROC lpProcGetRadius;
char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];
HWND     hWndMain, hX, hY, hOK2;
FARPROC  lpProcEnterPoint;
FARPROC  lpProcNewEnterPoint;
FARPROC  lpProcOldX;
FARPROC  lpProcOldY;
char     szXValue [40];
char     szYValue [40];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About\0",
"     This is a sample application to demonstrate the\n\
use of ViewPort Window Extent functions.",

"Help Message",
"     This program uses the Windows functions\n\
GetViewportExt, GetWindowExt, OffsetViewportOrg,\n\
OffsetWindowOrg, SetViewportExt, SetWindowExt,\n\
ScaleViewportExt, SetViewportOrg, SetWindowOrg\n\
and ScaleWindowExt to modify the relationship\n\
between the viewport and the screen pixels.  Use\n\
the menu to request the function, then set the\n\
variables accordingly.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
    HANDLE  hInstance, hPrevInstance;
    LPSTR  lpszCmdLine;
    int   nCmdShow;
    {
    static char szAppName[] = "ViewPort";
    HWND  hWnd;
    MSG   msg;
    WNDCLASS  wndclass;

    if (!hPrevInstance)  {
        wndclass.style          = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc    = WndProc;
        wndclass.cbClsExtra     = 0;
        wndclass.cbWndExtra     = 0;
        wndclass.hInstance      = hInstance;
        wndclass.hIcon          = NULL; /*LoadIcon (NULL, IDI_ASTERISK);*/
        wndclass.hCursor        = LoadCursor (NULL, IDC_CROSS);
        wndclass.hbrBackground  = GetStockObject (WHITE_BRUSH);
        wndclass.lpszMenuName   = szAppName;
        wndclass.lpszClassName  = szAppName;

        if (!RegisterClass (&wndclass) )
            return FALSE;
    }


    hWnd = CreateWindow (szAppName, "ViewPort",
      WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
    CW_USEDEFAULT, 0, NULL, NULL,
      hInstance, NULL);

    hInstMain = hInstance;
    hWndMain  = hWnd;

    ShowWindow (hWnd, nCmdShow);
    UpdateWindow (hWnd);

    lpProcEnterPoint    = MakeProcInstance (EnterPointDlgProc, hInstance);
    lpProcNewEnterPoint = MakeProcInstance (NewEnterPointDlgProc,hInstance);

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
  HWND      hWnd;
  unsigned    iMessage;
  WORD      wParam;
  LONG      lParam;
  {
   HMENU         hMenu;
  static HRGN   hRgnClip;
  static double xXcoord, yYcoord, fRadiusInc=(float)1, fRadius=(float)0,
                 fAngle=(float)0, fAngleShift=(float)1, fMaxRadius,
                 fProportion;
  static short  xClient, yClient;
  HDC          hDC;
  HRGN          hRGN;
  PAINTSTRUCT   ps;
   static WORD   OffViewX, OffViewY, OffWindowX, OffWindowY, SetViewX,
                 SetViewY, SetWindowX, SetWindowY, ScaleViewXnum,
                 ScaleViewYnum, ScaleViewXdenom, ScaleViewYdenom,
                 ScaleWindowXnum, ScaleWindowYnum, ScaleWindowXdenom,
                 ScaleWindowYdenom, SetWindowOrgX, SetWindowOrgY,
                 SetViewportOrgX, SetViewportOrgY;
   DWORD         Check;

  switch (iMessage) {
       case WM_CREATE:
            hMenu = GetSystemMenu (hWnd, FALSE);

            ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                        MF_APPEND | MF_STRING);
            break;

       case WM_SYSCOMMAND:
            switch (wParam) {
               case IDM_ABOUT:
                    ProcessMessage (hWnd, 0);
                    break;
               default:
                    return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
            }
            break;

      case WM_SIZE:
            xClient=LOWORD (lParam);
            yClient=HIWORD (lParam);
            fProportion= ((double) yClient)/ ((double) xClient);
            fMaxRadius = xClient/2.0;
            break;


       case WM_COMMAND:
            switch (wParam) {
               case IDM_CHANGE:
                    lpProcGetRadius = MakeProcInstance(GetRadiusDlgProc,
                                     hInstMain);
                    DialogBox (hInstMain, (LPSTR)"GetAngle", hWnd,
                              lpProcGetRadius);
                    FreeProcInstance (lpProcGetRadius);
                    fAngleShift = atof (szRadius);

                    lpProcGetRadius = MakeProcInstance(GetRadiusDlgProc,
                                     hInstMain);
                    DialogBox (hInstMain, (LPSTR)"GetRadius", hWnd,
                              lpProcGetRadius);
                    FreeProcInstance (lpProcGetRadius);
                    fRadiusInc = atof (szRadius);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_OFFVIEWPORT:
                    bOffsetViewportOrg = TRUE;
                    sprintf (szXValue, "Enter Origin (x,y)");
                    sprintf (szYValue, "OffsetViewportOrg");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    OffViewX = atoi (szXValue);
                    OffViewY = atoi (szYValue);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_OFFWINDOW:
                    bOffsetWindowOrg = TRUE;
                    sprintf (szXValue, "Enter Origin (x,y)");
                    sprintf (szYValue, "OffsetWindowOrg");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    OffWindowX = atoi (szXValue);
                    OffWindowY = atoi (szYValue);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_SETVIEWPORT:
                    bSetViewportExt = TRUE;
                    sprintf (szXValue, "Enter Extents (x,y)");
                    sprintf (szYValue, "SetViewportExt");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    SetViewX = atoi (szXValue);
                    SetViewY = atoi (szYValue);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_SETEXTENT:
                    bSetWindowExt = TRUE;
                    sprintf (szXValue, "Enter Extents (x,y)");
                    sprintf (szYValue, "SetWindowExt");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    SetWindowX = atoi (szXValue);
                    SetWindowY = atoi (szYValue);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_SCALEVIEW:
                    bScaleViewportExt = TRUE;
                    sprintf (szXValue, "Enter Numerators (x,y)");
                    sprintf (szYValue, "ScaleViewportExt");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    ScaleViewXnum = atoi (szXValue);
                    ScaleViewYnum = atoi (szYValue);

                    sprintf (szXValue, "Enter Denominators (x,y)");
                    sprintf (szYValue, "ScaleViewportExt");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    ScaleViewXdenom = atoi (szXValue);
                    ScaleViewYdenom = atoi (szYValue);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_SCALEWINDOW:
                    bScaleWindowExt = TRUE;
                    sprintf (szXValue, "Enter Numerators (x,y)");
                    sprintf (szYValue, "ScaleWindowExt");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    ScaleWindowXnum = atoi (szXValue);
                    ScaleWindowYnum = atoi (szYValue);

                    sprintf (szXValue, "Enter Denominators (x,y)");
                    sprintf (szYValue, "ScaleWindowExt");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    ScaleWindowXdenom = atoi (szXValue);
                    ScaleWindowYdenom = atoi (szYValue);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_GETVIEWPORTEXT:
                    hDC = GetDC (hWnd);
                    SetMapMode (hDC, MM_ANISOTROPIC);
                    if (bSetViewportExt)
                        SetViewportExt    (hDC, SetViewX, SetViewY);
                    Check = GetViewportExt (hDC);
                    sprintf (szOutputBuffer1, "Viewport Extension = (%i,%i)",
                            LOWORD (Check), HIWORD (Check));
                    MessageBox (hWnd, szOutputBuffer1, "GetViewportExt", MB_O
                    ReleaseDC (hWnd, hDC);
                    break;

               case IDM_GETWINDOWEXT:
                    hDC = GetDC (hWnd);
                    SetMapMode (hDC, MM_ANISOTROPIC);
                    if (bSetWindowExt)
                        SetWindowExt      (hDC, SetWindowX, SetWindowY);
                    Check = GetWindowExt (hDC);
                    sprintf (szOutputBuffer1, "Window Extention = (%i,%i)",
                            LOWORD (Check), HIWORD (Check));
                    MessageBox (hWnd, szOutputBuffer1, "GetWindowExt", MB_OK)
                    ReleaseDC (hWnd, hDC);
                    break;

               case IDM_SETVIEWPORTORG:
                    bSetViewportOrg = TRUE;
                    sprintf (szXValue, "Enter Origin (x,y)");
                    sprintf (szYValue, "SetViewportOrg");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    SetViewportOrgX = atoi (szXValue);
                    SetViewportOrgY = atoi (szYValue);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_SETWINDOWORG:
                    bSetWindowOrg = TRUE;
                    sprintf (szXValue, "Enter Origin (x,y)");
                    sprintf (szYValue, "SetWindowOrg");
                    DialogBox (hInstMain, (LPSTR)"EnterPointDlg", hWnd,
                           lpProcEnterPoint);
                    SetWindowOrgX = atoi (szXValue);
                    SetWindowOrgY = atoi (szYValue);

                    InvalidateRect (hWnd, NULL, TRUE);
                    UpdateWindow (hWnd);
                    break;

               case IDM_HELP:
                    ProcessMessage (hWnd, 2);
                    break;
            }
            break;

      case WM_PAINT:
            hDC=BeginPaint(hWnd, &ps);
            SetMapMode (hDC, MM_ANISOTROPIC);
            SetViewportOrg (hDC, xClient/2, yClient/2);

            if (bOffsetViewportOrg)
                  OffsetViewportOrg (hDC, OffViewX, OffViewY);
            if (bOffsetWindowOrg)
                  OffsetWindowOrg   (hDC, OffWindowX, OffWindowY);
            if (bSetViewportExt)
                  SetViewportExt    (hDC, SetViewX, SetViewY);
            if (bSetWindowExt)
                  SetWindowExt      (hDC, SetWindowX, SetWindowY);
            if (bScaleViewportExt)
                  ScaleViewportExt  (hDC, ScaleViewXnum, ScaleViewXdenom,
                                     ScaleViewYnum, ScaleViewYdenom);
            if (bScaleWindowExt)
                  ScaleWindowExt  (hDC, ScaleWindowXnum, ScaleWindowXdenom,
                                     ScaleWindowYnum, ScaleWindowYdenom);
            if (bSetViewportOrg)
                  SetViewportOrg (hDC, SetViewportOrgX, SetViewportOrgY);
            if (bSetWindowOrg)
                  SetWindowOrg (hDC, SetWindowOrgX, SetWindowOrgY);

            MoveTo (hDC, 0, 0);
            ShowCursor (TRUE);
            for (fRadius=(float)0; fRadius<fMaxRadius; fRadius+=fRadiusInc) {
                 xXcoord = fRadius * cos(fAngle);
                 yYcoord = fRadius * sin(fAngle) * fProportion;
                 LineTo (hDC, (short)xXcoord, (short)yYcoord);
                 fAngle +=fAngleShift;
            }
            EndPaint (hWnd, &ps);
            break;

       case WM_DESTROY:
            PostQuitMessage (0);
            break;

      default:
            return DefWindowProc( hWnd, iMessage, wParam, lParam );
       }
  return 0L;
}

/***************************************************************************/

BOOL FAR PASCAL GetRadiusDlgProc (hDlg, iMessage, wParam, lParam)
HWND hDlg;
unsigned iMessage;
WORD wParam;
LONG lParam;
{
     int Index;
     char szChange [10];
     long lReturn;

     switch (iMessage) {
        case WM_INITDIALOG:
             SendDlgItemMessage (hDlg, IDD_RADIUS, EM_LIMITTEXT,
                                 (WORD)80, 0L);
             SetDlgItemText (hDlg, IDD_RADIUS, "1.0");
             return TRUE;
             break;

        case WM_COMMAND:
             switch (wParam)
             {
               case IDD_RADIUS:
                    if (HIWORD (lParam) == EN_CHANGE)
                        EnableWindow (GetDlgItem(hDlg,IDOK),
                                     (BOOL)SendMessage(LOWORD (lParam),
                                      WM_GETTEXTLENGTH, 0, 0L)) ;
                    break;

               case IDOK:
                    GetDlgItemText (hDlg, IDD_RADIUS, szRadius, 80) ;
                    OemToAnsi (szRadius, szRadius);
                    EndDialog (hDlg, TRUE);
                    break;

               case IDCANCEL:
                EndDialog (hDlg, FALSE) ;
                    break;

               default:
                    return FALSE;
             }
        default:
             return FALSE;
     }
     return TRUE;
}

/****************************************************************************

BOOL FAR PASCAL EnterPointDlgProc (hDlg, iMessage, wParam, lParam)
HWND hDlg;
unsigned iMessage;
WORD wParam;
LONG lParam;
{
     int Index;
     char szChange [10];
     long lReturn;

     switch (iMessage) {
     case WM_INITDIALOG:
       SendDlgItemMessage (hDlg, IDD_X, EM_LIMITTEXT,
                           (WORD)40, 0L);
       SendDlgItemMessage (hDlg, IDD_Y, EM_LIMITTEXT,
                           (WORD)40, 0L);
       SetDlgItemText (hDlg, IDD_TEXT1, szXValue);
       SetDlgItemText (hDlg, IDD_TEXT2, szYValue);

       hX = GetDlgItem (hDlg, IDD_X);
         lpProcOldX = (FARPROC) GetWindowLong (hX, GWL_WNDPROC);
         SetWindowLong (hX, GWL_WNDPROC, (LONG) lpProcNewEnterPoint);
         SendMessage (hX, EM_SETSEL, 0, MAKELONG (0,32767));
       hY = GetDlgItem (hDlg, IDD_Y);
         lpProcOldY = (FARPROC) GetWindowLong (hY, GWL_WNDPROC);
         SetWindowLong (hY, GWL_WNDPROC, (LONG) lpProcNewEnterPoint);
         SendMessage (hY, EM_SETSEL, 0, MAKELONG (0,32767));
       hOK2 = GetDlgItem (hDlg, IDOK);

       return TRUE;
       break;

     case WM_COMMAND:
       switch (wParam) {
         case IDD_X:
              break;

         case IDD_Y:
              break;

         case IDOK:
              GetDlgItemText (hDlg, IDD_X, szXValue, 10) ;
              GetDlgItemText (hDlg, IDD_Y, szYValue, 10) ;
              EndDialog (hDlg, TRUE);
              break;

         default:
              return FALSE;
      }
    default:
      return FALSE;
  }
  return TRUE;
}

/****************************************************************************

BOOL FAR PASCAL NewEnterPointDlgProc  (hWnd, iMessage, wParam, lParam)
     HWND     hWnd;
     unsigned iMessage;
     WORD     wParam;
     LONG     lParam;
{
     switch (iMessage) {
       case WM_GETDLGCODE:
            return (DLGC_WANTALLKEYS);

       case WM_CHAR:
            if ((wParam == VK_TAB) || (wParam == VK_RETURN)) {
                SendMessage (hWndMain, WM_USER, 0, 0L);
                SetFocus (FindNextWindow (hWnd));
                return TRUE;
            }
            else {
              if (hWnd == hX)
                return ((BOOL)CallWindowProc (lpProcOldX, hWnd,
                        iMessage, wParam, lParam));
              if (hWnd == hY)
                return ((BOOL)CallWindowProc (lpProcOldY, hWnd,
                        iMessage, wParam, lParam));
            }
            break;

       default:
         if (hWnd == hX)
            return ((BOOL)CallWindowProc (lpProcOldX, hWnd,
                    iMessage, wParam, lParam));
         if (hWnd == hY)
            return ((BOOL)CallWindowProc (lpProcOldY, hWnd,
                    iMessage, wParam, lParam));
     }
}

/****************************************************************************

HWND FindNextWindow (hWnd)
     HWND   hWnd;
{
     if (hWnd == hX)      return hY;
     if (hWnd == hY)      return hOK2;
     return NULL;
}



WAITMSG.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MESSAGE\WAITMSG.C

/*

Function(s) demonstrated in this program: WaitMessage

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  This function yields control to other applications when an
    application has no other tasks to perform.  The WaitMessage function
   suspends the application and does not return until a new message is
   placed in the application's queue.

Additional Comments:

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "WaitMsg.h"


HWND     hWndMain;
HANDLE   hInstMain;

char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About",
"     This is a sample application to demonstrate the\n\
use  of  the  WaitMessage Windows function.",

"Help Message",
"     This program uses the WaitMessage Windows\n\
function to suspend processing of the current\n\
Window function until the window receives another\n\
Message.  To test this function type a character\n\
making sure not to move the cursor.  At this\n\
point the Window will be suspended until you give\n\
it another message.  This can be done by simply\n\
moving the cursor.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "WaitMsg" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;
          }

     hWndMain = CreateWindow (szAppName,        /* window class name       */
                    "WaitMessage",              /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWndMain, nCmdShow) ;
     UpdateWindow (hWndMain) ;

     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 PAINTSTRUCT ps;

 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_KEYUP:
       WaitMessage ();
       MessageBox (hWnd, "Window returned to regular processing",
                   "WaitMessage",MB_OK);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {
          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}




WFPOINT.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\WFPOINT.C

/*
 *  Function(s) demonstrated in this program: WindowFromPoint
 *  Compiler version: 5.1
 *  Description:
 *     This program will get the handle to the window that contains the
 *  point ( 100, 100 ) in it.
 */

#include <windows.h>

long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE      hInstance, hPrevInstance ;
LPSTR       lpszCmdLine ;
int         nCmdShow ;
  {
  HWND        hWnd;          /*  Handle to the window to iconize  */
  POINT       pPoint;        /*  Will hold the point  */

  pPoint.x = 100;            /*  Set the point to 100, 100  */
  pPoint.y = 100;

  hWnd = WindowFromPoint( pPoint );  /*  Get the window handle  */

  MessageBox( GetFocus(), (LPSTR)"We have the handle to the window",
              (LPSTR)"", MB_OK );
  return( TRUE );
  }


WINFIND.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\WINFIND.C

#include <windows.h>

void FAR PASCAL locate();


int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    cmdShow;
{
    locate();
    return 0;
}

void FAR PASCAL locate()
{
  char   buf[60];

  GetModuleFileName( GetModuleHandle((LPSTR)"winfind"), buf, 60 );
  MessageBox( GetFocus(), (LPSTR)buf, (LPSTR)"module loaded from", MB_OK);

}



WINSPAWN.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SPAWN\WINSPAWN.C

/*

Function(s) demonstrated in this program: Int21Function4B, LockSegment,
   UnlockSegment

Windows version:  2.03

Windows SDK version:  2.00

Compiler version:  C 5.10

Description:  Int21Function4B is a Function created using Masm, and it
   corresponds with the MS-DOS interrupt 21 function 4BH.  The function
   LockSegment locks the segment whose segment address is specified
  by the parameter.  If the parameter is -1 the function locks the
   current data segment.  The function UnlockSegment unlocks the segment
   whose address is specified by the parameter, -1 indicates current
  segment.

Additional Comments:  Int21Function4B can be used to spawn windows
   applications, as well as old MS-DOS applications from within a
   windows application.  A method of sending command line arguments
   to the spawnded windows application is also discussed.

*/

#define NOMINMAX
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "WinSpawn.h"

HWND     hWndMain;
HANDLE   hInstMain;
char     szOutputBuffer1 [70];
char     szOutputBuffer2 [500];
char     szSpawnAppName  [40];
char     szCommandLine   [40];

typedef struct {WORD   environment;
                LPSTR  commandline;
                LPSTR  FCB1;
                LPSTR  FCB2;
               } EXECBLOCK;
EXECBLOCK      exec;
WORD           w[2];


/****************************************************************************
/************************    Message Structure      *************************
/****************************************************************************

struct { char *szMessage; }
       Messages [] = {
"About",
"     This is a sample application to demonstrate the\n\
use of the LockSegment and UnlockSegment Windows\n\
Functions, as well as Interrupt 21 function 4B in\n\
spawning Windows applications, and MS-DOS applications\n\
from a Windows Windows application.",

"Help Message",
"     This program demonstrates the use of the\n\
Windows Function LockSegment, UnlockSegment, and\n\
Int21Function4B.  Use the menu to select either a\n\
MS-DOS application or a Windows application to be\n\
spawned.  The program will also send command line\n\
arguments to the spawned application.",

"LockSegment",
"    The current data segment has been locked.",

"UnlockSegment",
"    The current data segment has been unlocked.",

};

/****************************************************************************

void ProcessMessage (HWND, int);

void ProcessMessage (hWnd, MessageNumber)
     HWND     hWnd;
     int      MessageNumber;
{
     sprintf (szOutputBuffer1, "%s", Messages [MessageNumber]);
     sprintf (szOutputBuffer2, "%s", Messages [MessageNumber + 1]);
     MessageBox (hWnd, szOutputBuffer2, szOutputBuffer1, MB_OK);
}

/****************************************************************************

int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
     HANDLE      hInstance, hPrevInstance ;
     LPSTR       lpszCmdLine ;
     int         nCmdShow ;
     {
     static char szAppName [] = "WinSpawn" ;
     static char szChildClass [] = "WinSpawnChild" ;
     HWND        hWnd ;
     WNDCLASS    wndclass ;
     MSG msg;

     if (!hPrevInstance)
          {
          wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
          wndclass.lpfnWndProc   = WndProc ;
          wndclass.cbClsExtra    = 0 ;
          wndclass.cbWndExtra    = 0 ;
          wndclass.hInstance     = hInstance ;
          wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
          wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
          wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;
          wndclass.lpszMenuName  = szAppName ;
          wndclass.lpszClassName = szAppName ;

          if (!RegisterClass (&wndclass))
               return FALSE ;

          }

     hWnd = CreateWindow (szAppName,            /* window class name       */
                    "Windows Spawn",            /* window caption          */
                    WS_OVERLAPPEDWINDOW,        /* window style            */
                    CW_USEDEFAULT,              /* initial x position      */
                    0,                          /* initial y position      */
                    CW_USEDEFAULT,              /* initial x size          */
                    0,                          /* initial y size          */
                    NULL,                       /* parent window handle    */
                    NULL,                       /* window menu handle      */
                    hInstance,                  /* program instance handle */
                    NULL) ;                     /* create parameters       */

     ShowWindow (hWnd, nCmdShow) ;
     UpdateWindow (hWnd) ;

     hWndMain  = hWnd;
     hInstMain = hInstance;

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

/****************************************************************************

long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
HWND     hWnd ;
unsigned iMessage ;
WORD     wParam ;
LONG     lParam ;
{
 HMENU       hMenu;
 PAINTSTRUCT ps;

 switch(iMessage)
 {
  case WM_CREATE:
       hMenu = GetSystemMenu (hWnd, FALSE);

       ChangeMenu (hMenu, NULL, "&About", IDM_ABOUT,
                   MF_APPEND | MF_STRING);
       break;

  case WM_SYSCOMMAND:
       switch (wParam) {
          case IDM_ABOUT:
               ProcessMessage (hWnd, 0);
               break;
          default:
               return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
       }
       break;

  case WM_COMMAND:
       switch (wParam) {

          case IDM_SPAWNIT:
               GlobalCompact(-1L);
               LockSegment (-1);
               ProcessMessage (hWnd, 4);

               exec.environment = 0;
               exec.commandline = szCommandLine;

               w[0] = 2;
               w[1] = SW_SHOWNORMAL;
               exec.FCB1 = (LPSTR)w;
               exec.FCB2 = (LPSTR)NULL;

               Int21Function4B(0, (LPSTR)szSpawnAppName,
                               (LPSTR)&exec);

               UnlockSegment (-1);
               ProcessMessage (hWnd, 6);
               break;

          case IDM_CLOCK:
               sprintf (szSpawnAppName,"CLOCK.EXE");
               sprintf (szCommandLine, "\0\r");
               SendMessage (hWnd, WM_COMMAND, IDM_SPAWNIT, 0L);
               break;

          case IDM_DOSDIRSORT:
               sprintf (szSpawnAppName,"COMMAND.COM");
               sprintf (szCommandLine, "%c /c dir | sort\0\r", 14);
               SendMessage (hWnd, WM_COMMAND, IDM_SPAWNIT, 0L);
               break;

          case IDM_DOSTYPE:
               sprintf (szSpawnAppName,"COMMAND.COM");
               sprintf (szCommandLine, "%c /c type winspawn.c\0\r", 0x13);
               SendMessage (hWnd, WM_COMMAND, IDM_SPAWNIT, 0L);
               break;

          case IDM_NOTEPAD:
               sprintf (szSpawnAppName,"NOTEPAD.EXE");
               sprintf (szCommandLine, " WINSPAWN.C\0\r");
               SendMessage (hWnd, WM_COMMAND, IDM_SPAWNIT, 0L);
               break;


          case IDM_HELP:
               ProcessMessage (hWnd, 2);
               break;
       }
       break;

  case WM_PAINT:
       BeginPaint(hWnd, (LPPAINTSTRUCT)&ps);
       EndPaint(hWnd, (LPPAINTSTRUCT)&ps);
       break;

  case WM_DESTROY:
       PostQuitMessage(0);
       break;

  default:
  {
   return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
  }
 }
 return (0L);
}


WNDPROC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\HOOKS\MENUHELP\WNDPROC.C

#include "windows.h"
#include "APP.h"
#include "stdlib.h"
#include "string.h"

/* Static definitions */
FARPROC lpprocHook;
FARPROC lplpfnNextHook;

/* Keep track of the application's window handle for hook processing */
HWND hApp;

/* Function proto-types */
void FAR PASCAL InitHook( HWND );
BOOL FAR PASCAL KillHook();
DWORD FAR PASCAL Hook( int, WORD, LPMSG );

extern HANDLE hInst;

extern APPCommand( HWND, WORD, LONG );
extern APPPaint  ( HWND, WORD, LONG );

long FAR PASCAL WndProc( HWND, unsigned, WORD, LONG );
BOOL FAR PASCAL About( HWND, unsigned, WORD, LONG );


long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpprocAbout;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        case IDSABOUT:
            /* Bind callback function with module instance */
            lpprocAbout = MakeProcInstance( (FARPROC)About, hInst);
            DialogBox( hInst, MAKEINTRESOURCE(ABOUTBOX), hWnd, lpprocAbout );
            FreeProcInstance( (FARPROC)About );
            break;
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_COMMAND:
        switch (wParam) {
           case IDAPPMENU:
                APPCommand( hWnd, wParam, lParam );
                break;
           default:
                return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_CREATE:
        InitHook( hWnd );
        break;

    case WM_DESTROY:
        KillHook();
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        APPPaint( hWnd, wParam, lParam );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}
/*
*/


BOOL FAR PASCAL About( hDlg, message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    if (message == WM_COMMAND) {
        EndDialog( hDlg, TRUE );
        return TRUE;
        }
    else if (message == WM_INITDIALOG)
        return TRUE;
    else return FALSE;
}
/*
*/


/* Set the HOOK */
void FAR PASCAL InitHook( hWnd )
HWND hWnd;
{
        hApp = hWnd;

        lpprocHook = MakeProcInstance( (FARPROC)Hook, hInst);
        lplpfnNextHook = SetWindowsHook( WH_MSGFILTER, lpprocHook );

        return;
}
/*
*/

/* Remove the HOOK */
BOOL FAR PASCAL KillHook()
{
        BOOL fSuccess;

        fSuccess = UnhookWindowsHook( WH_MSGFILTER, lpprocHook );
        FreeProcInstance( lpprocHook );

        return fSuccess;
}
/*
*/

/* Hook function */
DWORD FAR PASCAL Hook( nCode, wParam, lParam )
int nCode;
WORD wParam;
LPMSG lParam;
{
        HDC hDC;
        TEXTMETRIC tmFontInfo;
        RECT rRect;
        int TextHeight;
        WORD y;

        if ((nCode != MSGF_MENU) || (lParam->message != WM_MENUSELECT) ) {
            DefHookProc( nCode, wParam, lParam, (FARPROC FAR *)&lplpfnNextHoo
            return 0;
        }

        hDC = GetDC( hApp );
        GetTextMetrics( hDC, (LPTEXTMETRIC)&tmFontInfo );
        TextHeight = tmFontInfo.tmExternalLeading + tmFontInfo.tmHeight;
        GetClientRect( hApp, (LPRECT)&rRect );
        y = rRect.bottom - TextHeight;
        switch (lParam->wParam) {
           case SC_CLOSE:
              TextOut( hDC, 0, y, (LPSTR)"Close the application ", 22 );
              break;
           case SC_MAXIMIZE:
              TextOut( hDC, 0, y, (LPSTR)"Enlarge to full size  ", 22 );
              break;
           case SC_MINIMIZE:
              TextOut( hDC, 0, y, (LPSTR)"Reduce window to icon ", 22 );
              break;
           case SC_MOVE:
              TextOut( hDC, 0, y, (LPSTR)"Change window position", 22 );
              break;
           case SC_RESTORE:
              TextOut( hDC, 0, y, (LPSTR)"Restore to normal size", 22 );
              break;
           case SC_SIZE:
              TextOut( hDC, 0, y, (LPSTR)"Change window size    ", 22 );
              break;

           case IDAPPMENU:
              TextOut( hDC, 0, y, (LPSTR)"Item 1 highlighted    ", 22 );
              break;
           case IDAPPMENU+1:
              TextOut( hDC, 0, y, (LPSTR)"Item 2 highlighted    ", 22 );
              break;
           case IDAPPMENU+2:
              TextOut( hDC, 0, y, (LPSTR)"Item 3 highlighted    ", 22 );
              break;
           case IDHELP:
              TextOut( hDC, 0, y, (LPSTR)"HELP the poor user    ", 22 );
              break;
           case IDSABOUT:
              TextOut( hDC, 0, y, (LPSTR)"Program information   ", 22 );
              break;

           default:
              TextOut( hDC, 0, y, (LPSTR)"                      ", 22 );
              break;
        }
        ReleaseDC( hApp, hDC );
        DefHookProc( nCode, wParam, lParam, (FARPROC FAR *)&lplpfnNextHook );
        return 0;
}


WNDPROC.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\HOOKS\JOURNAL\WNDPROC.C

#include "windows.h"
#include "APP.h"

extern HANDLE hInst;

extern APPPaint  ( HWND, WORD, LONG );

/* Function proto-types of Journal control functions in DLL */
void FAR PASCAL StartRecord();
void FAR PASCAL StopRecord();
void FAR PASCAL StartPlay();
void FAR PASCAL StopPlay();

long FAR PASCAL WndProc( HWND, unsigned, WORD, LONG );
BOOL FAR PASCAL About( HWND, unsigned, WORD, LONG );

long FAR PASCAL WndProc( hWnd, message, wParam, lParam )
HWND hWnd;
unsigned message;
WORD wParam;
LONG lParam;
{
    FARPROC lpprocAbout;
    HMENU hMenu;

    switch (message)
    {
    case WM_SYSCOMMAND:
        switch (wParam)
        {
        case IDSABOUT:
            /* Bind callback function with module instance */
            lpprocAbout = MakeProcInstance( (FARPROC)About, hInst);
            DialogBox( hInst, MAKEINTRESOURCE(ABOUTBOX), hWnd, lpprocAbout );
            FreeProcInstance( (FARPROC)About );
            break;
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
        }
        break;

    case WM_COMMAND:
        switch (wParam) {
           case IDRECORDON:
                MessageBox( hWnd, (LPSTR)"About to Record!", (LPSTR)"WARNING!
                StartRecord();
                break;
           case IDRECORDOFF:
                StopRecord();
                break;
           case IDPLAY:
                MessageBox( hWnd, (LPSTR)"About to Play!", (LPSTR)"WARNING!",
                StartPlay();
                break;

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

    case WM_DESTROY:
        /* Just in case.  Make sure un-hooked before app dies */
        StopRecord();
        StopPlay();
        PostQuitMessage( 0 );
        break;

    case WM_PAINT:
        APPPaint( hWnd, wParam, lParam );
        break;

    default:
        return DefWindowProc( hWnd, message, wParam, lParam );
        break;
    }
    return(0L);
}
/*
*/


BOOL FAR PASCAL About( hDlg, message, wParam, lParam )
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    if (message == WM_COMMAND) {
        EndDialog( hDlg, TRUE );
        return TRUE;
        }
    else if (message == WM_INITDIALOG)
        return TRUE;
    else return FALSE;
}
/*
*/


WRPROFST.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\STRING\WRPROFST.C

/*
 * This program demonstrates the use of WriteProfileString(). In this
 * example, the string "fubar=yes" keyword and value is written to an
 * application name called "foo".  If this construct currently exists
 * in the win.ini file, it is reported to the user. Note! This program
 * makes permanent changes to the WIN.INI file, but should not affect
 * any existing applications.
 */

#include <windows.h>

#define CHARLEN  4

int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
HANDLE hInstance, hPrevInstance;
LPSTR  lpszCmdLine;
int    nCmdShow;
{
   char  szFooStr[5];
   int   iCopied;
   int   iResult;
   BOOL  bResult;

   iCopied = GetProfileString((LPSTR)"foo", (LPSTR)"fubar", (LPSTR)"ERR",
                              (LPSTR)szFooStr, CHARLEN);

   if (iCopied == NULL)
      MessageBox(GetFocus(), (LPSTR)"Error in Checking WIN.INI",
                 (LPSTR)"GetProfileString()", MB_OK);
   else if ((szFooStr[0] == 'y') &&
            (szFooStr[1] == 'e') &&
            (szFooStr[2] == 's'))
      MessageBox(GetFocus(), (LPSTR)"Profile String Currently Exists!",
                 (LPSTR)"GetProfileString()", MB_OK);

   else {
      MessageBox(GetFocus(),
                 (LPSTR)"Inserting 'fubar=yes' into [foo] section of WIN.INI.
                 (LPSTR)"WriteProfileString()", MB_OK);
      iResult = MessageBox(GetFocus(),
                           (LPSTR)"Continuing Will Change WIN.INI Contents!",
                           (LPSTR)"WriteProfileString()",
                           MB_OKCANCEL | MB_ICONEXCLAMATION);
      if (iResult != IDCANCEL) {
         bResult = WriteProfileString((LPSTR)"foo", (LPSTR)"fubar",
                                      (LPSTR)"yes");
         if (bResult == NULL)
            MessageBox(GetFocus(), (LPSTR)"Error In Writing To WIN.INI!",
                       (LPSTR)"WriteProfileString() Error!",
                       MB_OK | MB_ICONEXCLAMATION);
         }
      }

   return(0);
}


WRTCOMM.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\COMM\WRTCOMM.C

/*
 *  WriteComm
 *
 *  This program demonstrates the use of the function WriteComm.
 *  It attempts to write a specified number of characters to the
 *  communication device that has already been opened. Before
 *  attempting to do any write, the communication device must have
 *  its device control block set up properly to a correct configuration.
 */

#include "windows.h"

/* Procedure called when the application is loaded for the first time */
BOOL WinInit( hInstance )
HANDLE hInstance;
{
    WNDCLASS   wcClass;

    /* registering the parent window class */
    wcClass.hCursor        = LoadCursor( NULL, IDC_ARROW );
    wcClass.hIcon          = LoadIcon (hInstance, (LPSTR)"WindowIcon");
    wcClass.lpszMenuName   = (LPSTR)NULL;
    wcClass.lpszClassName  = (LPSTR)"Wrtcomm";
    wcClass.hbrBackground  = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcClass.hInstance      = hInstance;
    wcClass.style          = CS_HREDRAW | CS_VREDRAW;
    wcClass.lpfnWndProc    = DefWindowProc;
    wcClass.cbClsExtra     = 0;
    wcClass.cbWndExtra     = 0;

    RegisterClass( (LPWNDCLASS)&wcClass );
    return TRUE;        /* Initialization succeeded */
}

int PASCAL WinMain( hInstance, hPrevInstance, lpszCmdLine, cmdShow )
HANDLE hInstance, hPrevInstance;
LPSTR lpszCmdLine;
int cmdShow;
{
    HWND  hWnd;            /* Handle to the parent window             */
    short nCid;            /* Short integer identifying the opened
                            * communication device                    */
    short nBytes;          /* The number of characters written        */
    DCB   dcb;             /* The device control block                */

    WinInit( hInstance );

    hWnd = CreateWindow((LPSTR)"Wrtcomm",
                        (LPSTR)"Writing to Communication Devices",
                        WS_OVERLAPPEDWINDOW,
                        50,                /* x         */
                        50,                /* y         */
                        600,               /* width     */
                        250,               /* height    */
                        (HWND)NULL,        /* no parent */
                        (HMENU)NULL,       /* use class menu */
                        (HANDLE)hInstance, /* handle to window instance */
                        (LPSTR)NULL        /* no params to pass on */
                        );

    /* Make window visible according to the way the app is activated */
    ShowWindow( hWnd, cmdShow );
    UpdateWindow( hWnd );

    /* attempt to open the com1 port */
    nCid = OpenComm ((LPSTR)"COM1", 25, 25);
    if (nCid < 0)
      {
        MessageBox (hWnd, (LPSTR)"Com port not opened!!",(LPSTR)NULL,MB_OK);
        return 0;
      }

    /* the communication device control block must be set to the appropriate
     * settings of the other dumb terminal in order to read and write
     * properly
     */
    if (GetCommState (nCid, (DCB FAR *) &dcb) >= 0)
      { dcb.BaudRate = 9600;
        dcb.ByteSize = 8;
        dcb.StopBits = ONESTOPBIT;
        dcb.Parity   = NOPARITY;
        dcb.fRtsflow = FALSE;
        dcb.fDtrflow = FALSE;
        dcb.fOutX    = FALSE;
        dcb.fInX     = FALSE;
        dcb.fNull    = FALSE;
        dcb.XonLim   = 1;
        dcb.XoffLim  = 20;
      }

    SetCommState ((DCB FAR *) &dcb);

    nBytes = WriteComm (nCid, (LPSTR)"Writing to COM port #1", 22);
    if (nBytes > 0)
      MessageBox (hWnd, (LPSTR)"Written successfully", (LPSTR)"OK", MB_OK);
    else
      /* Error should be checked by calling GetCommError at this point
       * so that other communiation function will work properly
       */
      MessageBox (hWnd, (LPSTR)"Error Occurred", (LPSTR)"ERROR", MB_OK);

    /* must close the communication device before leaving the program */
    CloseComm (nCid);

    return 0;
}




YIELD.C
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\YIELD.C

/*
 *  Yield
 *  yield.c
 *
 *  This program demonstrates the use of the function Yield.
 *  It does this by simply creating a message box that tells the user that
 *  the application is going to yield control to other applications.  After
 *  the user hits the OK button, the Yield call is made.
 *
 */

 "windows.h"      /* required for all Windows applications */
 "yield.h"        /* specific to this program              */

HANDLE hInst;             /* current instance                      */

int PASCAL WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
HANDLE hInstance;         /* current instance             */
HANDLE hPrevInstance;     /* previous instance            */
LPSTR lpCmdLine;          /* command line                 */
int nCmdShow;             /* show-window type (open/icon) */
{
    HWND hWnd;            /* window handle       */
    MSG msg;              /* message             */
    HANDLE hMenu;         /* Handle to the menu  */

    if (!hPrevInstance)              /* Has application been initialized? */
        if (!YieldInit(hInstance))
            return (NULL);           /* Exits if unable to initialize     */

    hInst = hInstance;               /* Saves the current instance        */

    hMenu = LoadMenu( hInst, (LPSTR)"YieldMenu" );
                                     /*  Load the menu    */

    hWnd = CreateWindow("Yield",     /* window class      */
        "Yield Sample Application",  /* window name       */
        WS_OVERLAPPEDWINDOW,         /* window style      */
        CW_USEDEFAULT,               /* x position        */
        CW_USEDEFAULT,               /* y position        */
        CW_USEDEFAULT,               /* width             */
        CW_USEDEFAULT,               /* height            */
        NULL,                        /* parent handle     */
        hMenu,                       /* menu or child ID  */
        hInstance,                   /* instance          */
        NULL);                       /* additional info   */

    if (!hWnd)                       /* Was the window created? */
        return (NULL);

    ShowWindow(hWnd, nCmdShow);      /* Shows the window        */
    UpdateWindow(hWnd);              /* Sends WM_PAINT message  */

    while (GetMessage(&msg,     /* message structure                      */
            NULL,               /* handle of window receiving the message */
            NULL,               /* lowest message to examine              */
            NULL))              /* highest message to examine             */
        {
        TranslateMessage(&msg);  /* Translates virtual key codes           */
        DispatchMessage(&msg);   /* Dispatches message to window           */
    }
    return (msg.wParam);         /* Returns the value from PostQuitMessage */
}

BOOL YieldInit(hInstance)
HANDLE hInstance;                /* current instance           */
{
    HANDLE hMemory;              /* handle to allocated memory */
    PWNDCLASS pWndClass;         /* structure pointer          */
    BOOL bSuccess;               /* RegisterClass() result     */

    hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS));
    pWndClass = (PWNDCLASS) LocalLock(hMemory);

    pWndClass->style = NULL;
    pWndClass->lpfnWndProc = YieldWndProc;
    pWndClass->hInstance = hInstance;
    pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION);
    pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
    pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH);
    pWndClass->lpszMenuName = (LPSTR) "YieldMenu";
    pWndClass->lpszClassName = (LPSTR) "Yield";

    bSuccess = RegisterClass(pWndClass);

    LocalUnlock(hMemory);     /* Unlocks the memory    */
    LocalFree(hMemory);       /* Returns it to Windows */

    return (bSuccess);        /* Returns result of registering the window */
}

long FAR PASCAL YieldWndProc(hWnd, message, wParam, lParam)
HWND hWnd;                    /* window handle                   */
unsigned message;             /* type of message                 */
WORD wParam;                  /* additional information          */
LONG lParam;                  /* additional information          */
{
    FARPROC lpProcAbout;      /* pointer to the "About" function */
    HMENU hMenu;              /* handle to the System menu       */

    switch (message) {
        case WM_SYSCOMMAND:   /* message: command from system menu */
            if (wParam == ID_ABOUT) {
                lpProcAbout = MakeProcInstance(About, hInst);

                DialogBox(hInst,         /* current instance         */
                    "AboutBox",          /* resource to use          */
                    hWnd,                /* parent handle            */
                    lpProcAbout);        /* About() instance address */

                FreeProcInstance(lpProcAbout);
                break;
            }

            else                         /* Lets Windows process it       */
                return (DefWindowProc(hWnd, message, wParam, lParam));

        case WM_CREATE:                  /* message: window being created */

            /* Get the handle of the System menu */

            hMenu = GetSystemMenu(hWnd, FALSE);

            /* Add a separator to the menu */

            ChangeMenu(hMenu,                    /* menu handle         */
                NULL,                            /* menu item to change */
                NULL,                            /* new menu item       */
                NULL,                            /* menu identifier     */
                MF_APPEND | MF_SEPARATOR);       /* type of change      */

            /* Add new menu item to the System menu */

            ChangeMenu(hMenu,                    /* menu handle         */
                NULL,                            /* menu item to change */
                "A&bout Yield...",               /* new menu item       */
                ID_ABOUT,                        /* menu identifier     */
                MF_APPEND | MF_STRING);          /* type of change      */
            break;

        case WM_COMMAND:
            if ( wParam == IDM_YIELD )
              {
              MessageBox(hWnd,(LPSTR)"Hit OK to Give Up Control of Processor"
                              (LPSTR)"Give It Up!",MB_OK);

                        /*  Tell User what we are going to do  */

              Yield();  /*  Do it!  -  This will cause Windows to see if
                         *  are currently any other applications that wish
                         *  to run.  If there are, then control will be
                         *  given to one of those applications.
                         */

              MessageBox(hWnd,(LPSTR)"We Have Control Back!",
                              (LPSTR)"Got it Back",MB_OK);
              }
            break;

/*  Because of how quickly the whole process goes, the user will not be able
 *  notice the difference unless a very demanding application is present at
 *  the time the Yield box is selected from the menu.
 */
        case WM_DESTROY:             /* message: window being destroyed */
            PostQuitMessage(0);
            break;

        default:                     /* Passes it on if unproccessed    */
            return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (NULL);
}

BOOL FAR PASCAL About(hDlg, message, wParam, lParam)
HWND hDlg;
unsigned message;
WORD wParam;
LONG lParam;
{
    switch (message) {
        case WM_INITDIALOG:              /* message: initialize dialog box */
            return (TRUE);

        case WM_COMMAND:                 /* message: received a command */
            if (wParam == IDOK) {        /* "OK" box selected?          */
                EndDialog(hDlg, NULL);   /* Exits the dialog box        */
                return (TRUE);
            }
            break;
    }
    return (FALSE);                      /* Didn't process a message    */
}




Microsoft Windows Sample Source Code (MASM)


FINDRESA.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\APPS\FINDRESA.ASM

        title   Hardware Dependent Parameters
        %out    config
        page    ,132
OEM     segment public
dw         0,     -7999
dw         836,   -7956
dw         1663,  -7825
dw         2472,  -7608
dw         3253,  -7308
dw         3999,  -6928
dw         4702,  -6472
dw         5353,  -5945
dw         5945,  -5353
dw         6472,  -4702
dw         6928,  -4000
dw         7308,  -3253
dw         7608,  -2472
dw         7825,  -1663
dw         7956,  -836

dw         8000,  0
dw         7956,  836
dw         7825,  1663
dw         7608,  2472
dw         7308,  3253
dw         6928,  4000
dw         6472,  4702
dw         5945,  5353
dw         5353,  5945
dw         4702,  6472
dw         3999,  6928
dw         3253,  7308
dw         2472,  7608
dw         1663,  7825
dw         836,   7956

dw          0,    7999
dw         -836,  7956
dw         -1663, 7825
dw         -2472, 7608
dw         -3253, 7308
dw         -4000, 6928
dw         -4702, 6472
dw         -5353, 5945
dw         -5945, 5353
dw         -6472, 4702
dw         -6928, 3999
dw         -7308, 3253
dw         -7608, 2472
dw         -7825, 1663
dw         -7956, 836

dw         -7999, -0
dw         -7956, -836
dw         -7825, -1663
dw         -7608, -2472
dw         -7308, -3253
dw         -6928, -4000
dw         -6472, -4702
dw         -5945, -5353
dw         -5353, -5945
dw         -4702, -6472
dw         -3999, -6928
dw         -3253, -7308
dw         -2472, -7608
dw         -1663, -7825
dw         -836 , -7956
OEM     ends
end



GETTIMER.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\TIME\GETTIMER.ASM

; get the time more efficiently than cmerge and DOSCALL() do

include cmacros.inc

time  struc
  hour  dw  ?
  minute  dw  ?
  second  dw  ?
time  ends

assumes CS,CODE
assumes DS,DATA

sBegin   CODE

cProc  GetTime, <PUBLIC, NEAR>
  parmW  pTime        ; pointer to the structure to fill
cBegin
  mov  ax, 2c00h      ; get time
  int  21h
  mov  bx, pTime
  cmp  ch, 12      ; if hour <12
  jl  lt12      ; we're ok
  sub  ch,12      ; else adjust it
lt12:
  xor  ax,ax
  mov  al,ch
  mov  [bx].hour, ax
  mov  al,cl
  mov  [bx].minute, ax
  mov  al,dh
  mov  [bx].second, ax
cEnd
sEnd  CODE
  END


LIBINIT.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\DDE\DDESPY\LIBINIT.ASM

?PLM = 1;
?WIN = 1;
memS = 1

include cmacros.inc

externFP    <LocalInit>
externFP    <UnlockSegment>

; PUBLIC definition of LIBINST, the library instance
sBegin  DATA
        assumes DS,DATA
        PUBLIC  _LIBINST
_LIBINST dw     ?
sEnd    DATA

sBegin CODE
assumes CS,CODE

cProc myastart,<PUBLIC,FAR>
cBegin
        ;;
        ;; DS = automatic data segment.
        ;; CX = size of heap.
        ;; DI = module handle.
        ;; ES:SI = address of command line (not used).
        ;;

        mov    _LIBINST,di
        xor    ax,ax
        cCall  LocalInit,<ds,ax,cx>
        mov    ax,0ffffh
        cCall  UnlockSegment,<ax>
cEND    myastart

sEnd   CODE

end myastart


LIBINIT.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\HOOKS\JOURNAL\LIBINIT.ASM

?PLM = 1;
?WIN = 1;
memS = 1

include cmacros.inc

externFP    <LocalInit>
externFP    <UnlockSegment>

; PUBLIC definition of LIBINST, the library instance
sBegin  DATA
        assumes DS,DATA
        PUBLIC  _LIBINST
_LIBINST dw     ?
sEnd    DATA

sBegin CODE
assumes CS,CODE

cProc myastart,<PUBLIC,FAR>
cBegin
        ;;
        ;; DS = automatic data segment.
        ;; CX = size of heap.
        ;; DI = module handle.
        ;; ES:SI = address of command line (not used).
        ;;

        mov    _LIBINST,di
        xor    ax,ax
        cCall  LocalInit,<ds,ax,cx>
        mov    ax,0ffffh
        cCall  UnlockSegment,<ax>
cEND    myastart

sEnd   CODE

end myastart


LIBINIT.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\LIBRARY\LIBINIT.ASM

?PLM = 1;
?WIN = 1;
memS = 1

include cmacros.inc

externFP    <LocalInit>
externFP    <UnlockSegment>

; PUBLIC definition of LIBINST, the library instance
sBegin  DATA
        assumes DS,DATA
        PUBLIC  _LIBINST
_LIBINST dw     ?
sEnd    DATA

sBegin CODE
assumes CS,CODE

cProc myastart,<PUBLIC,FAR>
cBegin
        ;;
        ;; DS = automatic data segment.
        ;; CX = size of heap.
        ;; DI = module handle.
        ;; ES:SI = address of command line (not used).
        ;;

        mov    _LIBINST,di
        xor    ax,ax
        cCall  LocalInit,<ds,ax,cx>
        mov    ax,0ffffh
        cCall  UnlockSegment,<ax>
cEND    myastart

sEnd   CODE

end myastart


STACK.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\MEMORY\STACK\STACK.ASM

;
; WINDOWS STACK USAGE CHECKER
;
; This code checks for the amount of stack being used by a Windows applicatio
; It does this check by initializing the stack to a known value, then going
; from the end of stack up until it finds the first value changed.  If the
; first value checked is changed, then it assumes the stack overflowed.
;
; The way it finds the end of the stack is by the variable rsrvptrs[6].  This
; is initialized by the Windows initialization code.  Also, the start of the
; stack is rsrvptrs[A].  rsrvptrs[8] is the stack low-water mark, but this is
; only set if _chkstk is called, and Windows doesn't call this on its entry
; points (why, I don't know).
;
; The routine InitStackUsed() initializes the stack to a known value.  The
; routine ReportStackUsed() returns an integer value which is the amount of
; stack space used, -1 if stack overflow was detected.
;
; Written 10/87 by Bill Turner.  Original concept by Bill Turner (modified fr
; similar code for another environment)
;

;
; See what memory model to use for the stack checking routines.  This is
; specified when the module is assembled by specifying -D?S for small,
; -D?M for medium.
;

if1
    ifdef ?S
        memS = 1
        %out ! Compiling for SWINLIBC.LIB
    else
        memM = 1
        %out ! Compiling for MWINLIBC.LIB/LWINLIBC.LIB
    endif
endif

;
;   Now include the Windows macro definition file.
;

.xlist
?PLM = 1;
?WIN = 1;
include cmacros.inc
.list

sBegin  DATA
        externW rsrvptrs
sEnd    DATA

sBegin  CODE
assumes CS,CODE
assumes DS,DATA

        PUBLIC  InitStackUsed
        PUBLIC  ReportStackUsed

;
; void PASCAL InitStackUsed();
;
; This routine initializes the stack to a known value.  It uses the STOSW
; instruction, and therefore wipes ES, DI, AX, and CX.
;

cProc   InitStackUsed
cBegin

        push    ss
        pop     es
        mov     di, rsrvptrs[6]         ; minimum SP value
        mov     cx, sp
        sub     cx, di                  ; space from end of stack to current
                                        ; SP value (in bytes)
        shr     cx,1                    ; convert to word count
        mov     ax, 0AAAAh              ; "known value" for comparison
        cld                             ; move to high memory
        rep     stosw                   ; fill memory

cEnd


;
; int PASCAL ReportStackUsed();
;
; This checks to see how much stack was actually used.  If the min SP value
; has been changed (ss:rsrvptrs[6]), then assume a stack overflow has occured
; Otherwise, scan through memory until a changed address is found, and subtra
; the address from the maximum SP value (rsrvptrs[A]).  This is the amount of
; stack space used.  This routine wipes out ES, DI, AX, and CX.
;

cProc ReportStackUsed
cBegin

        xor     cx, cx
        dec     cx              ; put -1 into CX -- so that REPZ will go unti
                                ; an address that changed is found.
        push    ss
        pop     es
        mov     di, rsrvptrs[6]
        mov     ax, 0AAAAh      ; "known value" stack was initialized to
        cld                     ; move to high memory
        repz    scasw
;
; At this point, DI is the next word after the change was detected.  Decremen
; by one word, and calculate stack usage.
;
        cmp     di, rsrvptrs[6]         ; same as minimum value:
        jz      overflowed              ; YES, report overflow
        sub     di, rsrvptrs[0Ah]       ; difference in bytes (negative value
        mov     ax, di                  ; move into AX for return.
        neg     ax                      ; and make a positive number
        jmp     do_rtn

overflowed:
        xor     ax, ax
        dec     ax                      ; move -1 into AX

do_rtn:                                 ; dummy label for end of procedure

cEnd

sEnd    CODE

        end


WSPAWN.ASM
CD-ROM Disc Path:   \SAMPCODE\WIN_LRN\SPAWN\WSPAWN.ASM




include cmacros.inc

externFP   <GlobalCompact>

createSeg   ASMCODE,ASMCODE,PARA,PUBLIC,ASMCODE

;;
;;  Int21Function4B cannot be a discardable segment.  If the segment
;;  were discardable, the int21 interrupt might cause it to be discarded
;;  and then reread from disk.  This would set stackSS and stackSP to 0.
;;  Upon return from int21, SS would be set to 0 and SP would be set to
;;  0.
;;
;;  Warning:  the code is not reentrant.  Multiple sp's cannot be saved.
;;  Warning:  In applications SS == DS by default.  If the DS should move
;;  the stored SS would be invalidated.  For maximum reliability it is
;;  recommended that LockData(), UnlockData() call bracket the call to
;;  int21function4B.
;;  Warning:  Should the code segment move using the debugging KERNEL,
;;  the segment will be checksummed and the write of SS:SP into the
;;  code segment detected as a fatal error.  To avoid this extraneous
;;  ( in this one instance ) error condition,
;;  use the non-debugging kernel or place the code in a fixed segment.
;;

assumes CS,ASMCODE
assumes DS,DATA


sBegin DATA
sEnd   DATA

sBegin ASMCODE
  stackSS dw 0
  stackSP dw 0

cProc   Int21Function4B,<PUBLIC,FAR>,<ax,bx,cx,dx,si,di,es,ds>
  parmB mode
  parmD path
  parmD execblock
cBegin
      mov ax,-1
      cCall GlobalCompact,<ax,ax>
  mov cs:[stackSS],ss         ;; EXEC destroys all register. Save SS:SP.
  mov cs:[stackSP],sp
  mov al,mode
  lds dx,path
  les bx,execblock
  mov ah,4bh
  int 21h
  mov ss,cs:[stackSS]
  mov sp,cs:[stackSP]
; AX is return value
cEnd

sEnd ASMCODE
END