Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
51
Добавлен:
06.05.2013
Размер:
45.77 Кб
Скачать
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "fy03.h"

#define NUMBUTTONS      5
#define NUMPARTS        5

void InitToolbar ();            // Initialize toolbar
void InitStatus (HWND hwnd);            // Initialize satus bar
LRESULT CALLBACK WindowFunc (HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK DialogFunc (HWND, UINT, WPARAM, LPARAM);
VOID CALLBACK Timer1Proc(HWND, UINT, UINT, DWORD);
VOID CALLBACK Timer2Proc(HWND, UINT, UINT, DWORD);

char szWinName [] = "MainWindow";       /* Window class name */
HINSTANCE hInst;
int nMaxX, nMaxY;                                       // Window size
HDC     memDC;                                                  // Virtual window DC
HBITMAP hBit;                                           // Bitmap (in memory)
HBRUSH hBrush;
//HBRUSH hBrush, hOldBrush;                     // Brush handles
// Pen handles
HPEN hOldPen;
HPEN hRedPen, hGreenPen, hBluePen, hDotPen;
int nTimer = !0, nCount = 0, nOverheads = !0;

TBBUTTON tbButtons [NUMBUTTONS];        // Buttons on toolbar
HWND hToolWnd;                                          // Toolbar handle
RECT tbRect;
int nYtb;
HWND hStatusWnd;
RECT stRect;
int nYst;
int parts [NUMPARTS];
char str [81];
HWND hMainWnd;
HANDLE hFuncSemaphore, hFunc;
HANDLE hEvent1, hEvent2;
DWORD FuncID;
DWORD Func (LPVOID param);
DWORD FuncCount (LPVOID param);
//
void vSetTimers (void);
void vKillTimers (void);
int nStr2Int (char *lpszStr, int nDef, int nMin, int nMax);
void vCalcFuncs (void);
void vDrawAxes (void);
void vClearMainWindow (void);
int nBoth (void);
void vTime2Str (char *lpszStr);
void vSetZero (char *lpszStr);
int nGetDelta (int nDelta, DWORD dwInit, DWORD *lpdwResult);
int nDelta1 = DELTA1_DEF, nDelta2 = DELTA2_DEF;
int nT;
double dStep = (X_MAX - X_MIN) / (POINTS - 1);
double dX [POINTS], dXmin, dXmax, dDx;
double dY1 [POINTS], dY1min, dY1max, dDy1;
double dY2 [POINTS], dY2min, dY2max, dDy2;
double dY3 [POINTS], dY3min, dY3max, dDy3;
int nX1left, nX1right, nDx1, nY1top, nY1bottom, nDy1;
int nX2left, nX2right, nDx2, nY2top, nY2bottom, nDy2;
int nX3left, nX3right, nDx3, nY3top, nY3bottom, nDy3;
int nI1, nI2, nI3, nI1old, nI2old;
int nX1td, nY1t, nX1tt, nX1tg, nX1ttt;
int nX2td, nY2t, nX2tt, nX2tg, nX2ttt;
RECT Rect1, Rect2, Rect3;
char szDelta [] = "Delta: ";
char szTime [] = "Time: ";
char szGet [] = "GetTickCount: ";
char szTotal [] = "Total time: ";
char szEmpty1 [] = "       ";                   // 7 spaces
char szEmpty2 [] = "            ";              // 12 spaces
char szEmpty3 [] = "          ";                // 10 spaces

int WINAPI WinMain (HINSTANCE hThisInst,        /* дескриптор текущего экземпляра */
                                        HINSTANCE hPrevInst,    /* то же предыдущего (всегда NULL) */
                                        LPSTR lpszArgs,                 /* аргументы командной строки */
                                        int nWinMode)                   /* способ визуализации окна */
{
HWND hwnd;              // Main window handle
MSG msg;                // Messages buffer
WNDCLASS wcl;   // Window class definition
HACCEL hAccel;  // Accelerators table

// Window class is defined
wcl.hInstance = hThisInst;              // Tihs application handle
wcl.lpszClassName = szWinName;  // Window class name
wcl.lpfnWndProc = WindowFunc;   // Window function
wcl.style = 0;                                  // Window style (0 - by default)

wcl.hIcon = LoadIcon (NULL, IDI_APPLICATION);   // Standard icon
wcl.hCursor = LoadCursor (NULL, IDC_ARROW);             // Stabdard cursor
wcl.lpszMenuName = "FY03";                                              // Main menu name (NULL - without)

wcl.cbClsExtra = 0;             // Extra data for class (0 - without)
wcl.cbWndExtra = 0;             // Extra data for window (0 - wihtout)

wcl.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);      // Window background

// Window class is registered
if (!RegisterClass (&wcl)) return 0;

// Window is created
hwnd = CreateWindow (szWinName,                                         // Window class name
                                         "Crazy timers",                                // Window title
                                         WS_OVERLAPPEDWINDOW,                   // Window style
                                         CW_USEDEFAULT, CW_USEDEFAULT,  // Upper left corner
                                         CW_USEDEFAULT, CW_USEDEFAULT,  // Width, height
                                         HWND_DESKTOP,                                  // Parent window handle (may be NULL)
                                         NULL,                                                  // Main menu handle
                                         hThisInst,                                             // Application handle
                                         NULL);                                                 // Extra info pointer

hInst = hThisInst;
hMainWnd = hwnd;
hAccel = LoadAccelerators (hThisInst, "FY03");          // Load accelerators

InitToolbar ();                                 // Initialize toolbar
InitCommonControls ();                  // Initialize common controls

// Create toolbar window
hToolWnd = CreateToolbarEx (hwnd,                                       // Parent window handle
                                                        WS_VISIBLE | WS_CHILD |
                                                        WS_BORDER | TBSTYLE_TOOLTIPS,   // Window style
                                                        ID_TOOLBAR,                     // Toolbar ID
                                                        NUMBUTTONS,                     // Buttons number
                                                        hThisInst,                              // Running application handle
                                                        IDTB_BMP,                               // Bitmap ID
                                                        tbButtons,                              // Buttons info (array of TBUTTON struct)
                                                        NUMBUTTONS,                     // Buttons number
                                                        0, 0,                                   // Buttons width & height (0 --- auto)
                                                        16, 16,                         // Bitmap width & height
                                                        sizeof (TBBUTTON));     // Structure TBUTTON size

ShowWindow (hwnd, nWinMode);    // Show window

GetWindowRect (hToolWnd, &tbRect);
nYtb = tbRect.bottom - tbRect.top;
vSetTimers ();

UpdateWindow (hwnd);                    // Update window
vCalcFuncs ();

// Message cycle is run
while (GetMessage (&msg,        // Message
                                   NULL,        // Window handle (NULL - all windows)
                                   0,           // First message
                                   0))          // Last message  (0, 0 - all messages)
{
        if (!TranslateAccelerator (hwnd, hAccel, &msg)) {
                TranslateMessage (&msg);        // Keyboard enable
                DispatchMessage (&msg);         // Return to windows
        }
}

vKillTimers ();
return msg.wParam;
}

