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

Contents of /trunk/PTD/PTD.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 305 - (show annotations)
Fri Mar 23 11:32:28 2007 UTC (17 years, 11 months ago) by twoaday
File size: 8305 byte(s)


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26