|
|
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);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.