File:  [WindowsNT SDKs] / q_a / samples / bezier / bezier.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:29:37 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntsdk-oct-1992, HEAD
Microsoft Windows NT Build 328 10-12-1992

/**************************************************************************\
*  bezier.c -- sample program demonstrating beziers.
*
*  written Feb 92 by Steve Firebaugh
*
* The user is able to place control points on the screen, and then
*  drag them.  The PolyBezier() call is made to dynamically show the
*  resulting curve.
\**************************************************************************/


#include <windows.h>
#include "bezier.h"



/**************************************************************************\
*
*  function:  WinMain()
*
*  input parameters:  c.f. generic sample
*
\**************************************************************************/
int APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance,
                     LPSTR lpCmdLine, int nCmdShow)
{
    HANDLE hInst;
    HWND   hwndMain;
    MSG   msg;

    UNREFERENCED_PARAMETER( lpCmdLine );


    /* Check for previous instance.  If none, then register class. */
    if (!hPrevInstance) {
        WNDCLASS  wc;

        wc.style = NULL;
        wc.lpfnWndProc = (WNDPROC)MainWndProc;

        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = LoadIcon(hInstance, "bezierIcon");
        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = GetStockObject(LTGRAY_BRUSH);
        wc.lpszMenuName =  NULL;
        wc.lpszClassName = "bezier";

        if (!RegisterClass(&wc)) return (FALSE);
    }  /* class registered o.k. */


    /* Create the main window.  Return false if CreateWindow() fails */
    hInst = hInstance;

    hwndMain = CreateWindow(
        "bezier",
        "PolyBezier",
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);

    if (!hwndMain) return (FALSE);
    ShowWindow(hwndMain, nCmdShow);
    UpdateWindow(hwndMain);


    /* Loop getting messages and dispatching them. */
    while (GetMessage(&msg,NULL, NULL, NULL)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (msg.wParam);
}



/**************************************************************************\
*
*  function:  MainWndProc()
*
*  input parameters:  normal window procedure parameters.
*
*  global variables: none.
*
*  static variables:
*   svPoints[] - array that stores the points for the GDI calls.
*   svIndex    - when tracking, the index of the point we are modifying.
*   svNumDown  - the number of points currently in the client area.
*   hPen*     - Pens to draw the lines, curves, or erase with.
\**************************************************************************/
LONG APIENTRY MainWndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
static HANDLE hPenGrey, hPenLine, hPenBezier;
static POINT svPoints [MAXPOINTS];
static int   svNumDown;
static int   svIndex;

  switch (message) {


    /**********************************************************************\
    *  WM_CREATE
    *
    * Initialize the static variables.
    *  Then create three pens for drawing with later.
    \**********************************************************************/
    case WM_CREATE:
        svNumDown = NONE;
        svIndex = NONE;
        hPenLine   = CreatePen (PS_SOLID, 1, (COLORREF) 0x01000002);
        hPenBezier = CreatePen (PS_SOLID, 1, (COLORREF) 0x01000005);
        hPenGrey   = CreatePen (PS_SOLID, 1, (COLORREF) 0x01000007);
    break;


    /**********************************************************************\
    *  WM_DESTROY
    *
    * Complement of the WM_CREATE message.  Delete the pens that were
    *  created and then call postquitmessage.
    \**********************************************************************/
    case WM_DESTROY:
      DeleteObject (hPenLine);
      DeleteObject (hPenBezier);
      DeleteObject (hPenGrey);

      PostQuitMessage(0);
    break;




    /**********************************************************************\
    *  WM_LBUTTONDOWN
    *
    * Hittest to see if the user is selecting an existing point.
    *  If not, check for point overflow.
    *  If o.k. then add a new point to the current list.
    \**********************************************************************/
    case WM_LBUTTONDOWN: {
      int i;
      RECT rectNear;

      /* Construct a rectangle around the mouse point. */
      rectNear.left   = LOWORD(lParam) - HITSIZE;
      rectNear.right  = LOWORD(lParam) + HITSIZE;
      rectNear.top    = HIWORD(lParam) - HITSIZE;
      rectNear.bottom = HIWORD(lParam) + HITSIZE;

      /* step through all points so far.  hittest mouse location against
       *  each one.  If we hit one, set index, capture mouse and exit
       *  window procedure.
       */
      for (i = 0; i<= svNumDown; i++) {
        if (PtInRect (&rectNear, svPoints[i])) {
          svIndex = i;
          SetCapture (hwnd);
          return NULL;
        }
      }

      /* we did not hit an old point, watch for overflow. */
      if (svNumDown == (MAXPOINTS-1)) {
        MessageBox (hwnd,
                    "Points may be dragged with left mouse button.",
                    "No more points allowed",
                    MB_OK | MB_ICONSTOP);
        return NULL;
      }

      /* don't have old point, still room for more.  Put down one more. */
      if (GetCapture() != hwnd) {
        svNumDown++;
        svPoints[svNumDown].x = LOWORD(lParam);
        svPoints[svNumDown].y = HIWORD(lParam);
        InvalidateRect (hwnd, NULL, TRUE);
      }

    }break;


    /**********************************************************************\
    *  WM_MOUSEMOVE
    *
    * If the curve is tracking the mouse, the erase the old curve by drawing
    *  over it with the grey pen.  Redraw the new curves with the proper pens.
    \**********************************************************************/
    case WM_MOUSEMOVE: {
      if (GetCapture() == hwnd) {
        HDC hdc;

        hdc = GetDC (hwnd);

        /* Erase the old lines and curves. */
        SelectObject(hdc, hPenGrey);
        Polyline (hdc, svPoints, svNumDown+1);
        PolyBezier (hdc, svPoints, svNumDown+1);

        /* Change the point to match the new mouse position. */
        svPoints[svIndex].x = (int)(short)LOWORD(lParam);
        svPoints[svIndex].y = (int)(short)HIWORD(lParam);

        SelectObject(hdc, hPenLine);
        Polyline (hdc, svPoints, svNumDown+1);
        SelectObject(hdc, hPenBezier);
        PolyBezier (hdc, svPoints, svNumDown+1);

        ReleaseDC (hwnd, hdc);
      }
    }break;



    /**********************************************************************\
    *  WM_LBUTTONUP
    *
    * Finished tracking.  Release the mouse capture.
    \**********************************************************************/
    case WM_LBUTTONUP:
      SetCapture (NULL);
    break;


    /**********************************************************************\
    *  WM_RBUTTONDOWN
    *
    * Re-Initialize the static variables, and force a repaint
    \**********************************************************************/
    case WM_RBUTTONDOWN:
      svNumDown = NONE;
      svIndex = NONE;
      InvalidateRect (hwnd, NULL, TRUE);
    break;



    /**********************************************************************\
    *  WM_PAINT
    *
    * Draw the polyline then draw the PolyBezier
    \**********************************************************************/
    case WM_PAINT: {
      HDC hdc;
      PAINTSTRUCT ps;

      hdc = BeginPaint(hwnd, &ps);

      SelectObject(hdc, hPenLine);
      Polyline (hdc, svPoints, svNumDown+1);
      SelectObject(hdc, hPenBezier);
      PolyBezier (hdc, svPoints, svNumDown+1);

      EndPaint (hwnd, &ps);
    } return FALSE;


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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.