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>
- #include <commctrl.h>
- #include <tchar.h>
- #include <strsafe.h>
- #pragma comment(lib, "Msimg32.lib")
- #pragma comment(lib, "comctl32.lib")
- #define ID_TIMER 1
- #define SIZE 425
- #define CLOCK_MARGIN 20
- #define ID_STATUSBAR 100
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- void DrawClock(HDC, int, int, int);
- void DrawHand(HDC, int, int, double, int, COLORREF, bool drawLineToCenter = true);
- void UpdateStatusBar(HWND, SYSTEMTIME);
- 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 + 30 }; // Added 30 for status bar
- 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) {
- static HWND hwndStatus;
- static HBITMAP hBitmap;
- static int cxClient, cyClient;
- HDC hdc, memDC;
- PAINTSTRUCT ps;
- SYSTEMTIME st;
- RECT rect;
- int centerX, centerY;
- switch (message) {
- case WM_CREATE:
- hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL,
- WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0,
- hwnd, (HMENU)ID_STATUSBAR, GetModuleHandle(NULL), NULL);
- SetTimer(hwnd, ID_TIMER, 1000, NULL);
- return 0;
- case WM_SIZE:
- cxClient = LOWORD(lParam);
- cyClient = HIWORD(lParam);
- if (hBitmap) {
- DeleteObject(hBitmap);
- }
- hdc = GetDC(hwnd);
- hBitmap = CreateCompatibleBitmap(hdc, cxClient, cyClient);
- ReleaseDC(hwnd, hdc);
- SendMessage(hwndStatus, WM_SIZE, 0, 0);
- return 0;
- case WM_PAINT:
- hdc = BeginPaint(hwnd, &ps);
- memDC = CreateCompatibleDC(hdc);
- SelectObject(memDC, hBitmap);
- GetClientRect(hwnd, &rect);
- centerX = (rect.right - rect.left) / 2;
- centerY = ((rect.bottom - rect.top) - 20) / 2; // Adjust for status bar
- FillRect(memDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
- DrawClock(memDC, centerX, centerY, min(centerX, centerY) - CLOCK_MARGIN);
- BitBlt(hdc, 0, 0, cxClient, cyClient, memDC, 0, 0, SRCCOPY);
- DeleteDC(memDC);
- EndPaint(hwnd, &ps);
- return 0;
- case WM_TIMER:
- GetLocalTime(&st);
- UpdateStatusBar(hwndStatus, st);
- InvalidateRect(hwnd, NULL, FALSE);
- return 0;
- case WM_DESTROY:
- KillTimer(hwnd, ID_TIMER);
- if (hBitmap) DeleteObject(hBitmap);
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
- void DrawClock(HDC hdc, int x, int y, int r) {
- SYSTEMTIME st;
- GetLocalTime(&st);
- 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);
- HPEN hPen = CreatePen(PS_SOLID, 8, RGB(128, 128, 128));
- HPEN hOldPen = (HPEN)SelectObject(memDC, hPen);
- Ellipse(memDC, 0, 0, 2 * r, 2 * r);
- BitBlt(hdc, x - r, y - r, 2 * r, 2 * r, memDC, 0, 0, SRCCOPY);
- SelectObject(memDC, hOldPen);
- DeleteObject(hPen);
- DeleteObject(hBitmap);
- DeleteDC(memDC);
- DrawHand(hdc, x, y, st.wSecond * 6, r - 30, RGB(255, 0, 0));
- DrawHand(hdc, x, y, (st.wMinute * 6) + (st.wSecond / 10.0), r - 60, RGB(0, 0, 0));
- DrawHand(hdc, x, y, (st.wHour * 30) + (st.wMinute / 2.0), r - 90, RGB(0, 0, 255));
- 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));
- 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));
- int numY = y + (int)(sin(angle) * (r - 25));
- WCHAR numStr[3];
- wsprintf(numStr, L"%d", i);
- TextOut(hdc, numX, numY, numStr, lstrlen(numStr));
- }
- SelectObject(hdc, hOldFont);
- DeleteObject(hFont);
- for (int i = 0; i < 60; i++) {
- if (i % 5 == 0) {
- DrawHand(hdc, x, y, i * 6, r - 10, RGB(0, 0, 0), false);
- }
- else {
- DrawHand(hdc, x, y, i * 6, r - 5, RGB(0, 0, 0), false);
- }
- }
- }
- 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) {
- MoveToEx(hdc, x, y, NULL);
- LineTo(hdc, endX, endY);
- }
- else {
- MoveToEx(hdc, endX, endY, NULL);
- LineTo(hdc, endX + (int)(cos(radian) * 5), endY + (int)(sin(radian) * 5));
- }
- SelectObject(hdc, hOldPen);
- DeleteObject(hPen);
- }
- void UpdateStatusBar(HWND hwndStatus, SYSTEMTIME st) {
- TCHAR szStatus[256];
- TCHAR szDayOfWeek[32], szMonth[32];
- TCHAR szSuffix[3];
- int weekNumber;
- // Get day of week and month names
- GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, TEXT("dddd"), szDayOfWeek, sizeof(szDayOfWeek) / sizeof(TCHAR));
- GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, TEXT("MMMM"), szMonth, sizeof(szMonth) / sizeof(TCHAR));
- // Calculate week number
- SYSTEMTIME newYearDay = { st.wYear, 1, 0, 1 };
- FILETIME ftNewYearDay, ftCurrentDay;
- SystemTimeToFileTime(&newYearDay, &ftNewYearDay);
- SystemTimeToFileTime(&st, &ftCurrentDay);
- ULARGE_INTEGER uliNewYearDay, uliCurrentDay;
- uliNewYearDay.LowPart = ftNewYearDay.dwLowDateTime;
- uliNewYearDay.HighPart = ftNewYearDay.dwHighDateTime;
- uliCurrentDay.LowPart = ftCurrentDay.dwLowDateTime;
- uliCurrentDay.HighPart = ftCurrentDay.dwHighDateTime;
- weekNumber = (int)(((uliCurrentDay.QuadPart - uliNewYearDay.QuadPart) / (7 * 24 * 60 * 60 * 10000000ULL)) + 1);
- // Get day suffix
- if (st.wDay == 1 || st.wDay == 21 || st.wDay == 31)
- _tcscpy_s(szSuffix, _T("st"));
- else if (st.wDay == 2 || st.wDay == 22)
- _tcscpy_s(szSuffix, _T("nd"));
- else if (st.wDay == 3 || st.wDay == 23)
- _tcscpy_s(szSuffix, _T("rd"));
- else
- _tcscpy_s(szSuffix, _T("th"));
- // Format the status string
- StringCbPrintf(szStatus, sizeof(szStatus),
- TEXT("%s %d%s %s %d #%d %d/%02d/%04d %02d:%02d:%02d %s"),
- szDayOfWeek, st.wDay, szSuffix, szMonth, st.wYear, weekNumber,
- st.wDay, st.wMonth, st.wYear,
- (st.wHour == 0 || st.wHour == 12) ? 12 : st.wHour % 12,
- st.wMinute, st.wSecond,
- st.wHour < 12 ? TEXT("AM") : TEXT("PM"));
- SendMessage(hwndStatus, SB_SETTEXT, 0, (LPARAM)szStatus);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement