GetClipboardData() in C++

Nov 23, 2011 at 2:45pm
Hi, I am relatively new to Windows programming and I am reading through a book. The book has samples that don't always work with C++, but C. I was trying to convert one of the samples from C to C++, and I am just curious if I am doing it right, IE: I've allocated memory correctly, and then deallocated it, and did not make any dumb errors with casting.

I figured I ask since I want to ensure I am handling memory correctly. Here is my code (Just the important part).

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
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	 static wchar_t			*wText;
	 wchar_t				*wGlobal;
	 HGLOBAL				hGlobal;
	 HDC					hdc;
	 PAINTSTRUCT			ps;
	 RECT					rc;

	switch(msg)
	{
		case WM_CREATE:
			
			OpenClipboard(hWnd);
			
			if(hGlobal = GetClipboardData(CF_UNICODETEXT))
			{
				
				wGlobal = (wchar_t*)GlobalLock(hGlobal);

				// Allocate memory from the clipboard
                wText = new wchar_t[GlobalSize(hGlobal)];

				// Make a copy of the text in the clipboard
                lstrcpy (wText, wGlobal);

				GlobalUnlock (hGlobal);
				InvalidateRect (hWnd, NULL, TRUE) ;
			}

			CloseClipboard();
			
			break;

		case WM_CLOSE:

			DestroyWindow(hWnd);

		break;

		case WM_PAINT:
			
			// Draw the text in the clipboard

			hdc = BeginPaint(hWnd,&ps);

			GetClientRect(hWnd,&rc);

			if(wText != NULL) // But only if there is something in the clipboard.
			{
				DrawText(hdc,wText, -1,&rc,DT_LEFT | DT_WORDBREAK);
			}

			EndPaint(hWnd,&ps);

		break;
		
		case WM_DESTROY:

			if(wText) // Deallocate memory if any was allocated.
			{
				delete[] wText;
			}

			PostQuitMessage(0);

		break;

		default:

			return DefWindowProc(hWnd, msg, wParam, lParam); 

		break;
	}
	return 0;
}
Nov 23, 2011 at 3:04pm
Looks OK to me but i'll chime in with a question. Would it be worth checking wText is Null before allocating space?
static wchar_t *wText=NULL;
1
2
3
if(wText!=NULL)
  delete [] wText;
wText = new wchar_t[GlobalSize(hGlobal)];


It's probably not relevant for your program, but what if a user was to close a window (case WM_CLOSE:) does that call WM_DESTROY to deallocate the memory? If not then opening a new window would reallocate the memory twice and you'd have a memory leak.

I'm not sure which is why I ask.
Last edited on Nov 23, 2011 at 3:06pm
Nov 23, 2011 at 4:25pm
You are right, I should be checking if it is null before allocating it. Thanks for pointing that out!

If I understand the second part of your post correctly, you are asking if WM_CLOSE calls WM_DESTROY so that WM_DESTROY can deallocate memory? If so, yes, that is what it does. When WM_CLOSE occurs, it calls DestroyWindow, which places a WM_DESTROY message into the message queue. When WndProc receives this, the program deallocates the memory associated with wText if it has been allocated.
Nov 23, 2011 at 4:36pm
As far as that checking for NULL stuff with wText, I would use the "ZeroMemory(...)" macro from Win32. This way you KNOW that it's blank when you go to use it. I guess this is a style preference but it's worth mentioning in my mind.

Double check that logic on Line 16, you're assigning the handle from "GetClipboardData(...)" to 'hGlobal' not comparing anything.
Nov 23, 2011 at 6:16pm
For Line 16, yeah I know about that, that was how it was in the book I was using.

As for ZeroMemory. I looked it up, but could not really find a good example of how to use it anywhere, but I am going to take a guess you mean to do this:

1
2
                wText = new wchar_t[GlobalSize(hGlobal)];
				ZeroMemory(wText,GlobalSize(hGlobal));
Last edited on Nov 23, 2011 at 9:18pm
Nov 23, 2011 at 6:23pm
ZeroMemory() is just a macro, look at memset() function to understand what it does.
Nov 23, 2011 at 8:49pm
Ah, okay now I get it. Thanks, modoran!
Topic archived. No new replies allowed.