Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <time.h>
- #include <math.h>
- #include <stdio.h>
- #pragma comment(lib, "Msimg32.lib")
- #define ID_TIMER 1
- #define SIZE 425
- #define CLOCK_MARGIN 20 // Add a margin to ensure the clock isn't cropped
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- void DrawClock(HDC, int, int, int);
- void DrawHand(HDC, int, int, double, int, COLORREF, bool drawLineToCenter = true);
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
- static TCHAR szAppName[] = TEXT("My Clock");
- HWND hwnd;
- MSG msg;
- WNDCLASS wndclass;
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szAppName;
- if (!RegisterClass(&wndclass)) {
- MessageBox(NULL, TEXT("Program requires Windows NT!"), szAppName, MB_ICONERROR);
- return 0;
- }
- RECT rect = { 0, 0, SIZE + 2 * CLOCK_MARGIN, SIZE + 2 * CLOCK_MARGIN };
- AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
- 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);
- ShowWindow(hwnd, iCmdShow);
- UpdateWindow(hwnd);
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return (int)msg.wParam;
- }
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
- HDC hdc;
- PAINTSTRUCT ps;
- switch (message) {
- case WM_CREATE:
- SetTimer(hwnd, ID_TIMER, 1000, NULL);
- return 0;
- case WM_PAINT: {
- hdc = BeginPaint(hwnd, &ps);
- RECT rect;
- GetClientRect(hwnd, &rect);
- int centerX = (rect.right - rect.left) / 2;
- int centerY = (rect.bottom - rect.top) / 2;
- DrawClock(hdc, centerX, centerY, min(centerX, centerY) - CLOCK_MARGIN);
- EndPaint(hwnd, &ps);
- return 0;
- }
- case WM_TIMER:
- InvalidateRect(hwnd, NULL, TRUE);
- return 0;
- case WM_DESTROY:
- KillTimer(hwnd, ID_TIMER);
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- void DrawClock(HDC hdc, int x, int y, int r) {
- SYSTEMTIME st;
- GetLocalTime(&st);
- // Create a memory DC to draw the gradient
- HDC memDC = CreateCompatibleDC(hdc);
- HBITMAP hBitmap = CreateCompatibleBitmap(hdc, 2 * r, 2 * r);
- SelectObject(memDC, hBitmap);
- TRIVERTEX vertex[2];
- vertex[0].x = 0;
- vertex[0].y = 0;
- vertex[0].Red = 0xc000;
- vertex[0].Green = 0xc000;
- vertex[0].Blue = 0xc000;
- vertex[0].Alpha = 0x0000;
- vertex[1].x = 2 * r;
- vertex[1].y = 2 * r;
- vertex[1].Red = 0x4000;
- vertex[1].Green = 0x4000;
- vertex[1].Blue = 0x4000;
- vertex[1].Alpha = 0x0000;
- GRADIENT_RECT gRect = {0, 1};
- GradientFill(memDC, vertex, 2, &gRect, 1, GRADIENT_FILL_RECT_H); // Use GRADIENT_FILL_RECT_H for horizontal gradient
- // Create a pen for the clock outline
- HPEN hPen = CreatePen(PS_SOLID, 8, RGB(128, 128, 128));
- HPEN hOldPen = (HPEN)SelectObject(memDC, hPen);
- // Draw the clock face
- Ellipse(memDC, 0, 0, 2 * r, 2 * r);
- // Transfer the gradient with the clock face to the main DC
- BitBlt(hdc, x - r, y - r, 2 * r, 2 * r, memDC, 0, 0, SRCCOPY);
- // Cleanup
- SelectObject(memDC, hOldPen);
- DeleteObject(hPen);
- DeleteObject(hBitmap);
- DeleteDC(memDC);
- // Draw the clock hands
- DrawHand(hdc, x, y, st.wSecond * 6, r - 30, RGB(255, 0, 0)); // Draw second hand in red
- DrawHand(hdc, x, y, (st.wMinute * 6) + (st.wSecond / 10.0), r - 60, RGB(0, 0, 0)); // Draw minute hand in black
- DrawHand(hdc, x, y, (st.wHour * 30) + (st.wMinute / 2.0), r - 90, RGB(0, 0, 255)); // Draw hour hand in blue
- // Draw the hour markers with numbers
- 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"));
- HFONT hOldFont = (HFONT)SelectObject(hdc, hFont);
- SetTextColor(hdc, RGB(112, 128, 144)); // Slate Gray
- SetTextAlign(hdc, TA_CENTER | TA_BASELINE);
- SetBkMode(hdc, TRANSPARENT);
- for (int i = 1; i <= 12; i++) {
- double angle = (i * 30 - 90) * (3.14159265358979323846 / 180);
- int numX = x + (int)(cos(angle) * (r - 25)); // Adjust this value to move text closer to markers
- int numY = y + (int)(sin(angle) * (r - 25)); // Adjust this value to move text closer to markers
- WCHAR numStr[3];
- wsprintf(numStr, L"%d", i);
- TextOut(hdc, numX, numY, numStr, lstrlen(numStr));
- }
- SelectObject(hdc, hOldFont);
- DeleteObject(hFont);
- // Draw the minute markers without lines to the center
- for (int i = 0; i < 60; i++) {
- if (i % 5 == 0) {
- DrawHand(hdc, x, y, i * 6, r - 10, RGB(0, 0, 0), false); // Draw longer lines for hour markers
- }
- else {
- DrawHand(hdc, x, y, i * 6, r - 5, RGB(0, 0, 0), false); // Draw shorter lines for minute markers
- }
- }
- }
- void DrawHand(HDC hdc, int x, int y, double angle, int length, COLORREF color, bool drawLineToCenter) {
- double radian = (angle - 90) * (3.14159265358979323846 / 180);
- int endX = x + (int)(cos(radian) * length);
- int endY = y + (int)(sin(radian) * length);
- HPEN hPen = CreatePen(PS_SOLID, 2, color);
- HPEN hOldPen = (HPEN)SelectObject(hdc, hPen);
- if (drawLineToCenter) {
- // Draw the hand as a line from the center to the end point
- MoveToEx(hdc, x, y, NULL);
- LineTo(hdc, endX, endY);
- }
- else {
- // Draw the hand as a line from the end point to a point slightly beyond it
- MoveToEx(hdc, endX, endY, NULL);
- LineTo(hdc, endX + (int)(cos(radian) * 5), endY + (int)(sin(radian) * 5));
- }
- SelectObject(hdc, hOldPen);
- DeleteObject(hPen);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement