/[winpt]/trunk/PTD/PTD.cpp
ViewVC logotype

Contents of /trunk/PTD/PTD.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 325 - (show annotations)
Fri Sep 25 15:51:28 2009 UTC (15 years, 5 months ago) by twoaday
File size: 7855 byte(s)
Updated.

1 /* PTD.cpp - Privacy Tray Dynamic
2 * Copyright (C) 2002-2009 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * WinPT is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
19
20 #include <windows.h>
21 #include <stdio.h>
22
23 HINSTANCE glob_hinst;
24
25 /* We need a special section in the DLL for storing our shared data.
26 This shared data is required by the hook function because that
27 function is called in the context of the actual thread running the
28 hook and thus we need a way to communicate the result of our hook
29 function back to us. We use a shared data segment for this. */
30 #ifdef __GNUC__
31 #define ATTR_SEC __attribute__((section (".SHARDAT"), shared))
32 #else
33 #define ATTR_SEC
34 #pragma data_seg(".SHARDAT")
35 #endif
36 static HHOOK cbt_hook ATTR_SEC = NULL; /* CTB hook handle. */
37 static DWORD tray_proc_id ATTR_SEC = 0; /* WinPT PID */
38 static HWND shell_traywnd ATTR_SEC = 0; /* Tray window handle. */
39 static HWND curr_focus ATTR_SEC = NULL; /* Current window focus handle. */
40 static HWND rebar_w32 ATTR_SEC = NULL;
41 static HWND mstask_swc ATTR_SEC = NULL;
42 static HWND systab_c32 ATTR_SEC = NULL;
43 #ifndef __GNUC__
44 #pragma data_seg()
45 #endif
46 #undef ATTR_SEC
47
48 static unsigned *journ_keys = 0;
49 static unsigned keyidx = 0;
50 static unsigned nkeys = 0;
51 static HHOOK journ_hook = NULL; /* Journaling hook handle. */
52
53
54
55 static LRESULT CALLBACK
56 PTD_CBT_proc (int code, WPARAM wparam, LPARAM lparam)
57 {
58 HWND curr_hwnd = NULL;
59 DWORD proc_id = 0;
60
61 if (code >= 0 && code == HCBT_SETFOCUS) {
62 /* A window is about to receive the keyboard focus */
63
64 curr_hwnd = (HWND)wparam;
65 GetWindowThreadProcessId (curr_hwnd, &proc_id);
66 /* Only if the current window is different from this window list,
67 we set the new focus. For more information read the hint in
68 PTD_initialize. */
69 if ((proc_id != tray_proc_id)
70 && (curr_hwnd != NULL)
71 && (curr_hwnd != curr_focus)
72 && (curr_hwnd != shell_traywnd)
73 && (curr_hwnd != systab_c32)
74 && (curr_hwnd != mstask_swc)
75 && (curr_hwnd != rebar_w32)) {
76 curr_focus = curr_hwnd;
77 }
78 }
79
80 return CallNextHookEx (cbt_hook , code, wparam, lparam);
81 }
82
83
84 /* Return the last selected window */
85 extern "C" HWND
86 PTD_get_curr_hwnd (void)
87 {
88 return curr_focus;
89 }
90
91
92 /* Initialize CTB hook and try to find the system windows. */
93 extern "C" BOOL
94 PTD_initialize (void)
95 {
96 tray_proc_id = GetCurrentProcessId ();
97 cbt_hook = SetWindowsHookEx (WH_CBT, PTD_CBT_proc, glob_hinst, 0);
98 if (cbt_hook == NULL)
99 return FALSE;
100
101 /* Okay, what are we doing here:
102 * In the past I used the Spy++ application to find out why the old current
103 * window doesn't work on so much systems. Now we try to use the computer
104 * based training hook, more precise the HCBT_SETFOCUS to find out the
105 * last window focus. But to succeed we need to ignore some windows
106 * because otherwise our own window or a window from the taskbar
107 * would be recognized.
108 *
109 * Here is what the Spy++ says about the windows order:
110 * Shell_TrayWnd
111 * \ ReBarWindow32
112 * \ MSTaskSwWClass
113 * \ SysTabControl32
114 *
115 * As a result we need to ignore those windows to prevent failured
116 * in the code.
117 */
118 shell_traywnd = FindWindowEx (NULL, NULL, "Shell_TrayWnd", NULL);
119 rebar_w32 = FindWindowEx (shell_traywnd, NULL, "ReBarWindow32", NULL);
120 mstask_swc = FindWindowEx (rebar_w32, NULL, "MSTaskSwWClass", NULL);
121 systab_c32 = FindWindowEx (mstask_swc, NULL, "SysTabControl32", NULL);
122
123 /*debug ("tray_proc_id=%u cbt_hook=%p shell_traywnd=%p rebar_w32=%p "
124 "mstask_swc=%p systab_c32=%p",
125 tray_proc_id, cbt_hook, shell_traywnd, rebar_w32,
126 mstask_swc, systab_c32);*/
127
128 return TRUE;
129 }
130
131
132 /* Remove the CTB hook from the system and reset all variables. */
133 extern "C" void
134 PTD_delete (void)
135 {
136 if (!cbt_hook)
137 return;
138 UnhookWindowsHookEx (cbt_hook);
139 cbt_hook = NULL;
140 shell_traywnd = NULL;
141 tray_proc_id = 0;
142 }
143
144
145 /* Return if the CTB hook is currently used. */
146 extern "C" int
147 PTD_is_used (void)
148 {
149 return shell_traywnd && cbt_hook;
150 }
151
152
153 static LRESULT CALLBACK
154 PTD_playback_proc (int code, WPARAM wparam, LPARAM lparam)
155 {
156 LPEVENTMSG em;
157
158 if (code == HC_SKIP) {
159 keyidx++;
160 if (keyidx == nkeys) {
161 UnhookWindowsHookEx (journ_hook);
162 journ_hook = NULL;
163 }
164 return 0;
165 }
166 else if (code == HC_GETNEXT) {
167 /* Here is an overview what the event message struct can contain:
168 * message - WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, WM_SYSKEYDOWN:
169 * paramL - specifies the virtual key code of the key that was pressed.
170 * paramH - specifies the scan code.
171 */
172 em = (LPEVENTMSG )lparam;
173 if (journ_keys[keyidx] & 0x8000)
174 em->message = journ_keys[keyidx] & 0x4000 ? WM_SYSKEYDOWN : WM_KEYDOWN;
175 else
176 em->message = journ_keys[keyidx] & 0x4000 ? WM_SYSKEYUP : WM_KEYUP;
177 em->paramL = LOBYTE( journ_keys[keyidx] )
178 | (MapVirtualKey (LOBYTE (journ_keys[keyidx]), 0) << 8);
179 em->paramH = 1;
180 em->time = GetTickCount ();
181 return 0;
182 }
183
184 return CallNextHookEx (journ_hook, code, wparam, lparam);
185 }
186
187
188
189 extern "C" BOOL
190 PTD_keyb_send (UINT *keys, UINT n_keys)
191 {
192 MSG msg;
193 journ_keys = keys;
194 keyidx = 0;
195 nkeys = n_keys;
196
197 if (journ_hook)
198 return FALSE;
199
200 while (GetAsyncKeyState (VK_MENU) & 0x8000
201 || GetAsyncKeyState (VK_SHIFT) & 0x8000
202 || GetAsyncKeyState (VK_CONTROL) & 0x8000) {
203 if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
204 if (msg.message == WM_QUIT) {
205 PostMessage (msg.hwnd, msg.message, msg.wParam, msg.lParam);
206 return FALSE;
207 }
208 TranslateMessage (&msg);
209 DispatchMessage (&msg);
210 }
211 }
212 journ_hook = SetWindowsHookEx (WH_JOURNALPLAYBACK,
213 (HOOKPROC)PTD_playback_proc,
214 glob_hinst, 0);
215 if (journ_hook == NULL)
216 return FALSE;
217
218 while (journ_hook) {
219 if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
220 if (msg.message == WM_QUIT) {
221 if (journ_hook)
222 UnhookWindowsHookEx (journ_hook);
223 PostMessage (msg.hwnd, msg.message, msg.wParam, msg.wParam);
224 }
225 TranslateMessage (&msg);
226 DispatchMessage (&msg);
227 }
228 }
229
230 return TRUE;
231 }
232
233
234 /*FILE *fp;*/
235
236 extern "C" BOOL WINAPI
237 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)
238 {
239 switch (reason) {
240 case DLL_PROCESS_ATTACH:
241 glob_hinst = hinst;
242 /*
243 fp = fopen ("attach_pid.txt", "a+b");
244 if (fp != NULL) {
245 fprintf (fp, "[+ %lu]\r\n", GetCurrentProcessId());
246 fclose (fp);
247 }*/
248 break;
249
250 case DLL_PROCESS_DETACH:
251 /*fp = fopen ("attach_pid.txt", "a+b");
252 if (fp != NULL) {
253 fprintf (fp, "[- %lu]\r\n", GetCurrentProcessId());
254 fclose (fp);
255 }*/
256 break;
257
258 case DLL_THREAD_ATTACH:
259 case DLL_THREAD_DETACH:
260 break;
261
262 }
263
264 return TRUE;
265 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26