source: trunk/testapp/keyboard/OKeyTest/OKeyTest.cpp@ 7152

Last change on this file since 7152 was 7152, checked in by phaller, 24 years ago

Added keyboard test prog

File size: 8.6 KB
Line 
1// OKeyTest.cpp : Defines the entry point for the application.
2//
3
4
5/**
6
7To Do:
8- enable standard keyboard hook
9- enable WIN NT low-level hook
10
11 */
12
13#include <windows.h>
14#include <string.h>
15#include <stdio.h>
16#include "okeytest.h"
17
18#include "stdafx.h"
19#include "resource.h"
20
21#define MAX_LOADSTRING 100
22
23
24// definitions
25#define OKEYTEST_EXPORT __declspec(dllexport)
26#define OKEYHOOK_API __declspec(dllimport)
27
28
29// Global Variables:
30HINSTANCE hInst; // current instance
31TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
32TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
33HWND hwndListbox; // the listbox for all the logged messages
34HINSTANCE hHOOKDLL; // instance for the hooking DLL
35
36// Foward declarations of functions included in this code module:
37ATOM MyRegisterClass(HINSTANCE hInstance);
38BOOL InitInstance(HINSTANCE, int);
39LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
40LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
41
42#ifdef __cplusplus
43extern "C" {
44#endif
45
46
47OKEYTEST_EXPORT void logString(LPSTR lpstrOrigin, LPSTR lpstrText);
48OKEYTEST_EXPORT void logMessage(LPSTR lpstrOrigin, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
49
50typedef (* OKEYHOOK_API THOOK_ENABLE)(BOOL fEnable);
51THOOK_ENABLE phook_Enable;
52BOOL fHookEnabled = FALSE;
53
54
55#ifdef __cplusplus
56}
57#endif
58
59
60
61
62void i_hookEnable(BOOL fEnable)
63{
64 if (NULL == hHOOKDLL)
65 {
66 hHOOKDLL = LoadLibrary("OKEYHOOK.DLL");
67
68 // Note: loading the DLL automatically installs the hooks
69 if (NULL == hHOOKDLL)
70 {
71 logString("*", "OKEYHOOK.DLL not loaded");
72 return;
73 }
74 }
75
76 // get proc addr
77 phook_Enable = (THOOK_ENABLE)GetProcAddress(hHOOKDLL, "hook_Enable");
78 if (NULL == phook_Enable)
79 {
80 logString("*", "Can't get hook_Enable export");
81 return;
82 }
83
84 phook_Enable(fEnable);
85}
86
87
88
89int APIENTRY WinMain(HINSTANCE hInstance,
90 HINSTANCE hPrevInstance,
91 LPSTR lpCmdLine,
92 int nCmdShow)
93{
94 // TODO: Place code here.
95 MSG msg;
96 HACCEL hAccelTable;
97
98 // Initialize global strings
99 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
100 LoadString(hInstance, IDC_OKEYTEST, szWindowClass, MAX_LOADSTRING);
101 MyRegisterClass(hInstance);
102
103 // Perform application initialization:
104 if (!InitInstance (hInstance, nCmdShow))
105 {
106 return FALSE;
107 }
108
109 hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_OKEYTEST);
110
111 // Main message loop:
112 while (GetMessage(&msg, NULL, 0, 0))
113 {
114 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
115 {
116 TranslateMessage(&msg);
117 DispatchMessage(&msg);
118 }
119 }
120
121 return msg.wParam;
122}
123
124
125
126//
127// FUNCTION: MyRegisterClass()
128//
129// PURPOSE: Registers the window class.
130//
131// COMMENTS:
132//
133// This function and its usage is only necessary if you want this code
134// to be compatible with Win32 systems prior to the 'RegisterClassEx'
135// function that was added to Windows 95. It is important to call this function
136// so that the application will get 'well formed' small icons associated
137// with it.
138//
139ATOM MyRegisterClass(HINSTANCE hInstance)
140{
141 WNDCLASSEX wcex;
142
143 wcex.cbSize = sizeof(WNDCLASSEX);
144
145 wcex.style = CS_HREDRAW | CS_VREDRAW;
146 wcex.lpfnWndProc = (WNDPROC)WndProc;
147 wcex.cbClsExtra = 0;
148 wcex.cbWndExtra = 0;
149 wcex.hInstance = hInstance;
150 wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_OKEYTEST);
151 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
152 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
153 wcex.lpszMenuName = (LPCSTR)IDC_OKEYTEST;
154 wcex.lpszClassName = szWindowClass;
155 wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
156
157 return RegisterClassEx(&wcex);
158}
159
160//
161// FUNCTION: InitInstance(HANDLE, int)
162//
163// PURPOSE: Saves instance handle and creates main window
164//
165// COMMENTS:
166//
167// In this function, we save the instance handle in a global variable and
168// create and display the main program window.
169//
170BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
171{
172 HWND hWnd;
173
174 hInst = hInstance; // Store instance handle in our global variable
175
176 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
177 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
178
179 if (!hWnd)
180 {
181 return FALSE;
182 }
183
184 ShowWindow(hWnd, nCmdShow);
185 UpdateWindow(hWnd);
186
187 return TRUE;
188}
189
190
191
192//
193// cheesy logging functions
194//
195
196#define LOG_MAX_ENTRIES 100
197
198
199OKEYTEST_EXPORT void logString(LPSTR lpstrOrigin, LPSTR lpstrText)
200{
201 CHAR szBuf[512];
202 static int nMessage = 0;
203
204 nMessage++;
205
206 wsprintf(szBuf, "%06d|%5s|",
207 nMessage,
208 lpstrOrigin);
209
210 if (NULL != lpstrText)
211 strcat(szBuf, lpstrText);
212
213 SendMessage(hwndListbox, LB_ADDSTRING, (WPARAM)0, (LPARAM)szBuf);
214
215 // check if we've got to delete the top entry?
216 DWORD dwItems = SendMessage(hwndListbox, LB_GETCOUNT, 0, 0);
217 if (dwItems > LOG_MAX_ENTRIES)
218 {
219 // delete the top entry
220 SendMessage(hwndListbox, LB_DELETESTRING, 0, 0);
221 }
222
223 // scroll to the last visible entry
224// int rc = SendMessage(hwndListbox, LB_SETTOPINDEX, (WPARAM)dwItems - 1, (LPARAM)0);
225// if (rc == LB_ERR)
226// MessageBox(0, "err", "err", MB_OK);
227
228 // simulate "END" key
229 SendMessage(hwndListbox, WM_KEYDOWN, 0x23, 0x014f0001);
230}
231
232
233OKEYTEST_EXPORT void logMessage(LPSTR lpstrOrigin, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
234{
235 CHAR szBuf[512];
236 LPSTR pszMsg;
237
238 switch(msg)
239 {
240 case WM_CHAR: pszMsg = "WM_CHAR"; break;
241 case WM_KEYUP: pszMsg = "WM_KEYUP"; break;
242 case WM_KEYDOWN: pszMsg = "WM_KEYDOWN"; break;
243 case WM_SYSKEYUP: pszMsg = "WM_SYSKEYUP"; break;
244 case WM_SYSKEYDOWN: pszMsg = "WM_SYSKEYDOWN"; break;
245 default: pszMsg = "unknown"; break;
246 }
247
248 wsprintf(szBuf, "%08xh %16s (%08xh, %08xh)",
249 hwnd,
250 pszMsg,
251 wParam,
252 lParam);
253
254 logString(lpstrOrigin, szBuf);
255}
256
257
258//
259// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
260//
261// PURPOSE: Processes messages for the main window.
262//
263// WM_COMMAND - process the application menu
264// WM_PAINT - Paint the main window
265// WM_DESTROY - post a quit message and return
266//
267//
268LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
269{
270 int wmId, wmEvent;
271 TCHAR szHello[MAX_LOADSTRING];
272 LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
273
274 switch (message)
275 {
276 case WM_CREATE:
277 {
278 RECT rcl;
279 GetClientRect(hWnd, &rcl);
280
281 // create a listbox that fills the main client window
282 hwndListbox = CreateWindow("LISTBOX",
283 "log",
284 WS_CHILD | WS_VSCROLL | WS_VISIBLE | LBS_DISABLENOSCROLL | LBS_NOINTEGRALHEIGHT,
285 0, 0,
286 rcl.right - rcl.left,
287 rcl.bottom - rcl.top,
288 hWnd,
289 0,
290 hInst,
291 NULL);
292
293 break;
294 }
295
296 case WM_KILLFOCUS:
297 {
298 // prevent the listbox from gaining the focus
299 HWND hwndNew = (HWND)wParam;
300 if (hwndNew == hwndListbox)
301 SetFocus(hWnd); // skip this message
302 break;
303 }
304
305 case WM_SIZE:
306 {
307 // resize the listbox also!
308 RECT rcl;
309 GetClientRect(hWnd, &rcl);
310 SetWindowPos(hwndListbox, 0, 0, 0,
311 rcl.right - rcl.left,
312 rcl.bottom - rcl.top,
313 SWP_NOZORDER);
314 break;
315 }
316
317 case WM_CHAR:
318 case WM_KEYUP:
319 case WM_KEYDOWN:
320 case WM_SYSKEYUP:
321 case WM_SYSKEYDOWN:
322 logMessage("Queue", hWnd, message, wParam, lParam);
323 break;
324
325 case WM_COMMAND:
326 wmId = LOWORD(wParam);
327 wmEvent = HIWORD(wParam);
328 // Parse the menu selections:
329 switch (wmId)
330 {
331 case IDM_ABOUT:
332 DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
333 break;
334
335 case IDM_EXIT:
336 DestroyWindow(hWnd);
337 break;
338
339 case IDC_EDIT_HOOK:
340 {
341 if (fHookEnabled == TRUE)
342 {
343 // disable hooks
344 logString("*", "Uninstalling hooks");
345 i_hookEnable(FALSE);
346 fHookEnabled = FALSE;
347 }
348 else
349 {
350 // enable hooks
351 logString("*", "Installing hooks");
352 i_hookEnable(TRUE);
353 fHookEnabled = TRUE;
354 }
355
356 HMENU hMenu = GetMenu(hWnd);
357 CheckMenuItem(hMenu,
358 IDC_EDIT_HOOK,
359 MF_BYCOMMAND |
360 fHookEnabled ? MF_CHECKED : MF_UNCHECKED);
361
362 break;
363 }
364
365 case IDC_EDIT_CLEAR:
366 SendMessage(hwndListbox,
367 LB_RESETCONTENT,
368 0,
369 0);
370 break;
371 default:
372 return DefWindowProc(hWnd, message, wParam, lParam);
373 }
374 break;
375
376 case WM_DESTROY:
377 if (NULL != hHOOKDLL)
378 {
379 i_hookEnable(FALSE);
380 FreeLibrary(hHOOKDLL);
381 }
382
383 PostQuitMessage(0);
384 break;
385
386 default:
387 return DefWindowProc(hWnd, message, wParam, lParam);
388 }
389 return 0;
390}
391
392// Mesage handler for about box.
393LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
394{
395 switch (message)
396 {
397 case WM_INITDIALOG:
398 return TRUE;
399
400 case WM_COMMAND:
401 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
402 {
403 EndDialog(hDlg, LOWORD(wParam));
404 return TRUE;
405 }
406 break;
407 }
408 return FALSE;
409}
Note: See TracBrowser for help on using the repository browser.