LRESULT CALLBACK WindowFunc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;                        // Device context
PAINTSTRUCT paintstruct;        // Information for an application
LPTOOLTIPTEXT TTtext;
int i;

switch (message) {
case WM_CREATE :
// Get screen size
	nMaxX = GetSystemMetrics (SM_CXSCREEN);
    nMaxY = GetSystemMetrics (SM_CYSCREEN);
// Create memory bitmap
    hdc = GetDC (hwnd);                     // Get device context (screen)
    memDC = CreateCompatibleDC (hdc);       // Create device context (memory)
    hBit = CreateCompatibleBitmap (hdc, nMaxX, nMaxY);      // Create bitmap in memory
    SelectObject (memDC, hBit);                     // Select object into specified DC
    hBrush = (HBRUSH) GetStockObject (WHITE_BRUSH);  // Handle to the predefined brush
    SelectObject (memDC, hBrush);           // Select object into specified DC
    PatBlt (memDC, 0, 0, nMaxX, nMaxY, PATCOPY);    // Fills selected region
// "Create" new pens
    hRedPen = CreatePen (PS_SOLID, 1, RGB (255, 0, 0));
    hGreenPen = CreatePen (PS_SOLID, 1, RGB (0, 255, 0));
    hBluePen = CreatePen (PS_SOLID, 1, RGB (0, 0, 255));
    hDotPen = CreatePen (PS_DOT, 1, RGB (190, 190, 190));
// Save default pen
    hOldPen = (HPEN) SelectObject (memDC, hRedPen);
    SelectObject (memDC, hOldPen);
    ReleaseDC (hwnd, hdc);          // Release device context (screen)
// Initialize status bar
    InitStatus (hwnd);
    GetWindowRect (hStatusWnd, &stRect);
    nYst = stRect.bottom - stRect.top;
// Create semaphore
    if ((hFuncSemaphore = CreateSemaphore (NULL, 1, 1, "Semaphore1")) == NULL) {
        MessageBox (hwnd, "Cannot create semaphore", "Error", MB_OK);
        SendMessage (hwnd, WM_DESTROY, 0, 0);
    }
// Create events
    if ((hEvent1 = CreateEvent (NULL, TRUE, FALSE, "Event1")) == NULL) {
        MessageBox (hwnd, "Cannot create event", "Error", MB_OK);
        SendMessage (hwnd, WM_DESTROY, 0, 0);
    }
    if ((hEvent2 = CreateEvent (NULL, TRUE, FALSE, "Event2")) == NULL) {
        MessageBox (hwnd, "Cannot create event", "Error", MB_OK);
        SendMessage (hwnd, WM_DESTROY, 0, 0);
    }
    break;
case WM_NOTIFY :                        // Request from tooltips
    TTtext = (LPTOOLTIPTEXT) lParam;
    if (TTtext->hdr.code == TTN_NEEDTEXT) {
        switch (TTtext->hdr.idFrom) {
        case ID_SETPARMS :
            TTtext->lpszText = "Set parameters";
            break;
        case ID_RUN :
            TTtext->lpszText = "Run";
            break;
        case ID_STOP :
            TTtext->lpszText = "Stop";
            break;
        }
    }
    break;
case WM_COMMAND :                       // Menu command
    switch (LOWORD (wParam)) {
    case ID_SETPARMS :
        if (WaitForSingleObject (hFuncSemaphore, 10) == WAIT_TIMEOUT) break;
        DialogBox (hInst, "FY03", hwnd, DialogFunc);
        ReleaseSemaphore (hFuncSemaphore, 1, NULL);
        break;
    case ID_RUN :
        if (WaitForSingleObject (hFuncSemaphore, 10) == WAIT_TIMEOUT) break;
        vClearMainWindow ();
		if (nTimer) {
	        if ((hFunc = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) Func,
				NULL, 0, &FuncID)) == NULL) {
		        MessageBox (hwnd, "Cannot create thread", "Error", MB_OK);
			    SendMessage (hwnd, WM_DESTROY, 0, 0);
	        }
		}
		else {
	        if ((hFunc = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) FuncCount,
				NULL, 0, &FuncID)) == NULL) {
		        MessageBox (hwnd, "Cannot create thread", "Error", MB_OK);
			    SendMessage (hwnd, WM_DESTROY, 0, 0);
	        }
		}
        SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 4, (LPARAM) "Running...");
        break;
    case ID_STOP :
        if (WaitForSingleObject (hFuncSemaphore, 10) == WAIT_TIMEOUT) {
            PostThreadMessage (FuncID, WM_QUIT, 0, 0);
//                      TerminateThread (hFunc, 0);
//                      ReleaseSemaphore (hFuncSemaphore, 1, NULL);
//                      SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 3, (LPARAM) "Stopped");
        }
        else ReleaseSemaphore (hFuncSemaphore, 1, NULL);
        break;
    case ID_EXIT :
        SendMessage (hwnd, WM_DESTROY, 0, 0);
        break;
    case ID_HELP :
        MessageBox (hwnd, "Лень мне сегодня...", "Help", MB_OK);
        break;
    }
	break;
case WM_PAINT :
    hdc = BeginPaint (hwnd, &paintstruct);  // Get device context (screen)
    BitBlt (hdc, 0, nYtb, nMaxX, nMaxY, memDC, 0, 0, SRCCOPY);      // Copy regions
    EndPaint (hwnd, &paintstruct);                  // Release device context
    break;
case WM_SIZE :
    SendMessage (hToolWnd, WM_SIZE, wParam, lParam);
// Set parts number
    GetClientRect (hwnd, &stRect);
    for (i = 0; i < NUMPARTS; i++)
        parts [i] = stRect.right / NUMPARTS * (i + 1);
    SendMessage (hStatusWnd, SB_SETPARTS, (WPARAM) NUMPARTS, (LPARAM) parts);
    SendMessage (hStatusWnd, WM_SIZE, wParam, lParam);
    break;
case WM_DESTROY :                       // Quit
    CloseHandle (hEvent2);
    CloseHandle (hEvent1);
    CloseHandle (hFuncSemaphore);
    DeleteObject (hDotPen);
    DeleteObject (hBluePen);
    DeleteObject (hGreenPen);
    DeleteObject (hRedPen);
    DeleteDC (memDC);               // Delete virtual memory
    PostQuitMessage (0);
    break;
