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

Contents of /trunk/PTD/PTD.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 273 - (show annotations)
Fri Dec 8 10:22:17 2006 UTC (18 years, 2 months ago) by twoaday
File size: 8529 byte(s)


1 /* PTD.cpp - Privacy Tray Dynamic
2 * Copyright (C) 2002-2006 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 * You should have received a copy of the GNU General Public License
17 * along with WinPT; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <windows.h>
26 #include <stdio.h>
27 #include <ocidl.h>
28 #include <olectl.h>
29
30 #include "wptJPG.h"
31
32 HINSTANCE glob_hinst;
33
34 /* We need a special section in the DLL for storing our shared data.
35 This shared data is required by the hook function because that
36 function is called in the context of the actual thread running the
37 hook and thus we need a way to communicate the result of our hook
38 function back to us. We use a shared data segment for this. */
39 #ifdef __GNUC__
40 #define ATTR_SEC __attribute__((section (".SHARDAT"), shared))
41 #else
42 #define ATTR_SEC
43 #pragma data_seg(".SHARDAT")
44 #endif
45 static HHOOK cbt_hook ATTR_SEC = NULL; /* CTB hook handle. */
46 static DWORD tray_proc_id ATTR_SEC = 0; /* WinPT PID */
47 static HWND shell_traywnd ATTR_SEC = 0; /* Tray window handle. */
48 static HWND curr_focus ATTR_SEC = NULL; /* Current window focus handle. */
49 static HWND rebar_w32 ATTR_SEC = NULL;
50 static HWND mstask_swc ATTR_SEC = NULL;
51 static HWND systab_c32 ATTR_SEC = NULL;
52 #ifndef __GNUC__
53 #pragma data_seg()
54 #endif
55 #undef ATTR_SEC
56
57 static unsigned *journ_keys = 0;
58 static unsigned key_idx = 0;
59 static unsigned nkeys = 0;
60 static HHOOK journ_hook = NULL; /* Journaling hook handle. */
61
62
63 void dns_cleanup (void);
64
65
66 static LRESULT CALLBACK
67 PTD_CBT_proc (int code, WPARAM wparam, LPARAM lparam)
68 {
69 HWND curr_hwnd = NULL;
70 DWORD proc_id = 0;
71
72 if (code >= 0 && code == HCBT_SETFOCUS) {
73 /* A window is about to receive the keyboard focus */
74
75 curr_hwnd = (HWND)wparam;
76 GetWindowThreadProcessId (curr_hwnd, &proc_id);
77 /* Only if the current window is different from this window list,
78 we set the new focus. For more information read the hint in
79 PTD_initialize. */
80 if ((proc_id != tray_proc_id)
81 && (curr_hwnd != NULL)
82 && (curr_hwnd != curr_focus)
83 && (curr_hwnd != shell_traywnd)
84 && (curr_hwnd != systab_c32)
85 && (curr_hwnd != mstask_swc)
86 && (curr_hwnd != rebar_w32)) {
87 curr_focus = curr_hwnd;
88 }
89 }
90
91 return CallNextHookEx (cbt_hook , code, wparam, lparam);
92 }
93
94
95 /* Return the last selected window */
96 extern "C" HWND
97 PTD_get_curr_hwnd (void)
98 {
99 return curr_focus;
100 }
101
102
103 /* Initialize CTB hook and try to find the system windows. */
104 extern "C" BOOL
105 PTD_initialize (void)
106 {
107 tray_proc_id = GetCurrentProcessId ();
108 cbt_hook = SetWindowsHookEx (WH_CBT, PTD_CBT_proc, glob_hinst, 0);
109 if (cbt_hook == NULL)
110 return FALSE;
111
112 /* Okay, what are we doing here:
113 * In the past I used the Spy++ application to find out why the old current
114 * window doesn't work on so much systems. Now we try to use the computer
115 * based training hook, more precise the HCBT_SETFOCUS to find out the
116 * last window focus. But to succeed we need to ignore some windows
117 * because otherwise our own window or a window from the taskbar
118 * would be recognized.
119 *
120 * Here is what the Spy++ says about the windows order:
121 * Shell_TrayWnd
122 * \ ReBarWindow32
123 * \ MSTaskSwWClass
124 * \ SysTabControl32
125 *
126 * As a result we need to ignore those windows to prevent failured
127 * in the code.
128 */
129 shell_traywnd = FindWindowEx (NULL, NULL, "Shell_TrayWnd", NULL);
130 rebar_w32 = FindWindowEx (shell_traywnd, NULL, "ReBarWindow32", NULL);
131 mstask_swc = FindWindowEx (rebar_w32, NULL, "MSTaskSwWClass", NULL);
132 systab_c32 = FindWindowEx (mstask_swc, NULL, "SysTabControl32", NULL);
133
134 /*log_foo ("tray_proc_id=%u cbt_hook=%p shell_traywnd=%p rebar_w32=%p "
135 "mstask_swc=%p systab_c32=%p",
136 tray_proc_id, cbt_hook, shell_traywnd, rebar_w32,
137 mstask_swc, systab_c32);*/
138
139 return TRUE;
140 }
141
142
143 /* Remove the CTB hook from the system and reset all variables. */
144 extern "C" void
145 PTD_delete (void)
146 {
147 if (!cbt_hook)
148 return;
149 dns_cleanup ();
150 UnhookWindowsHookEx (cbt_hook);
151 cbt_hook = NULL;
152 shell_traywnd = NULL;
153 tray_proc_id = 0;
154 }
155
156
157 /* Return if the CTB hook is currently used. */
158 extern "C" int
159 PTD_is_used (void)
160 {
161 return shell_traywnd && cbt_hook;
162 }
163
164
165 static LRESULT CALLBACK
166 PTD_playback_proc (int code, WPARAM wparam, LPARAM lparam)
167 {
168 LPEVENTMSG em;
169
170 if (code == HC_SKIP) {
171 key_idx++;
172 if (key_idx == nkeys) {
173 UnhookWindowsHookEx (journ_hook);
174 journ_hook = NULL;
175 }
176 return 0;
177 }
178 else if (code == HC_GETNEXT) {
179 /* Here is an overview what the event message struct can contain:
180 * message - WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, WM_SYSKEYDOWN:
181 * paramL - specifies the virtual key code of the key that was pressed.
182 * paramH - specifies the scan code.
183 */
184 em = (LPEVENTMSG )lparam;
185 if (journ_keys[key_idx] & 0x8000)
186 em->message = journ_keys[key_idx] & 0x4000 ? WM_SYSKEYDOWN : WM_KEYDOWN;
187 else
188 em->message = journ_keys[key_idx] & 0x4000 ? WM_SYSKEYUP : WM_KEYUP;
189 em->paramL = LOBYTE( journ_keys[key_idx] )
190 | (MapVirtualKey (LOBYTE (journ_keys[key_idx]), 0) << 8);
191 em->paramH = 1;
192 em->time = GetTickCount ();
193 return 0;
194 }
195
196 return CallNextHookEx (journ_hook, code, wparam, lparam);
197 }
198
199
200
201 extern "C" BOOL
202 PTD_keyb_send (UINT *keys, UINT n_keys)
203 {
204 MSG msg;
205 journ_keys = keys;
206 key_idx = 0;
207 nkeys = n_keys;
208
209 if (journ_hook)
210 return FALSE;
211
212 while (GetAsyncKeyState (VK_MENU) & 0x8000
213 || GetAsyncKeyState (VK_SHIFT) & 0x8000
214 || GetAsyncKeyState (VK_CONTROL) & 0x8000) {
215 if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
216 if (msg.message == WM_QUIT) {
217 PostMessage (msg.hwnd, msg.message, msg.wParam, msg.lParam);
218 return FALSE;
219 }
220 TranslateMessage (&msg);
221 DispatchMessage (&msg);
222 }
223 }
224 journ_hook = SetWindowsHookEx (WH_JOURNALPLAYBACK,
225 (HOOKPROC)PTD_playback_proc,
226 glob_hinst, 0);
227 if (journ_hook == NULL)
228 return FALSE;
229
230 while (journ_hook) {
231 if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
232 if (msg.message == WM_QUIT) {
233 if (journ_hook)
234 UnhookWindowsHookEx (journ_hook);
235 PostMessage (msg.hwnd, msg.message, msg.wParam, msg.wParam);
236 }
237 TranslateMessage (&msg);
238 DispatchMessage (&msg);
239 }
240 }
241
242 return TRUE;
243 }
244
245
246 /* Display a JPG picture in the given window at the given point. */
247 extern "C" int
248 PTD_jpg_show (HWND hwnd, POINT *p, LPCSTR name)
249 {
250 CJPG jpg;
251 HDC hdc;
252 POINT sizewnd;
253 RECT rwnd;
254 BOOL rc;
255
256 rc = jpg.load (name);
257 if (!rc)
258 return -1; /* XXX: use real return code. */
259 hdc = GetWindowDC (hwnd);
260 rc = jpg.updateSizeOnDC (hdc);
261 if (!rc) {
262 ReleaseDC (hwnd, hdc);
263 return -2; /* XXX: use real return code. */
264 }
265
266 GetWindowRect (hwnd, &rwnd);
267 sizewnd.x = rwnd.right - rwnd.left;
268 sizewnd.y = rwnd.bottom - rwnd.top;
269 rc = jpg.show (hdc, p, &sizewnd, 0, 0);
270
271 ReleaseDC (hwnd, hdc);
272 jpg.freePictureData ();
273 return rc;
274 }
275
276
277 extern "C" BOOL WINAPI
278 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)
279 {
280 switch (reason) {
281 case DLL_PROCESS_ATTACH:
282 glob_hinst = hinst;
283 break;
284 case DLL_THREAD_ATTACH:
285 break;
286 case DLL_THREAD_DETACH:
287 break;
288 case DLL_PROCESS_DETACH:
289 break;
290 }
291 return TRUE;
292 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26