How can I Paint the time to the client area on a window?

I am trying to paint the time to the client area on a blank window. I am using Dev c++.

I am converting the time to string using the strftime()function but some where after converting it and passing it to the variable LPSTR startLoopTime causes problems. It displays as gibberish; the unicode changes.

when I use cout << buffer; to display it, shows the time perfectly.

I have cycled through, LPSTR, LPWSTR, LPCSTR and the variable type and function return type but still the same, the displayed text is complete gibberish.

Can someone please help me with this, I should believe that its an easy fix but I've spent a mighty amount of time on this.. Funny thing is it works in visual studio but VS is to heavy for my laptop.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
LPSTR startLoopTime = loopStartTime();

case WM_PAINT:
	hdc = BeginPaint(hwnd, &ps); 
	TextOutA(hdc, 50, 50, startLoopTime, strlen(startLoopTime)); 
	EndPaint(hwnd, &ps);
break;

LPTSTR loopStartTime()
{
	time_t rawtime;
	struct tm * timeinfo;
	char buffer [80];	
  
	time (&rawtime);
	timeinfo = localtime (&rawtime);
	strftime (buffer,80,"Loop Start: %I:%M:%S%p.",timeinfo);
  
	cout << buffer << endl;	
	return buffer;
}
The problem is that you return a pointer to a local variable/buffer that is not longer valid after leaving loopStartTime(). So either you pass the buffer to that function as a parameter or you use container like std::string as the result.
you can also make buffer static if you need to use the window's types and this function is single threaded. Its not a great solution, but if you are locked into what you have
Last edited on
Thanks so much guys.. I would never have realized I was trying to return a local variable... Your suggestions both works..
Last edited on
A Win32 SDK digital clock using a timer:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <windows.h>
#include <strsafe.h>
#include <ctime>
#include <tchar.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nWinMode)
{
   const TCHAR szWinName[] = TEXT("WINCLOCK");
   WNDCLASSEX  wc;

   wc.cbSize        = sizeof(WNDCLASSEX);
   wc.hInstance     = hInstance;
   wc.lpszClassName = szWinName;
   wc.lpfnWndProc   = WndProc;
   wc.style         = 0;
   wc.hIcon         = (HICON)   LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
   wc.hIconSm       = (HICON)   LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
   wc.hCursor       = (HCURSOR) LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
   wc.lpszMenuName  = NULL;
   wc.cbClsExtra    = 0;
   wc.cbWndExtra    = 0;
   wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);

   if (RegisterClassEx(&wc) == 0)
   {
      MessageBox(NULL, TEXT("Couldn't Register the Window Class!"), TEXT("ERROR"), MB_OK | MB_ICONERROR);
      return E_FAIL;
   }

   const TCHAR szAppTitle[] = TEXT("Win Clock");

   HWND hwnd = CreateWindow(szWinName, szAppTitle,
                            WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
                            0, 0,
                            210, 60,
                            HWND_DESKTOP, NULL, hInstance, NULL);

   if (hwnd == NULL)
   {
      MessageBox(NULL, TEXT("Couldn't Create the Main Window!"), TEXT("ERROR"), MB_OK | MB_ICONERROR);
      return E_FAIL;
   }

   // start a timer; interrupt once per second
   SetTimer(hwnd, 1, 1000, NULL);

   ShowWindow(hwnd, nWinMode);
   UpdateWindow(hwnd);

   MSG msg;

   while (GetMessage(&msg, NULL, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   // stop the timer
   KillTimer(hwnd, 1);

   return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   const size_t  strSize = 255;
   static TCHAR  str[strSize] = TEXT("");
   static size_t strLen = 0;

   switch (message)
   {
   case WM_CREATE:
   case WM_TIMER:
      // timer went off, get the new time
      struct tm newtime;
      time_t    t;

      t = time(NULL);

      localtime_s(&newtime, &t);

      // format the new time to a string
      _tasctime_s(str, strSize, &newtime);

      // remove formatting
      StringCchLength(str, (int) strSize, &strLen);

      str[strLen - 1] = TEXT('\0');

      // display the new time
      InvalidateRect(hwnd, NULL, FALSE);
      return S_OK;

   case WM_PAINT:
      HDC         hdc;
      PAINTSTRUCT ps;

      hdc = BeginPaint(hwnd, &ps);

      StringCchLength(str, (int) strSize, &strLen);
      TextOut(hdc, 4, 1, str, (int) strLen);

      EndPaint(hwnd, &ps);
      return S_OK;

   case WM_DESTROY:
      PostQuitMessage(0);
      return S_OK;
   }

   return DefWindowProc(hwnd, message, wParam, lParam);
}

The source I've had for years, semi-updated to work with Visual Studio 2017/2019 and Win 10. You shouldn't have too much difficulty adapting it to your needs.

I really should update it to use Unicode wide-char Windows functions instead using the TCHAR macros for ANSI and Unicode. Rather lazy and concentrating on other projects at the moment.
Wow... thats kool thanks..
Topic archived. No new replies allowed.