default :                                       // Default (to windows)
    return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}

BOOL CALLBACK DialogFunc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int nTimerTmp, nCountTmp, nOver;

switch (message) {
case WM_INITDIALOG :            // Initialize listbox
	sprintf (str, "%d", nDelta1);
    SetDlgItemText (hwnd, ID_DELTA1, str);
    sprintf (str, "%d", nDelta2);
    SetDlgItemText (hwnd, ID_DELTA2, str);
	nTimerTmp = nTimer; nCountTmp = nCount, nOver = nOverheads;
	SendDlgItemMessage (hwnd, ID_TIMER, BM_SETCHECK, nTimerTmp, 0);
	SendDlgItemMessage (hwnd, ID_COUNT, BM_SETCHECK, nCountTmp, 0);
	SendDlgItemMessage (hwnd, ID_OVERHEADS, BM_SETCHECK, nOver, 0);
    return 1;
case WM_CLOSE :
    return 1;
case WM_DESTROY :
    return 1;
case WM_COMMAND :                       // Command
    switch (LOWORD (wParam)) {
    case ID_CANCEL : EndDialog (hwnd, 0); return 1;
    case ID_OK :                            // Enter end
        GetDlgItemText (hwnd, ID_DELTA1, str, 80);
        nDelta1 = nStr2Int (str, DELTA1_DEF, DELTA1_MIN, DELTA1_MAX);
        GetDlgItemText (hwnd, ID_DELTA2, str, 80);
        nDelta2 = nStr2Int (str, DELTA2_DEF, DELTA2_MIN, DELTA2_MAX);
		nTimer = nTimerTmp; nCount = nCountTmp; nOverheads = nOver;
		if (nTimer)
	        SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 0, (LPARAM) "Set/Kill Timer");
		else
	        SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 0, (LPARAM) "GetTickCount");
        sprintf (str, "Delta1: %d ms", nDelta1);
        SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 1, (LPARAM) str);
        sprintf (str, "Delta2: %d ms", nDelta2);
        SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 2, (LPARAM) str);
		if (nOverheads)
			SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 3, (LPARAM) "Overheads: allow");
		else
			SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 3, (LPARAM) "Overheads: deny");
        vKillTimers ();
        ResetEvent (hEvent1); ResetEvent (hEvent2);
        vSetTimers ();
        EndDialog (hwnd, 1);
        return 1;
	case ID_TIMER :
		nTimerTmp = !0; nCountTmp = 0;
//		SendDlgItemMessage (hwnd, ID_TIMER, BM_SETCHECK, nTr, 0);
//		SendDlgItemMessage (hwnd, ID_COUNT, BM_SETCHECK, nCt, 0);
		return 1;
	case ID_COUNT :
		nTimerTmp = 0; nCountTmp = !0;
//		SendDlgItemMessage (hwnd, ID_TIMER, BM_SETCHECK, nTr, 0);
//		SendDlgItemMessage (hwnd, ID_COUNT, BM_SETCHECK, nCt, 0);
		return 1;
	case ID_OVERHEADS :
		nOver = !nOver;
		SendDlgItemMessage (hwnd, ID_OVERHEADS, BM_SETCHECK, nOver, 0);
		break;
    case ID_SETDEF :
        sprintf (str, "%d", DELTA1_DEF);
        SetDlgItemText (hwnd, ID_DELTA1, str);
        sprintf (str, "%d", DELTA2_DEF);
        SetDlgItemText (hwnd, ID_DELTA2, str);
		nTimerTmp = !0; nCountTmp = 0;
		SendDlgItemMessage (hwnd, ID_TIMER, BM_SETCHECK, nTimerTmp, 0);
		SendDlgItemMessage (hwnd, ID_COUNT, BM_SETCHECK, nCountTmp, 0);
		nOver = !0;
		SendDlgItemMessage (hwnd, ID_OVERHEADS, BM_SETCHECK, nOver, 0);
        return 1;
    }
}
return 0;
}

int nBoth (void)
{
        if (nDelta1 >= nDelta2) {
                if (nI1old != nI1) {
                        nI1old = nI1; return (TRUE);
                }
                else return (FALSE);
        }
        else {
                if (nI2old != nI2) {
                        nI2old = nI2; return (TRUE);
                }
                else return (FALSE);
        }
}

void vSetZero (char *lpszStr)
{
        while (*lpszStr == ' ') {*lpszStr = '0'; lpszStr++;}
}

void vTime2Str (char *lpszStr)
{
char szT1 [13], szT2 [5];
SYSTEMTIME Time;

        GetLocalTime (&Time);
        sprintf (szT1, "%2d:", Time.wHour); vSetZero (szT1);
        sprintf (szT2, "%2d:", Time.wMinute); vSetZero (szT2); strcat (szT1, szT2);
        sprintf (szT2, "%2d:", Time.wSecond); vSetZero (szT2); strcat (szT1, szT2);
        sprintf (szT2, "%3d", Time.wMilliseconds); vSetZero (szT2); strcat (szT1, szT2);
        strcpy (lpszStr, szT1);
}

