Advertisement
alien_fx_fiend

Analog Clock Win32 [*FINAL*]

Jul 11th, 2024 (edited)
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.32 KB | None | 0 0
  1. #include <windows.h>
  2. #include <time.h>
  3. #include <math.h>
  4. #include <stdio.h>
  5.  
  6. #pragma comment(lib, "Msimg32.lib")
  7.  
  8. #define ID_TIMER 1
  9. #define SIZE 425
  10. #define CLOCK_MARGIN 20 // Add a margin to ensure the clock isn't cropped
  11.  
  12. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  13. void DrawClock(HDC, int, int, int);
  14. void DrawHand(HDC, int, int, double, int, COLORREF, bool drawLineToCenter = true);
  15.  
  16. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
  17.     static TCHAR szAppName[] = TEXT("My Clock");
  18.     HWND hwnd;
  19.     MSG msg;
  20.     WNDCLASS wndclass;
  21.  
  22.     wndclass.style = CS_HREDRAW | CS_VREDRAW;
  23.     wndclass.lpfnWndProc = WndProc;
  24.     wndclass.cbClsExtra = 0;
  25.     wndclass.cbWndExtra = 0;
  26.     wndclass.hInstance = hInstance;
  27.     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  28.     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  29.     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  30.     wndclass.lpszMenuName = NULL;
  31.     wndclass.lpszClassName = szAppName;
  32.  
  33.     if (!RegisterClass(&wndclass)) {
  34.         MessageBox(NULL, TEXT("Program requires Windows NT!"), szAppName, MB_ICONERROR);
  35.         return 0;
  36.     }
  37.  
  38.     RECT rect = { 0, 0, SIZE + 2 * CLOCK_MARGIN, SIZE + 2 * CLOCK_MARGIN };
  39.     AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
  40.  
  41.     hwnd = CreateWindow(szAppName, TEXT("Time is Meaningless The Insurgency is Live & Well"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hInstance, NULL);
  42.     ShowWindow(hwnd, iCmdShow);
  43.     UpdateWindow(hwnd);
  44.  
  45.     while (GetMessage(&msg, NULL, 0, 0)) {
  46.         TranslateMessage(&msg);
  47.         DispatchMessage(&msg);
  48.     }
  49.     return (int)msg.wParam;
  50. }
  51.  
  52. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  53.     HDC hdc;
  54.     PAINTSTRUCT ps;
  55.  
  56.     switch (message) {
  57.     case WM_CREATE:
  58.         SetTimer(hwnd, ID_TIMER, 1000, NULL);
  59.         return 0;
  60.     case WM_PAINT: {
  61.         hdc = BeginPaint(hwnd, &ps);
  62.         RECT rect;
  63.         GetClientRect(hwnd, &rect);
  64.         int centerX = (rect.right - rect.left) / 2;
  65.         int centerY = (rect.bottom - rect.top) / 2;
  66.         DrawClock(hdc, centerX, centerY, min(centerX, centerY) - CLOCK_MARGIN);
  67.         EndPaint(hwnd, &ps);
  68.         return 0;
  69.     }
  70.     case WM_TIMER:
  71.         InvalidateRect(hwnd, NULL, TRUE);
  72.         return 0;
  73.     case WM_DESTROY:
  74.         KillTimer(hwnd, ID_TIMER);
  75.         PostQuitMessage(0);
  76.         return 0;
  77.     }
  78.     return DefWindowProc(hwnd, message, wParam, lParam);
  79. }
  80.  
  81. void DrawClock(HDC hdc, int x, int y, int r) {
  82.     SYSTEMTIME st;
  83.     GetLocalTime(&st);
  84.  
  85.     // Create a memory DC to draw the gradient
  86.     HDC memDC = CreateCompatibleDC(hdc);
  87.     HBITMAP hBitmap = CreateCompatibleBitmap(hdc, 2 * r, 2 * r);
  88.     SelectObject(memDC, hBitmap);
  89.  
  90.     TRIVERTEX vertex[2];
  91.     vertex[0].x = 0;
  92.     vertex[0].y = 0;
  93.     vertex[0].Red = 0xc000;
  94.     vertex[0].Green = 0xc000;
  95.     vertex[0].Blue = 0xc000;
  96.     vertex[0].Alpha = 0x0000;
  97.  
  98.     vertex[1].x = 2 * r;
  99.     vertex[1].y = 2 * r;
  100.     vertex[1].Red = 0x4000;
  101.     vertex[1].Green = 0x4000;
  102.     vertex[1].Blue = 0x4000;
  103.     vertex[1].Alpha = 0x0000;
  104.  
  105.     GRADIENT_RECT gRect = {0, 1};
  106.     GradientFill(memDC, vertex, 2, &gRect, 1, GRADIENT_FILL_RECT_H); // Use GRADIENT_FILL_RECT_H for horizontal gradient
  107.  
  108.     // Create a pen for the clock outline
  109.     HPEN hPen = CreatePen(PS_SOLID, 8, RGB(128, 128, 128));
  110.     HPEN hOldPen = (HPEN)SelectObject(memDC, hPen);
  111.  
  112.     // Draw the clock face
  113.     Ellipse(memDC, 0, 0, 2 * r, 2 * r);
  114.  
  115.     // Transfer the gradient with the clock face to the main DC
  116.     BitBlt(hdc, x - r, y - r, 2 * r, 2 * r, memDC, 0, 0, SRCCOPY);
  117.  
  118.     // Cleanup
  119.     SelectObject(memDC, hOldPen);
  120.     DeleteObject(hPen);
  121.     DeleteObject(hBitmap);
  122.     DeleteDC(memDC);
  123.  
  124.     // Draw the clock hands
  125.     DrawHand(hdc, x, y, st.wSecond * 6, r - 30, RGB(255, 0, 0)); // Draw second hand in red
  126.     DrawHand(hdc, x, y, (st.wMinute * 6) + (st.wSecond / 10.0), r - 60, RGB(0, 0, 0)); // Draw minute hand in black
  127.     DrawHand(hdc, x, y, (st.wHour * 30) + (st.wMinute / 2.0), r - 90, RGB(0, 0, 255)); // Draw hour hand in blue
  128.  
  129.     // Draw the hour markers with numbers
  130.     HFONT hFont = CreateFont(12, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, TEXT("Segoe UI"));
  131.     HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);
  132.     SetTextColor(hdc, RGB(112, 128, 144)); // Slate Gray
  133.     SetTextAlign(hdc, TA_CENTER | TA_BASELINE);
  134.     SetBkMode(hdc, TRANSPARENT);
  135.  
  136.     for (int i = 1; i <= 12; i++) {
  137.         double angle = (i * 30 - 90) * (3.14159265358979323846 / 180);
  138.         int numX = x + (int)(cos(angle) * (r - 25)); // Adjust this value to move text closer to markers
  139.         int numY = y + (int)(sin(angle) * (r - 25)); // Adjust this value to move text closer to markers
  140.         WCHAR numStr[3];
  141.         wsprintf(numStr, L"%d", i);
  142.         TextOut(hdc, numX, numY, numStr, lstrlen(numStr));
  143.     }
  144.     SelectObject(hdc, hOldFont);
  145.     DeleteObject(hFont);
  146.  
  147.     // Draw the minute markers without lines to the center
  148.     for (int i = 0; i < 60; i++) {
  149.         if (i % 5 == 0) {
  150.             DrawHand(hdc, x, y, i * 6, r - 10, RGB(0, 0, 0), false); // Draw longer lines for hour markers
  151.         }
  152.         else {
  153.             DrawHand(hdc, x, y, i * 6, r - 5, RGB(0, 0, 0), false); // Draw shorter lines for minute markers
  154.         }
  155.     }
  156. }
  157.  
  158. void DrawHand(HDC hdc, int x, int y, double angle, int length, COLORREF color, bool drawLineToCenter) {
  159.     double radian = (angle - 90) * (3.14159265358979323846 / 180);
  160.     int endX = x + (int)(cos(radian) * length);
  161.     int endY = y + (int)(sin(radian) * length);
  162.  
  163.     HPEN hPen = CreatePen(PS_SOLID, 2, color);
  164.     HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
  165.  
  166.     if (drawLineToCenter) {
  167.         // Draw the hand as a line from the center to the end point
  168.         MoveToEx(hdc, x, y, NULL);
  169.         LineTo(hdc, endX, endY);
  170.     }
  171.     else {
  172.         // Draw the hand as a line from the end point to a point slightly beyond it
  173.         MoveToEx(hdc, endX, endY, NULL);
  174.         LineTo(hdc, endX + (int)(cos(radian) * 5), endY + (int)(sin(radian) * 5));
  175.     }
  176.  
  177.     SelectObject(hdc, hOldPen);
  178.     DeleteObject(hPen);
  179. }
  180.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement