1 #include <windows.h>
2 #include <stdio.h>
3 
4 LRESULT WINAPI UnicodeWndProc(HWND, UINT, WPARAM, LPARAM);
5 LRESULT WINAPI UnicodeSubclassProc(HWND, UINT, WPARAM, LPARAM);
6 LRESULT WINAPI AnsiSubclassProc(HWND, UINT, WPARAM, LPARAM);
7 
8 static WNDPROC SavedWndProcW;
9 static WNDPROC SavedWndProcA;
10 
11 int WINAPI
12 WinMain(HINSTANCE hInstance,
13 	HINSTANCE hPrevInstance,
14 	LPSTR lpszCmdLine,
15 	int nCmdShow)
16 {
17   WNDCLASSW wc;
18   HWND hWnd;
19   WCHAR WindowTextW[256];
20   char WindowTextA[256];
21 
22   wc.lpszClassName = L"UnicodeClass";
23   wc.lpfnWndProc = UnicodeWndProc;
24   wc.style = 0;
25   wc.hInstance = hInstance;
26   wc.hIcon = NULL;
27   wc.hCursor = NULL;
28   wc.hbrBackground = NULL;
29   wc.lpszMenuName = NULL;
30   wc.cbClsExtra = 0;
31   wc.cbWndExtra = 0;
32   if (RegisterClassW(&wc) == 0)
33     {
34       fprintf(stderr, "RegisterClassW failed (last error 0x%lx)\n",
35 	      GetLastError());
36       return 1;
37     }
38   printf("Unicode class registered, WndProc = 0x%p\n", wc.lpfnWndProc);
39 
40   hWnd = CreateWindowA("UnicodeClass",
41 		       "Unicode Window",
42 		       WS_OVERLAPPEDWINDOW,
43 		       0,
44 		       0,
45 		       CW_USEDEFAULT,
46 		       CW_USEDEFAULT,
47 		       NULL,
48 		       NULL,
49 		       hInstance,
50 		       NULL);
51   if (hWnd == NULL)
52     {
53       fprintf(stderr, "CreateWindowA failed (last error 0x%lx)\n",
54 	      GetLastError());
55       return 1;
56     }
57 
58   printf("Window created, IsWindowUnicode returns %s\n", IsWindowUnicode(hWnd) ? "TRUE" : "FALSE");
59 
60   printf("Calling GetWindowTextW\n");
61   if (! GetWindowTextW(hWnd, WindowTextW, sizeof(WindowTextW) / sizeof(WindowTextW[0])))
62     {
63       fprintf(stderr, "GetWindowTextW failed (last error 0x%lx)\n", GetLastError());
64       return 1;
65     }
66   printf("GetWindowTextW returned Unicode string \"%S\"\n", WindowTextW);
67 
68   printf("Calling GetWindowTextA\n");
69   if (! GetWindowTextA(hWnd, WindowTextA, sizeof(WindowTextA) / sizeof(WindowTextA[0])))
70     {
71       fprintf(stderr, "GetWindowTextA failed (last error 0x%lx)\n", GetLastError());
72       return 1;
73     }
74   printf("GetWindowTextA returned Ansi string \"%s\"\n", WindowTextA);
75   printf("\n");
76 
77   SavedWndProcW = (WNDPROC) GetWindowLongW(hWnd, GWL_WNDPROC);
78   printf("GetWindowLongW returned 0x%p\n", SavedWndProcW);
79   SavedWndProcA = (WNDPROC) GetWindowLongA(hWnd, GWL_WNDPROC);
80   printf("GetWindowLongA returned 0x%p\n", SavedWndProcA);
81   printf("\n");
82 
83   printf("Subclassing window using SetWindowLongW, new WndProc 0x%p\n", UnicodeSubclassProc);
84   SetWindowLongW(hWnd, GWL_WNDPROC, (LONG) UnicodeSubclassProc);
85   printf("After subclass, IsWindowUnicode %s, WndProcA 0x%lx, WndProcW 0x%lx\n",
86          IsWindowUnicode(hWnd) ? "TRUE" : "FALSE", GetWindowLongA(hWnd, GWL_WNDPROC),
87          GetWindowLongW(hWnd, GWL_WNDPROC));
88 
89   printf("Calling GetWindowTextW\n");
90   if (! GetWindowTextW(hWnd, WindowTextW, sizeof(WindowTextW) / sizeof(WindowTextW[0])))
91     {
92       fprintf(stderr, "GetWindowTextW failed (last error 0x%lx)\n", GetLastError());
93       return 1;
94     }
95   printf("GetWindowTextW returned Unicode string \"%S\"\n", WindowTextW);
96   printf("\n");
97 
98   printf("Subclassing window using SetWindowLongA, new WndProc 0x%p\n", AnsiSubclassProc);
99   SetWindowLongA(hWnd, GWL_WNDPROC, (LONG) AnsiSubclassProc);
100   printf("After subclass, IsWindowUnicode %s, WndProcA 0x%lx, WndProcW 0x%lx\n",
101          IsWindowUnicode(hWnd) ? "TRUE" : "FALSE", GetWindowLongA(hWnd, GWL_WNDPROC),
102          GetWindowLongW(hWnd, GWL_WNDPROC));
103 
104   printf("Calling GetWindowTextW\n");
105   if (! GetWindowTextW(hWnd, WindowTextW, sizeof(WindowTextW) / sizeof(WindowTextW[0])))
106     {
107       fprintf(stderr, "GetWindowTextW failed (last error 0x%lx)\n", GetLastError());
108       return 1;
109     }
110   printf("GetWindowTextW returned Unicode string \"%S\"\n", WindowTextW);
111 
112   DestroyWindow(hWnd);
113 
114   return 0;
115 }
116 
117 LRESULT CALLBACK UnicodeWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
118 {
119   LRESULT Result;
120 
121   switch(msg)
122     {
123       case WM_GETTEXT:
124         printf("UnicodeWndProc calling DefWindowProcW\n");
125         Result = DefWindowProcW(hWnd, msg, wParam, lParam);
126         printf("UnicodeWndProc Unicode window text \"%S\"\n", (LPWSTR) lParam);
127         break;
128       default:
129         Result = DefWindowProcW(hWnd, msg, wParam, lParam);
130         break;
131     }
132 
133   return Result;
134 }
135 
136 LRESULT CALLBACK UnicodeSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
137 {
138   LRESULT Result;
139 
140   switch(msg)
141     {
142       case WM_GETTEXT:
143         printf("UnicodeSubclassProc calling SavedWindowProc\n");
144         Result = CallWindowProcW(SavedWndProcW, hWnd, msg, wParam, lParam);
145         printf("UnicodeSubclassProc Unicode window text \"%S\"\n", (LPWSTR) lParam);
146         break;
147       default:
148         Result = CallWindowProcW(SavedWndProcW, hWnd, msg, wParam, lParam);
149         break;
150     }
151 
152   return Result;
153 }
154 
155 LRESULT CALLBACK AnsiSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
156 {
157   LRESULT Result;
158 
159   switch(msg)
160     {
161       case WM_GETTEXT:
162         printf("AnsiSubclassProc calling SavedWindowProcA\n");
163         Result = CallWindowProcA(SavedWndProcA, hWnd, msg, wParam, lParam);
164         printf("AnsiSubclassProc Ansi window text \"%s\"\n", (LPSTR) lParam);
165         break;
166       default:
167         Result = CallWindowProcA(SavedWndProcA, hWnd, msg, wParam, lParam);
168         break;
169     }
170 
171   return Result;
172 }
173