DWORD Func (LPVOID param)
{
int nEnd1, nEndTime1, nX1, nY1, nX1old, nY1old;
int nEnd2, nEndTime2, nX2, nY2, nX2old, nY2old;
int nX3, nY3, nX3old, nY3old;
int nI1old, nI2old;
DWORD nT1s, nT1e, nT2s, nT2e;
MSG Msg;

vDrawAxes ();
nI1 = nI2 = nI3 = 0;
nI1old = nI2old = 0;
nEnd1 = nEnd2 = FALSE; nEndTime1 = nEndTime2 = TRUE;
nX1old = nX1left + (int) ((dX [nI1] - dXmin) * nDx1 / dDx);
nY1old = nY1bottom - (int) ((dY1 [nI1] - dY1min) * nDy1 / dDy1);
nX2old = nX2left + (int) ((dX [nI2] - dXmin) * nDx2 / dDx);
nY2old = nY2bottom - (int) ((dY2 [nI2] - dY2min) * nDy2 / dDy2);
nX3old = nX3left + (int) ((dX [nI3] - dXmin) * nDx3 / dDx);
nY3old = nY3bottom - (int) ((dY3 [nI3] - dY3min) * nDy3 / dDy3);
nT1s = GetTickCount (); nT2s = GetTickCount ();
ResetEvent (hEvent1); ResetEvent (hEvent2);
while (1) {
        if (nI1 < POINTS - 1) {
                if (WaitForSingleObject (hEvent1, 10) != WAIT_TIMEOUT) {
                        nI1++;
                        nX1 = nX1left + (int) ((dX [nI1] - dXmin) * nDx1 / dDx);
                        nY1 = nY1bottom - (int) ((dY1 [nI1] - dY1min) * nDy1 / dDy1);
                        SelectObject (memDC, hRedPen);
                        MoveToEx (memDC, nX1old, nY1old, NULL);
                        LineTo (memDC, nX1, nY1);
                        nX1old = nX1; nY1old = nY1;
						if (nOverheads) {
	                        TextOut (memDC, nX1td, nY1t, szEmpty1, strlen (szEmpty1));
	                        sprintf (str, "%d", nDelta1 * nI1);
	                        TextOut (memDC, nX1td, nY1t, str, strlen (str));
	                        TextOut (memDC, nX1tt, nY1t, szEmpty2, strlen (szEmpty2));
	                        vTime2Str (str);
	                        TextOut (memDC, nX1tt, nY1t, str, strlen (str));
	                        TextOut (memDC, nX1tg, nY1t, szEmpty3, strlen (szEmpty3));
	                        sprintf (str, "%ld", GetTickCount ());
	                        TextOut (memDC, nX1tg, nY1t, str, strlen (str));
						}
                        InvalidateRect (hMainWnd, &Rect1, FALSE);
                        ResetEvent (hEvent1);
                }
        }
        else {
			nEnd1 = TRUE;
			if (nEndTime1) {
				nT1e = GetTickCount ();
				sprintf (str, "%ld", nT1e - nT1s);
				TextOut (memDC, nX1ttt, nY1t, str, strlen (str));
				TextOut (memDC, nX1td, nY1t, szEmpty1, strlen (szEmpty1));
				sprintf (str, "%d", nDelta1 * nI1);
				TextOut (memDC, nX1td, nY1t, str, strlen (str));
				InvalidateRect (hMainWnd, &Rect1, FALSE);
				nEndTime1 = FALSE;
			}
		}
        if (nI2 < POINTS - 1) {
                if (WaitForSingleObject (hEvent2, 10) != WAIT_TIMEOUT) {
                        nI2++;
                        nX2 = nX2left + (int) ((dX [nI2] - dXmin) * nDx2 / dDx);
                        nY2 = nY2bottom - (int) ((dY2 [nI2] - dY2min) * nDy2 / dDy2);
                        SelectObject (memDC, hGreenPen);
                        MoveToEx (memDC, nX2old, nY2old, NULL);
                        LineTo (memDC, nX2, nY2);
                        nX2old = nX2; nY2old = nY2;
						if (nOverheads) {
	                        TextOut (memDC, nX2td, nY2t, szEmpty1, strlen (szEmpty1));
	                        sprintf (str, "%d", nDelta2 * nI2);
	                        TextOut (memDC, nX2td, nY2t, str, strlen (str));
	                        TextOut (memDC, nX2tt, nY2t, szEmpty2, strlen (szEmpty2));
	                        vTime2Str (str);
	                        TextOut (memDC, nX2tt, nY2t, str, strlen (str));
	                        TextOut (memDC, nX2tg, nY2t, szEmpty3, strlen (szEmpty3));
	                        sprintf (str, "%ld", GetTickCount ());
	                        TextOut (memDC, nX2tg, nY2t, str, strlen (str));
						}
                        InvalidateRect (hMainWnd, &Rect2, FALSE);
                        ResetEvent (hEvent2);
                }
        }
        else {
			nEnd2 = TRUE;
			if (nEndTime2) {
				nT2e = GetTickCount ();
				sprintf (str, "%ld", nT2e - nT2s);
				TextOut (memDC, nX2ttt, nY2t, str, strlen (str));
				TextOut (memDC, nX2td, nY2t, szEmpty1, strlen (szEmpty1));
				sprintf (str, "%d", nDelta2 * nI2);
				TextOut (memDC, nX2td, nY2t, str, strlen (str));
				InvalidateRect (hMainWnd, &Rect2, FALSE);
				nEndTime2 = FALSE;
			}
		}
        if (nI3 < POINTS - 1) {
                if (nBoth ()) {
                        nI3++;
                        nX3 = nX3left + (int) ((dX [nI3] - dXmin) * nDx3 / dDx);
                        nY3 = nY3bottom - (int) ((dY3 [nI3] - dY3min) * nDy3 / dDy3);
                        SelectObject (memDC, hBluePen);
                        MoveToEx (memDC, nX3old, nY3old, NULL);
                        LineTo (memDC, nX3, nY3);
                        nX3old = nX3; nY3old = nY3;
                        InvalidateRect (hMainWnd, &Rect3, FALSE);
                }
        }

        if (PeekMessage (&Msg, NULL, 0, 0, PM_REMOVE)) {
                if (Msg.message == WM_QUIT) {
					nT1e = nT2e = GetTickCount ();
					sprintf (str, "%ld", nT1e - nT1s);
					TextOut (memDC, nX1ttt, nY1t, str, strlen (str));
					sprintf (str, "%ld", nT2e - nT2s);
					TextOut (memDC, nX2ttt, nY2t, str, strlen (str));
					TextOut (memDC, nX1td, nY1t, szEmpty1, strlen (szEmpty1));
					sprintf (str, "%d", nDelta1 * nI1);
					TextOut (memDC, nX1td, nY1t, str, strlen (str));
					TextOut (memDC, nX2td, nY2t, szEmpty1, strlen (szEmpty1));
					sprintf (str, "%d", nDelta2 * nI2);
					TextOut (memDC, nX2td, nY2t, str, strlen (str));
                    SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 4, (LPARAM) "Stopped");
                    SelectObject (memDC, hOldPen);
					InvalidateRect (hMainWnd, NULL, FALSE);
                    ReleaseSemaphore (hFuncSemaphore, 1, NULL);
                    return (1);
                }
        }
        if (nEnd1 && nEnd2) break;
}
SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 4, (LPARAM) "Stopped");
SelectObject (memDC, hOldPen);
InvalidateRect (hMainWnd, NULL, FALSE);
ReleaseSemaphore (hFuncSemaphore, 1, NULL);
return (0);
}

int nGetDelta (int nDelta, DWORD dwInit, DWORD *lpdwResult)
{
DWORD dwTmp;

	dwTmp = GetTickCount ();
	if ((int) (dwTmp - dwInit) >= nDelta) {
		*lpdwResult = dwTmp; return TRUE;
	}
	else return FALSE;
}

