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

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

.

File size: 8.7 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 // get key name
249 CHAR szBufKey[40];
250 GetKeyNameText(lParam, szBufKey, sizeof(szBufKey));
251
252 wsprintf(szBuf, "%08xh %16s (%08xh, %08xh) name=[%s]",
253 hwnd,
254 pszMsg,
255 wParam,
256 lParam,
257 szBufKey);
258
259 logString(lpstrOrigin, szBuf);
260}
261
262
263//
264// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
265//
266// PURPOSE: Processes messages for the main window.
267//
268// WM_COMMAND - process the application menu
269// WM_PAINT - Paint the main window
270// WM_DESTROY - post a quit message and return
271//
272//
273LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
274{
275 int wmId, wmEvent;
276 TCHAR szHello[MAX_LOADSTRING];
277 LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
278
279 switch (message)
280 {
281 case WM_CREATE:
282 {
283 RECT rcl;
284 GetClientRect(hWnd, &rcl);
285
286 // create a listbox that fills the main client window
287 hwndListbox = CreateWindow("LISTBOX",
288 "log",
289 WS_CHILD | WS_VSCROLL | WS_VISIBLE | LBS_DISABLENOSCROLL | LBS_NOINTEGRALHEIGHT,
290 0, 0,
291 rcl.right - rcl.left,
292 rcl.bottom - rcl.top,
293 hWnd,
294 0,
295 hInst,
296 NULL);
297
298 break;
299 }
300
301 case WM_KILLFOCUS:
302 {
303 // prevent the listbox from gaining the focus
304 HWND hwndNew = (HWND)wParam;
305 if (hwndNew == hwndListbox)
306 SetFocus(hWnd); // skip this message
307 break;
308 }
309
310 case WM_SIZE:
311 {
312 // resize the listbox also!
313 RECT rcl;
314 GetClientRect(hWnd, &rcl);
315 SetWindowPos(hwndListbox, 0, 0, 0,
316 rcl.right - rcl.left,
317 rcl.bottom - rcl.top,
318 SWP_NOZORDER);
319 break;
320 }
321
322 case WM_CHAR:
323 case WM_KEYUP:
324 case WM_KEYDOWN:
325 case WM_SYSKEYUP:
326 case WM_SYSKEYDOWN:
327 logMessage("Queue", hWnd, message, wParam, lParam);
328 break;
329
330 case WM_COMMAND:
331 wmId = LOWORD(wParam);
332 wmEvent = HIWORD(wParam);
333 // Parse the menu selections:
334 switch (wmId)
335 {
336 case IDM_ABOUT:
337 DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
338 break;
339
340 case IDM_EXIT:
341 DestroyWindow(hWnd);
342 break;
343
344 case IDC_EDIT_HOOK:
345 {
346 if (fHookEnabled == TRUE)
347 {
348 // disable hooks
349 logString("*", "Uninstalling hooks");
350 i_hookEnable(FALSE);
351 fHookEnabled = FALSE;
352 }
353 else
354 {
355 // enable hooks
356 logString("*", "Installing hooks");
357 i_hookEnable(TRUE);
358 fHookEnabled = TRUE;
359 }
360
361 HMENU hMenu = GetMenu(hWnd);
362 CheckMenuItem(hMenu,
363 IDC_EDIT_HOOK,
364 MF_BYCOMMAND |
365 fHookEnabled ? MF_CHECKED : MF_UNCHECKED);
366
367 break;
368 }
369
370 case IDC_EDIT_CLEAR:
371 SendMessage(hwndListbox,
372 LB_RESETCONTENT,
373 0,
374 0);
375 break;
376 default:
377 return DefWindowProc(hWnd, message, wParam, lParam);
378 }
379 break;
380
381 case WM_DESTROY:
382 if (NULL != hHOOKDLL)
383 {
384 i_hookEnable(FALSE);
385 FreeLibrary(hHOOKDLL);
386 }
387
388 PostQuitMessage(0);
389 break;
390
391 default:
392 return DefWindowProc(hWnd, message, wParam, lParam);
393 }
394 return 0;
395}
396
397// Mesage handler for about box.
398LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
399{
400 switch (message)
401 {
402 case WM_INITDIALOG:
403 return TRUE;
404
405 case WM_COMMAND:
406 if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
407 {
408 EndDialog(hDlg, LOWORD(wParam));
409 return TRUE;
410 }
411 break;
412 }
413 return FALSE;
414}
Note: See TracBrowser for help on using the repository browser.