#include #include #include #include #include #include #define ID_XSTART 574 #define ID_XEND 399 #define ID_WIDTH 333 #define ID_COLORSIN 519 #define ID_COLORCOS 605 #define MAX_CHARS 16 HWND hGraph, hTools; WINDOWINFO hwndInfo; CHOOSECOLOR nColor; TCHAR buf[MAX_CHARS]; int width, height, penWidth; double sinx, cosx, sinxL, cosxL; double start, end, tmp; COLORREF sinColor = RGB(255, 0, 0), cosColor = RGB(0, 0, 255); void RepaintGraph(); LONG WINAPI WndProc(HWND, UINT, WPARAM,LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; WNDCLASS w; memset(&w, 0, sizeof(WNDCLASS)); w.style = WS_TILED | CS_HREDRAW | CS_VREDRAW; w.lpfnWndProc = WndProc; w.hInstance = hInstance; w.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); w.lpszClassName = L"Lab2"; w.hIcon = LoadIcon(NULL, IDI_EXCLAMATION); w.hCursor = LoadCursor(NULL, IDC_ARROW); RegisterClass(&w); // graph window hGraph = CreateWindow(L"Lab2", L"Nepryakhin 3121", WS_OVERLAPPEDWINDOW, 200, 200, 600, 400, NULL, NULL, hInstance, NULL); // tools window hTools = CreateWindow(L"Lab2", L"Tools", WS_DLGFRAME, 200, 100, 280, 100, NULL, NULL, hInstance, NULL); // create 3 textboxes (x start, x end, line width) HWND hStart = CreateWindow(L"Edit", NULL, WS_BORDER | WS_CHILD | WS_VISIBLE | ES_LEFT, 70, 8, 50, 20, hTools, (HMENU)ID_XSTART, hInstance, 0); HWND hEnd = CreateWindow(L"Edit", NULL, WS_BORDER | WS_CHILD | WS_VISIBLE | ES_LEFT, 70, 38, 50, 20, hTools, (HMENU)ID_XEND, hInstance, 0); HWND hWidth = CreateWindow(L"Edit", NULL, WS_BORDER | WS_CHILD | WS_VISIBLE | ES_LEFT | ES_NUMBER, 200, 8, 50, 20, hTools, (HMENU)ID_WIDTH, hInstance, 0); SetWindowText(hStart, L"-5"); // def start -5 SetWindowText(hEnd, L"10"); // def end 10 SetWindowText(hWidth, L"1"); // def width 1 // create buttons (picks line color) HWND hColorSin = CreateWindow(L"Button", NULL, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 140, 38, 50, 20, hTools, (HMENU)ID_COLORSIN, hInstance, 0); HWND hColorCos = CreateWindow(L"Button", NULL, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 200, 38, 50, 20, hTools, (HMENU)ID_COLORCOS, hInstance, 0); SetWindowText(hColorSin, L"sin clr"); // info SetWindowText(hColorCos, L"cos clr"); ShowWindow(hGraph,nCmdShow); // show graph window UpdateWindow(hGraph); ShowWindow(hTools,nCmdShow); // show tools window UpdateWindow(hTools); RepaintGraph(); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } void RepaintGraph() { InvalidateRect (hGraph, NULL, TRUE); UpdateWindow (hGraph); } void RepaintTools() { InvalidateRect (hTools, NULL, TRUE); UpdateWindow (hTools); } void SetText(int CID, LPCWSTR format, double data) { if (CID != ID_WIDTH) StringCbPrintf(buf, sizeof(buf), format, data); else StringCbPrintf(buf, sizeof(buf), format, (int)data); SetDlgItemText(hTools, CID, buf); } void TextBoxHandle(WPARAM param) { LPTSTR endPtr; errno = 0; if (LOWORD(param) == ID_XSTART) { // get text, convert to double GetDlgItemText(hTools, ID_XSTART, buf, MAX_CHARS); tmp = _tcstod(buf, &endPtr); // convert validation if (!(*endPtr) && errno != ERANGE && wcslen(buf) != 0 && end - tmp <= 100 && tmp <= end) { start = tmp; // its ok, remember new value start--; } else SetText(ID_XSTART, L"%0.3f", start+1); // incorrect, set last value to textbox } if (LOWORD(param)==ID_XEND) { GetDlgItemText(hTools, ID_XEND, buf, MAX_CHARS); tmp = _tcstod(buf, &endPtr); if (!(*endPtr) && errno != ERANGE && wcslen(buf) != 0 && tmp - start <= 100 && tmp >= start) { end = tmp; end++; } else SetText(ID_XEND, L"%0.3f", end-1); } if (LOWORD(param)==ID_WIDTH) { GetDlgItemText(hTools, ID_WIDTH, buf, MAX_CHARS); tmp = _tcstod(buf, &endPtr); if (!(*endPtr) && errno != ERANGE && wcslen(buf) != 0 && tmp > 0 && tmp < 100) penWidth = (int)tmp; else SetText(ID_WIDTH, L"%d", penWidth); } RepaintGraph(); // repaint graph } void CreateChooseColorDlg(WPARAM param) { nColor.lStructSize = sizeof(CHOOSECOLOR); nColor.hwndOwner = hTools; COLORREF cc[16] = { 0 }; nColor.lpCustColors = cc; if (ChooseColor(&nColor) == TRUE) { if (LOWORD(param) == ID_COLORSIN) sinColor = nColor.rgbResult; else cosColor = nColor.rgbResult; RepaintTools(); RepaintGraph(); } } LONG WINAPI WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam) { HDC hdc; PAINTSTRUCT ps; HPEN sinPen, cosPen, defPen; double xRatio = width / (end-start); double yRatio = height / 2; switch (Message){ case WM_DESTROY: PostQuitMessage(0); break; case WM_COMMAND: if (HIWORD(wparam) == EN_UPDATE) TextBoxHandle(wparam); if (HIWORD(wparam) == BN_CLICKED) CreateChooseColorDlg(wparam); break; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); SetBkMode(hdc,TRANSPARENT); if (hwnd == hTools) { sinPen = CreatePen(0 | 0x00010000, 4, sinColor); cosPen = CreatePen(0 | 0x00010000, 4, cosColor); TextOut(hdc, 10, 10, L"x start:", 8); TextOut(hdc, 10, 40, L"x end:", 6); TextOut(hdc, 140, 10, L"width:", 6); SelectObject(hdc, sinPen); MoveToEx(hdc, 140, 60, (LPPOINT)NULL); LineTo(hdc, 190, 60); SelectObject(hdc, cosPen); MoveToEx(hdc, 200, 60, (LPPOINT)NULL); LineTo(hdc, 250, 60); } else { ZeroMemory(&hwndInfo, sizeof(WINDOWINFO)); hwndInfo.cbSize = sizeof(WINDOWINFO); GetWindowInfo(hwnd, &hwndInfo); width = hwndInfo.rcClient.right - hwndInfo.rcClient.left; height = hwndInfo.rcClient.bottom - hwndInfo.rcClient.top; // х ось MoveToEx(hdc, 0, height/2, (LPPOINT)NULL); LineTo(hdc, width, height/2); TextOut(hdc, width-10, height/2-20, L"X", 1); // стрелка MoveToEx(hdc, width-8, height/2-4, (LPPOINT)NULL); LineTo(hdc, width, height/2); MoveToEx(hdc, width-8, height/2+4, (LPPOINT)NULL); LineTo(hdc, width, height/2); // у ось MoveToEx(hdc, width-16, 0, (LPPOINT)NULL); LineTo(hdc, width-16, height); TextOut(hdc, width-12, 5, L"Y", 1); TextOut(hdc, width-40, 0, L"1.0", 3); TextOut(hdc, width-42, height-14, L"-1.0", 4); // стрелка MoveToEx(hdc, width-16, 0, (LPPOINT)NULL); LineTo(hdc, width-8, 4); MoveToEx(hdc, width-16, 0, (LPPOINT)NULL); LineTo(hdc, width-24, 4); defPen = CreatePen(0 | 0x00010000, 1, RGB(128, 128, 128)); SelectObject(hdc, defPen); for (double i = -0.9; i < 0.9; i += 0.1) { if (abs(i) <= 0.0001) continue; MoveToEx(hdc, 0, (int)(-yRatio * i + height / 2), (LPPOINT)NULL); LineTo(hdc, width, (int)(-yRatio * i + height / 2)); } if (abs(start - 0.001) <= 0.0001) sinx = 0.002; else sinx = 0.001; sinxL = sin(start - sinx)/(start - sinx); cosxL = cos(start - sinx)/(start - sinx); sinPen = CreatePen(0 | 0x00010000, penWidth, sinColor); cosPen = CreatePen(0 | 0x00010000, penWidth, cosColor); defPen = CreatePen(0 | 0x00010000, 1, RGB(0, 0, 0)); // let's draw for (double i = start; i < end + 0.001; i+=0.001) { if (abs(i) <= 0.0001) // exclude divide by 0, function doesn't exist { cosxL = 0.999; continue; } sinx = sin(i)/i; // get sin(x)/x cosx = cos(i)/i; // get cos(x)/x SelectObject(hdc, sinPen); MoveToEx(hdc, (int)(xRatio * (i - 0.001) - start * xRatio), (int)(-yRatio * sinxL + height / 2), (LPPOINT)NULL); LineTo(hdc, (int)(xRatio * i - start * xRatio), (int)(-yRatio * sinx + height / 2)); SelectObject(hdc, cosPen); MoveToEx(hdc, (int)(xRatio * (i - 0.001) - start * xRatio), (int)(-yRatio * cosxL + height / 2), (LPPOINT)NULL); LineTo(hdc, (int)(xRatio * i - start * xRatio), (int)(-yRatio * cosx + height / 2)); //SetPixel(hdc, (int)(xRatio * i - start * xRatio), (int)(-yRatio * sinx + height / 2), RGB(255,0,0)); //SetPixel(hdc, (int)(xRatio * i - start * xRatio), (int)(-yRatio * cosx + height / 2), RGB(0,0,255)); sinxL = sinx; cosxL = cosx; if (fabs(modf(i, &sinx)) < 0.001) { SelectObject(hdc, defPen); StringCbPrintf(buf, sizeof(buf), L"%d", (int)i); TextOut(hdc, (int)(xRatio * i - start * xRatio) - 4, (int)(height / 2 + 4), buf, wcslen(buf)); MoveToEx(hdc, (int)(xRatio * i - start * xRatio), (int)(height / 2 - 4), (LPPOINT)NULL); LineTo(hdc, (int)(xRatio * i - start * xRatio), (int)(height / 2 + 4)); } } DeleteObject(defPen); } DeleteObject(sinPen); DeleteObject(cosPen); DeleteDC(hdc); EndPaint(hwnd, &ps); break; default: return DefWindowProc(hwnd, Message, wparam, lparam); } return 0; }