DWORD FuncCount (LPVOID param)
{
int nEnd1, nEndTime1, nX1, nY1, nX1old, nY1old;
int nEnd2, nEndTime2, nX2, nY2, nX2old, nY2old;
int nX3, nY3, nX3old, nY3old;
int nI1old, nI2old;
DWORD nT1s, nT1e, nT2s, nT2e;
DWORD dwT1, dwT1tmp, dwT2, dwT2tmp;
MSG Msg;

vDrawAxes ();
nI1 = nI2 = nI3 = 0;
nI1old = nI2old = 0;
nEnd1 = nEnd2 = FALSE; nEndTime1 = nEndTime2 = TRUE;
nX1old = nX1left + (int) ((dX [nI1] - dXmin) * nDx1 / dDx);
nY1old = nY1bottom - (int) ((dY1 [nI1] - dY1min) * nDy1 / dDy1);
nX2old = nX2left + (int) ((dX [nI2] - dXmin) * nDx2 / dDx);
nY2old = nY2bottom - (int) ((dY2 [nI2] - dY2min) * nDy2 / dDy2);
nX3old = nX3left + (int) ((dX [nI3] - dXmin) * nDx3 / dDx);
nY3old = nY3bottom - (int) ((dY3 [nI3] - dY3min) * nDy3 / dDy3);
nT1s = dwT1 = GetTickCount (); nT2s = dwT2 = GetTickCount ();
while (1) {
    if (nI1 < POINTS - 1) {
        if (nGetDelta (nDelta1, dwT1, &dwT1tmp)) {
            nI1++; dwT1 = dwT1tmp;
            nX1 = nX1left + (int) ((dX [nI1] - dXmin) * nDx1 / dDx);
            nY1 = nY1bottom - (int) ((dY1 [nI1] - dY1min) * nDy1 / dDy1);
            SelectObject (memDC, hRedPen);
            MoveToEx (memDC, nX1old, nY1old, NULL);
            LineTo (memDC, nX1, nY1);
            nX1old = nX1; nY1old = nY1;
			if (nOverheads) {
	            TextOut (memDC, nX1td, nY1t, szEmpty1, strlen (szEmpty1));
	            sprintf (str, "%d", nDelta1 * nI1);
	            TextOut (memDC, nX1td, nY1t, str, strlen (str));
	            TextOut (memDC, nX1tt, nY1t, szEmpty2, strlen (szEmpty2));
	            vTime2Str (str);
	            TextOut (memDC, nX1tt, nY1t, str, strlen (str));
	            TextOut (memDC, nX1tg, nY1t, szEmpty3, strlen (szEmpty3));
	            sprintf (str, "%ld", GetTickCount ());
	            TextOut (memDC, nX1tg, nY1t, str, strlen (str));
			}
            InvalidateRect (hMainWnd, &Rect1, FALSE);
        }
    }
    else {
		nEnd1 = TRUE;
		if (nEndTime1) {
			nT1e = GetTickCount ();
			sprintf (str, "%ld", nT1e - nT1s);
			TextOut (memDC, nX1ttt, nY1t, str, strlen (str));
			TextOut (memDC, nX1td, nY1t, szEmpty1, strlen (szEmpty1));
			sprintf (str, "%d", nDelta1 * nI1);
			TextOut (memDC, nX1td, nY1t, str, strlen (str));
			InvalidateRect (hMainWnd, &Rect1, FALSE);
			nEndTime1 = FALSE;
		}
	}
    if (nI2 < POINTS - 1) {
        if (nGetDelta (nDelta2, dwT2, &dwT2tmp)) {
            nI2++; dwT2 = dwT2tmp;
            nX2 = nX2left + (int) ((dX [nI2] - dXmin) * nDx2 / dDx);
            nY2 = nY2bottom - (int) ((dY2 [nI2] - dY2min) * nDy2 / dDy2);
            SelectObject (memDC, hGreenPen);
            MoveToEx (memDC, nX2old, nY2old, NULL);
            LineTo (memDC, nX2, nY2);
            nX2old = nX2; nY2old = nY2;
			if (nOverheads) {
	            TextOut (memDC, nX2td, nY2t, szEmpty1, strlen (szEmpty1));
	            sprintf (str, "%d", nDelta2 * nI2);
	            TextOut (memDC, nX2td, nY2t, str, strlen (str));
	            TextOut (memDC, nX2tt, nY2t, szEmpty2, strlen (szEmpty2));
	            vTime2Str (str);
	            TextOut (memDC, nX2tt, nY2t, str, strlen (str));
	            TextOut (memDC, nX2tg, nY2t, szEmpty3, strlen (szEmpty3));
	            sprintf (str, "%ld", GetTickCount ());
	            TextOut (memDC, nX2tg, nY2t, str, strlen (str));
			}
            InvalidateRect (hMainWnd, &Rect2, FALSE);
        }
    }
    else {
		nEnd2 = TRUE;
		if (nEndTime2) {
			nT2e = GetTickCount ();
			sprintf (str, "%ld", nT2e - nT2s);
			TextOut (memDC, nX2ttt, nY2t, str, strlen (str));
			TextOut (memDC, nX2td, nY2t, szEmpty1, strlen (szEmpty1));
			sprintf (str, "%d", nDelta2 * nI2);
			TextOut (memDC, nX2td, nY2t, str, strlen (str));
			InvalidateRect (hMainWnd, &Rect2, FALSE);
			nEndTime2 = FALSE;
		}
	}
    if (nI3 < POINTS - 1) {
        if (nBoth ()) {
            nI3++;
            nX3 = nX3left + (int) ((dX [nI3] - dXmin) * nDx3 / dDx);
            nY3 = nY3bottom - (int) ((dY3 [nI3] - dY3min) * nDy3 / dDy3);
            SelectObject (memDC, hBluePen);
            MoveToEx (memDC, nX3old, nY3old, NULL);
            LineTo (memDC, nX3, nY3);
            nX3old = nX3; nY3old = nY3;
            InvalidateRect (hMainWnd, &Rect3, FALSE);
        }
    }

    if (PeekMessage (&Msg, NULL, 0, 0, PM_REMOVE)) {
        if (Msg.message == WM_QUIT) {
			nT1e = nT2e = GetTickCount ();
			sprintf (str, "%ld", nT1e - nT1s);
			TextOut (memDC, nX1ttt, nY1t, str, strlen (str));
			sprintf (str, "%ld", nT2e - nT2s);
			TextOut (memDC, nX2ttt, nY2t, str, strlen (str));
			TextOut (memDC, nX1td, nY1t, szEmpty1, strlen (szEmpty1));
			sprintf (str, "%d", nDelta1 * nI1);
			TextOut (memDC, nX1td, nY1t, str, strlen (str));
			TextOut (memDC, nX2td, nY2t, szEmpty1, strlen (szEmpty1));
			sprintf (str, "%d", nDelta2 * nI2);
			TextOut (memDC, nX2td, nY2t, str, strlen (str));
            SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 4, (LPARAM) "Stopped");
            SelectObject (memDC, hOldPen);
			InvalidateRect (hMainWnd, NULL, FALSE);
            ReleaseSemaphore (hFuncSemaphore, 1, NULL);
            return (1);
		}
    }
    if (nEnd1 && nEnd2) break;
}
SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 4, (LPARAM) "Stopped");
SelectObject (memDC, hOldPen);
InvalidateRect (hMainWnd, NULL, FALSE);
ReleaseSemaphore (hFuncSemaphore, 1, NULL);
return (0);
}

void vSetTimers (void)
{
        SetTimer (hMainWnd, TIMER1, nDelta1, Timer1Proc);
        SetTimer (hMainWnd, TIMER2, nDelta2, Timer2Proc);
}

void vKillTimers (void)
{
        KillTimer (hMainWnd, TIMER2);
        KillTimer (hMainWnd, TIMER1);
}

VOID CALLBACK Timer1Proc(HWND hwnd,             // handle of window for timer messages
                                                 UINT message,  // WM_TIMER message
                                                 UINT idEvent,  // WM_TIMER message
                                                 DWORD dwTime)  // current system time
                                                                                // This is the value returned by the
                                                                                // GetTickCount function.
{
        switch (message) {
        case WM_TIMER :
                if (idEvent == TIMER1) {
                        SetEvent (hEvent1);
                }
                break;
        default :
                break;
        }
        return;
}
 
VOID CALLBACK Timer2Proc(HWND hwnd, UINT message, UINT idEvent, DWORD dwTime)
{
        switch (message) {
        case WM_TIMER :
                if (idEvent == TIMER2) {
                        SetEvent (hEvent2);
                }
                break;
        default :
                break;
        }
        return;
}
 
void vDrawAxes (void)
{
RECT Rect;
SIZE Size;
int nI, nT1, nT2, nX, nY, nX1t, nX2t;
double dT1, dT2;

GetClientRect (hMainWnd, &Rect);
Rect.bottom -= (nYtb + nYst); nT = (Rect.bottom - Rect.top) / 3;
nX1left = nX2left = nX3left = Rect.left;
nX1right = nX2right = nX3right = Rect.right;
nY1top = Rect.top; nY1bottom = nT;
nY2top = nY1bottom; nY2bottom = nT * 2;
nY3top = nY2bottom; nY3bottom = nT * 3;

sprintf (str, "%.2lf", dXmax);
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
nT = Size.cx / 2;
nX1right -= nT; nX2right -= nT; nX3right -= nT;

nT2 = 0;
dT1 = dDy1 / (TICK_CNT - 1);
for (nI = 0; nI < TICK_CNT; nI++) {
        dT2 = dY1min + dT1 * nI;
        sprintf (str, "%.2lf", dT2);
        GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
        nT1 = Size.cx + TICK_LEN;
        if (nT2 < nT1) nT2 = nT1;
}
nX1left += nT2;
nT2 = 0;
dT1 = dDy2 / (TICK_CNT - 1);
for (nI = 0; nI < TICK_CNT; nI++) {
        dT2 = dY2min + dT1 * nI;
        sprintf (str, "%.2lf", dT2);
        GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
        nT1 = Size.cx + TICK_LEN;
        if (nT2 < nT1) nT2 = nT1;
}
nX2left += nT2;
nT2 = 0;
dT1 = dDy3 / (TICK_CNT - 1);
for (nI = 0; nI < TICK_CNT; nI++) {
        dT2 = dY3min + dT1 * nI;
        sprintf (str, "%.2lf", dT2);
        GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
        nT1 = Size.cx + TICK_LEN;
        if (nT2 < nT1) nT2 = nT1;
}
nX3left += nT2;

strcpy (str, "0");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
nT = Size.cy;
nY1top += nT; nY2top += nT; nY3top += nT;
nT1 = nT * 2 + TICK_LEN;
nY1bottom -= nT1; nY2bottom -= nT1; nY3bottom -= nT1;

nDx1 = nX1right - nX1left;
nDx2 = nX2right - nX2left;
nDx3 = nX3right - nX3left;
nDy1 = nY1bottom - nY1top;
nDy2 = nY2bottom - nY2top;
nDy3 = nY3bottom - nY3top;

nY1t = nY1top - nT; nY2t = nY2top - nT;
strcpy (str, "0000000");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
nX1td = nX1right - Size.cx; nX2td = nX2right - Size.cx;
GetTextExtentPoint32 (memDC, szDelta, strlen (szDelta), &Size);
nX1t = nX1td - Size.cx; nX2t = nX2td - Size.cx;
TextOut (memDC, nX1t, nY1t, szDelta, strlen (szDelta));
TextOut (memDC, nX2t, nY2t, szDelta, strlen (szDelta));
strcpy (str, "00:00:00:000 ");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
nX1tt = nX1t - Size.cx; nX2tt = nX2t - Size.cx;
GetTextExtentPoint32 (memDC, szTime, strlen (szTime), &Size);
nX1t = nX1tt - Size.cx; nX2t = nX2tt - Size.cx;
TextOut (memDC, nX1t, nY1t, szTime, strlen (szTime));
TextOut (memDC, nX2t, nY2t, szTime, strlen (szTime));
strcpy (str, "0000000000 ");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
nX1tg = nX1t - Size.cx; nX2tg = nX2t - Size.cx;
GetTextExtentPoint32 (memDC, szGet, strlen (szGet), &Size);
nX1t = nX1tg - Size.cx; nX2t = nX2tg - Size.cx;
TextOut (memDC, nX1t, nY1t, szGet, strlen (szGet));
TextOut (memDC, nX2t, nY2t, szGet, strlen (szGet));
strcpy (str, "0000000000 ");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
nX1ttt = nX1t - Size.cx; nX2ttt = nX2t - Size.cx;
GetTextExtentPoint32 (memDC, szTotal, strlen (szTotal), &Size);
nX1t = nX1ttt - Size.cx; nX2t = nX2ttt - Size.cx;
TextOut (memDC, nX1t, nY1t, szTotal, strlen (szTotal));
TextOut (memDC, nX2t, nY2t, szTotal, strlen (szTotal));

MoveToEx (memDC, nX1left, nY1top, NULL);
LineTo (memDC, nX1right, nY1top); LineTo (memDC, nX1right, nY1bottom);
LineTo (memDC, nX1left, nY1bottom); LineTo (memDC, nX1left, nY1top);
MoveToEx (memDC, nX2left, nY2top, NULL);
LineTo (memDC, nX2right, nY2top); LineTo (memDC, nX2right, nY2bottom);
LineTo (memDC, nX2left, nY2bottom); LineTo (memDC, nX2left, nY2top);
MoveToEx (memDC, nX3left, nY3top, NULL);
LineTo (memDC, nX3right, nY3top); LineTo (memDC, nX3right, nY3bottom);
LineTo (memDC, nX3left, nY3bottom); LineTo (memDC, nX3left, nY3top);

dT1 = dDx / (TICK_CNT - 1);
for (nI = 0; nI < TICK_LEN; nI++) {
        dT2 = dXmin + dT1 * nI;
        sprintf (str, "%.2lf", dT2);
        GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
        nT1 = Size.cx / 2;
        nX = nX1left + (int) ((dT1 * nI) * nDx1 / dDx);
        MoveToEx (memDC, nX, nY1bottom, NULL);
        LineTo (memDC, nX, nY1bottom + TICK_LEN);
        TextOut (memDC, nX - nT1, nY1bottom + TICK_LEN, str, strlen (str));
        if ((nI > 0) && (nI < TICK_LEN - 1)) {
                SelectObject (memDC, hDotPen);
                MoveToEx (memDC, nX, nY1top, NULL);
                LineTo (memDC, nX, nY1bottom);
                SelectObject (memDC, hOldPen);
        }
}
strcpy (str, "Argument1");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
TextOut (memDC, nX1left + (nDx1 - Size.cx) / 2, nY1bottom + nT + TICK_LEN, str, strlen (str));
dT1 = dDy1 / (TICK_CNT - 1);
for (nI = 0; nI < TICK_LEN; nI++) {
        dT2 = dY1min + dT1 * nI;
        sprintf (str, "%.2lf", dT2);
        GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
        nT1 = Size.cx + TICK_LEN; nT2 = Size.cy / 2;
        nY = nY1bottom - (int) (dT1 * nI * nDy1 / dDy1);
        MoveToEx (memDC, nX1left, nY, NULL);
        LineTo (memDC, nX1left - TICK_LEN, nY);
        TextOut (memDC, nX1left - nT1, nY - nT2, str, strlen (str));
        if ((nI > 0) && (nI < TICK_LEN - 1)) {
                SelectObject (memDC, hDotPen);
                MoveToEx (memDC, nX1left, nY, NULL);
                LineTo (memDC, nX1right, nY);
                SelectObject (memDC, hOldPen);
        }
}
strcpy (str, "Function1");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
TextOut (memDC, nX1left, nY1top - Size.cy, str, strlen (str));

dT1 = dDx / (TICK_CNT - 1);
for (nI = 0; nI < TICK_LEN; nI++) {
        dT2 = dXmin + dT1 * nI;
        sprintf (str, "%.2lf", dT2);
        GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
        nT1 = Size.cx / 2;
        nX = nX2left + (int) ((dT1 * nI) * nDx2 / dDx);
        MoveToEx (memDC, nX, nY2bottom, NULL);
        LineTo (memDC, nX, nY2bottom + TICK_LEN);
        TextOut (memDC, nX - nT1, nY2bottom + TICK_LEN, str, strlen (str));
        if ((nI > 0) && (nI < TICK_LEN - 1)) {
                SelectObject (memDC, hDotPen);
                MoveToEx (memDC, nX, nY2top, NULL);
                LineTo (memDC, nX, nY2bottom);
                SelectObject (memDC, hOldPen);
        }
}
strcpy (str, "Argument2");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
TextOut (memDC, nX2left + (nDx2 - Size.cx) / 2, nY2bottom + nT + TICK_LEN, str, strlen (str));
dT1 = dDy2 / (TICK_CNT - 1);
for (nI = 0; nI < TICK_LEN; nI++) {
        dT2 = dY2min + dT1 * nI;
        sprintf (str, "%.2lf", dT2);
        GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
        nT1 = Size.cx + TICK_LEN; nT2 = Size.cy / 2;
        nY = nY2bottom - (int) (dT1 * nI * nDy2 / dDy2);
        MoveToEx (memDC, nX2left, nY, NULL);
        LineTo (memDC, nX2left - TICK_LEN, nY);
        TextOut (memDC, nX2left - nT1, nY - nT2, str, strlen (str));
        if ((nI > 0) && (nI < TICK_LEN - 1)) {
                SelectObject (memDC, hDotPen);
                MoveToEx (memDC, nX2left, nY, NULL);
                LineTo (memDC, nX2right, nY);
                SelectObject (memDC, hOldPen);
        }
}
strcpy (str, "Function2");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
TextOut (memDC, nX2left, nY2top - Size.cy, str, strlen (str));

dT1 = dDx / (TICK_CNT - 1);
for (nI = 0; nI < TICK_LEN; nI++) {
        dT2 = dXmin + dT1 * nI;
        sprintf (str, "%.2lf", dT2);
        GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
        nT1 = Size.cx / 2;
        nX = nX3left + (int) ((dT1 * nI) * nDx3 / dDx);
        MoveToEx (memDC, nX, nY3bottom, NULL);
        LineTo (memDC, nX, nY3bottom + TICK_LEN);
        TextOut (memDC, nX - nT1, nY3bottom + TICK_LEN, str, strlen (str));
        if ((nI > 0) && (nI < TICK_LEN - 1)) {
                SelectObject (memDC, hDotPen);
                MoveToEx (memDC, nX, nY3top, NULL);
                LineTo (memDC, nX, nY3bottom);
                SelectObject (memDC, hOldPen);
        }
}
strcpy (str, "Argument3");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
TextOut (memDC, nX3left + (nDx3 - Size.cx) / 2, nY3bottom + nT + TICK_LEN, str, strlen (str));
dT1 = dDy3 / (TICK_CNT - 1);
for (nI = 0; nI < TICK_LEN; nI++) {
        dT2 = dY3min + dT1 * nI;
        sprintf (str, "%.2lf", dT2);
        GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
        nT1 = Size.cx + TICK_LEN; nT2 = Size.cy / 2;
        nY = nY3bottom - (int) (dT1 * nI * nDy3 / dDy3);
        MoveToEx (memDC, nX1left, nY, NULL);
        LineTo (memDC, nX1left - TICK_LEN, nY);
        TextOut (memDC, nX3left - nT1, nY - nT2, str, strlen (str));
        if ((nI > 0) && (nI < TICK_LEN - 1)) {
                SelectObject (memDC, hDotPen);
                MoveToEx (memDC, nX3left, nY, NULL);
                LineTo (memDC, nX3right, nY);
                SelectObject (memDC, hOldPen);
        }
}
strcpy (str, "Function3");
GetTextExtentPoint32 (memDC, str, strlen (str), &Size);
TextOut (memDC, nX3left, nY3top - Size.cy, str, strlen (str));

Rect1.left = nX1left; Rect1.top = nY1top + nYtb - nT - 1;
Rect1.right = nX1right; Rect1.bottom = nY1bottom + nYtb + 1;
Rect2.left = nX2left; Rect2.top = nY2top + nYtb - nT - 1;
Rect2.right = nX2right; Rect2.bottom = nY2bottom + nYtb + 1;
Rect3.left = nX3left; Rect3.top = nY3top + nYtb - 1;
Rect3.right = nX3right; Rect3.bottom = nY3bottom + nYtb + 1;
if (nOverheads) {
	sprintf (str, "%d", 0);
	TextOut (memDC, nX1td, nY1t, str, strlen (str));
	vTime2Str (str);
	TextOut (memDC, nX1tt, nY1t, str, strlen (str));
	sprintf (str, "%ld", GetTickCount ());
	TextOut (memDC, nX1tg, nY1t, str, strlen (str));
	sprintf (str, "%d", 0);
	TextOut (memDC, nX2td, nY2t, str, strlen (str));
	vTime2Str (str);
	TextOut (memDC, nX2tt, nY2t, str, strlen (str));
	sprintf (str, "%ld", GetTickCount ());
	TextOut (memDC, nX2tg, nY2t, str, strlen (str));
}

InvalidateRect (hMainWnd, NULL, FALSE);
}

int nStr2Int (char *lpszStr, int nDef, int nMin, int nMax)
{
int nValue;

if (lpszStr [0] == '\x0') return (nDef);
if (sscanf (lpszStr, "%d", &nValue) == 0) nValue = nDef;
if (nValue < nMin) nValue = nMin;
if (nValue > nMax) nValue = nMax;
return (nValue);
}

void vCalcFuncs (void)
{
int nI;

        for (nI = 0; nI < POINTS; nI++) {
                dX [nI] = dStep * nI;
                dY1 [nI] = sin (25* dX [nI]);
                dY2 [nI] = cos (5*dX [nI]) * 2.0;
                dY3 [nI] = sin (exp (sin(cos(sin (dX [nI] * 2.6))))) * cos (sin(tan (sin (sin (dX [nI]) * 4))));
        }
        dXmin = dXmax = dX [0];
        dY1min = dY1max = dY1 [0];
        dY2min = dY2max = dY2 [0];
        dY3min = dY3max = dY3 [0];
        for (nI = 1; nI < POINTS; nI++) {
                if (dXmin > dX [nI]) dXmin = dX [nI];
                if (dXmax < dX [nI]) dXmax = dX [nI];
                if (dY1min > dY1 [nI]) dY1min = dY1 [nI];
                if (dY1max < dY1 [nI]) dY1max = dY1 [nI];
                if (dY2min > dY2 [nI]) dY2min = dY2 [nI];
                if (dY2max < dY2 [nI]) dY2max = dY2 [nI];
                if (dY3min > dY3 [nI]) dY3min = dY3 [nI];
                if (dY3max < dY3 [nI]) dY3max = dY3 [nI];
        }
        dDx = dXmax - dXmin;
        dDy1 = dY1max - dY1min;
        dDy2 = dY2max - dY2min;
        dDy3 = dY3max - dY3min;
}

void InitToolbar ()
{
        tbButtons [0].iBitmap = 0;                                      // Bitmap index (offset in bitmap)
        tbButtons [0].idCommand = ID_SETPARMS;          // Command, associated with button
        tbButtons [0].fsState = TBSTATE_ENABLED;        // Button start state
        tbButtons [0].fsStyle = TBSTYLE_BUTTON;         // Button style
        tbButtons [0].dwData = 0L;                                      // Additional info
        tbButtons [0].iString = 0;                                      // String, associated with button
//
// Separator 1
        tbButtons [1].iBitmap = 0;
        tbButtons [1].idCommand = 0;
        tbButtons [1].fsState = TBSTATE_ENABLED;
        tbButtons [1].fsStyle = TBSTYLE_SEP;
        tbButtons [1].dwData = 0L;
        tbButtons [1].iString = 0;
//
        tbButtons [2].iBitmap = 1;
        tbButtons [2].idCommand = ID_RUN;
        tbButtons [2].fsState = TBSTATE_ENABLED;
        tbButtons [2].fsStyle = TBSTYLE_BUTTON;
        tbButtons [2].dwData = 0L;
        tbButtons [2].iString = 0;
//
// Separator 2
        tbButtons [3].iBitmap = 0;
        tbButtons [3].idCommand = 0;
        tbButtons [3].fsState = TBSTATE_ENABLED;
        tbButtons [3].fsStyle = TBSTYLE_SEP;
        tbButtons [3].dwData = 0L;
        tbButtons [3].iString = 0;
//
        tbButtons [4].iBitmap = 2;
        tbButtons [4].idCommand = ID_STOP;
        tbButtons [4].fsState = TBSTATE_ENABLED;
        tbButtons [4].fsStyle = TBSTYLE_BUTTON;
        tbButtons [4].dwData = 0L;
        tbButtons [4].iString = 0;
}

void InitStatus (HWND hwnd)
{
int i;

        GetClientRect (hwnd, &stRect);
        for (i = 0; i < NUMPARTS; i++)
                parts [i] = stRect.right / NUMPARTS * (i + 1);
        hStatusWnd = CreateWindow (STATUSCLASSNAME,     // Pointer to registered class name
                                                          "",                           // Pointer to window name
                                                                                                // (in this example not using)
                                                          WS_CHILD | WS_VISIBLE,        // Window style
                                                          0, 0, 0, 0,           // Left, top, width, height
                                                                                                // Set by parent window size
                                                          hwnd,                         // Handle to parent window
                                                          NULL,                         // Handle to menu od child-window ID
                                                          hInst,                        // Handle to application instance
                                                          NULL);                        // Pointer to window creation data
// Set parts number
        SendMessage (hStatusWnd, SB_SETPARTS, (WPARAM) NUMPARTS, (LPARAM) parts);
// Set first part
        SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 0, (LPARAM) "Set/Kill Timer");
// Set second part
        sprintf (str, "Delta1: %d ms", DELTA1_DEF);
        SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 1, (LPARAM) str);
// Set third part
        sprintf (str, "Delta2: %d ms", DELTA2_DEF);
        SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 2, (LPARAM) str);
// Set fourth part
        SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 3, (LPARAM) "Overheads: allow");
// Set fifth part
        SendMessage (hStatusWnd, SB_SETTEXT, (WPARAM) 4, (LPARAM) "Stopped");
}

void vClearMainWindow (void)
{
        MoveToEx (memDC, 0, 0, NULL);
        PatBlt (memDC, 0, 0, nMaxX, nMaxY, PATCOPY);    // Fills selected region
        InvalidateRect (hMainWnd, NULL, TRUE);
}
Соседние файлы в папке Задача с бегущими синусами