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

Contents of /trunk/PTD/PTD.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 61 - (show annotations)
Wed Nov 2 14:48:01 2005 UTC (19 years, 3 months ago) by werner
File size: 8453 byte(s)
Fixed DLLMain linkage and enabled shared segment.

1 /* PTD.cpp - Privacy Tray Dynamic
2 * Copyright (C) 2002-2005 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 <windows.h>
27 #include <stdio.h>
28 #include <ocidl.h>
29 #include <olectl.h>
30
31 #include "wptJPG.h"
32
33 HINSTANCE glob_hinst;
34
35 /* We need a special section in the DLL for storing our shared data.
36 This shared data is required by the hook function becuase theat
37 function is called in the context of the actual thread running the
38 hook and thus we need a way to communicate the result of our hook
39 function back to us. We use a shared data segment for this. */
40 #ifdef __GNUC__
41 #define ATTR_SEC __attribute__((section (".SHARDAT"), shared))
42 #else
43 #define ATTR_SEC
44 #pragma data_seg(".SHARDAT")
45 #endif
46 static HHOOK cbt_hook ATTR_SEC = NULL; /* CTB hook handle. */
47 static DWORD tray_proc_id ATTR_SEC = 0; /* WinPT PID */
48 static HWND shell_traywnd ATTR_SEC = 0; /* Tray window handle. */
49 static HWND curr_focus ATTR_SEC = NULL; /* Current window focus handle. */
50 static HWND rebar_w32 ATTR_SEC = NULL;
51 static HWND mstask_swc ATTR_SEC = NULL;
52 static HWND systab_c32 ATTR_SEC = NULL;
53 #ifndef __GNUC__
54 #pragma data_seg()
55 #endif
56 #undef ATTR_SEC
57
58
59 static unsigned *journ_keys = 0;
60 static unsigned key_idx = 0;
61 static unsigned nkeys = 0;
62 static HHOOK journ_hook = NULL; /* Journaling hook handle. */
63
64
65 static LRESULT CALLBACK
66 PTD_CBT_proc (int code, WPARAM wparam, LPARAM lparam)
67 {
68 HWND curr_hwnd = NULL;
69 DWORD proc_id = 0;
70
71 if (code >= 0 && code == HCBT_SETFOCUS) {
72 /* A window is about to receive the keyboard focus */
73
74 curr_hwnd = (HWND)wparam;
75 GetWindowThreadProcessId( curr_hwnd, &proc_id );
76 /* Only if the current window is different from this window list,
77 we set the new focus. For more information read the hint in
78 PTD_initialize. */
79 if ((proc_id != tray_proc_id)
80 && (curr_hwnd != NULL)
81 && (curr_hwnd != curr_focus)
82 && (curr_hwnd != shell_traywnd)
83 && (curr_hwnd != systab_c32)
84 && (curr_hwnd != mstask_swc)
85 && (curr_hwnd != rebar_w32)) {
86 curr_focus = curr_hwnd;
87 }
88 }
89
90 return CallNextHookEx (cbt_hook , code, wparam, lparam);
91 }
92
93
94 /* Return the last selected window */
95 extern "C" HWND
96 PTD_get_curr_hwnd (void)
97 {
98 return curr_focus;
99 }
100
101
102 /* Initialize CTB hook and try to find the system windows. */
103 extern "C" BOOL
104 PTD_initialize (void)
105 {
106 tray_proc_id = GetCurrentProcessId ();
107 cbt_hook = SetWindowsHookEx (WH_CBT, PTD_CBT_proc, glob_hinst, 0);
108 if (cbt_hook == NULL)
109 return FALSE;
110
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 UnhookWindowsHookEx (cbt_hook);
150 cbt_hook = NULL;
151 shell_traywnd = NULL;
152 tray_proc_id = 0;
153 }
154
155
156 /* Return if the CTB hook is currently used. */
157 extern "C" int
158 PTD_is_used (void)
159 {
160 return shell_traywnd && cbt_hook;
161 }
162
163
164 static LRESULT CALLBACK
165 PTD_playback_proc (int code, WPARAM wparam, LPARAM lparam)
166 {
167 LPEVENTMSG em;
168
169 if (code == HC_SKIP) {
170 key_idx++;
171 if (key_idx == nkeys) {
172 UnhookWindowsHookEx (journ_hook);
173 journ_hook = NULL;
174 }
175 return 0;
176 }
177 else if (code == HC_GETNEXT) {
178 /* Here is an overview what the event message struct can contain:
179 * message - WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, WM_SYSKEYDOWN:
180 * paramL - specifies the virtual key code of the key that was pressed.
181 * paramH - specifies the scan code.
182 */
183 em = (LPEVENTMSG )lparam;
184 if (journ_keys[key_idx] & 0x8000)
185 em->message = journ_keys[key_idx] & 0x4000 ? WM_SYSKEYDOWN : WM_KEYDOWN;
186 else
187 em->message = journ_keys[key_idx] & 0x4000 ? WM_SYSKEYUP : WM_KEYUP;
188 em->paramL = LOBYTE( journ_keys[key_idx] )
189 | (MapVirtualKey (LOBYTE (journ_keys[key_idx]), 0) << 8);
190 em->paramH = 1;
191 em->time = GetTickCount ();
192 return 0;
193 }
194
195 return CallNextHookEx (journ_hook, code, wparam, lparam);
196 } /* PTD_Playback_proc */
197
198
199
200 extern "C" BOOL
201 PTD_keyb_send (UINT *keys, UINT n_keys)
202 {
203 MSG msg;
204 journ_keys = keys;
205 key_idx = 0;
206 nkeys = n_keys;
207
208 if (journ_hook)
209 return FALSE;
210
211 while (GetAsyncKeyState (VK_MENU) & 0x8000
212 || GetAsyncKeyState (VK_SHIFT) & 0x8000
213 || GetAsyncKeyState (VK_CONTROL) & 0x8000) {
214 if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
215 if (msg.message == WM_QUIT) {
216 PostMessage (msg.hwnd, msg.message, msg.wParam, msg.lParam);
217 return FALSE;
218 }
219 TranslateMessage (&msg);
220 DispatchMessage (&msg);
221 }
222 }
223 journ_hook = SetWindowsHookEx (WH_JOURNALPLAYBACK,
224 (HOOKPROC)PTD_playback_proc,
225 glob_hinst, 0);
226 if (journ_hook == NULL)
227 return FALSE;
228
229 while (journ_hook) {
230 if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
231 if (msg.message == WM_QUIT) {
232 if (journ_hook)
233 UnhookWindowsHookEx (journ_hook);
234 PostMessage (msg.hwnd, msg.message, msg.wParam, msg.wParam);
235 }
236 TranslateMessage (&msg);
237 DispatchMessage (&msg);
238 }
239 }
240
241 return TRUE;
242 }
243
244
245 /* Display a JPG picture in the given window at the given point. */
246 extern "C" int
247 PTD_jpg_show (HWND hwnd, POINT *p, LPCSTR name)
248 {
249 CJPG jpg;
250 HDC hdc;
251 POINT p2;
252 BOOL rc;
253
254 rc = jpg.load (name);
255 if (!rc)
256 return -1; /* XXX: use real return code. */
257 hdc = GetWindowDC (hwnd);
258 rc = jpg.updateSizeOnDC (hdc);
259 if (!rc) {
260 ReleaseDC (hwnd, hdc);
261 return -2; /* XXX: use real return code. */
262 }
263
264 p2.x = jpg.m_Width;
265 p2.y = jpg.m_Height;
266 rc = jpg.show (hdc, p, &p2, 0, 0);
267
268 ReleaseDC (hwnd, hdc);
269 jpg.freePictureData ();
270 return rc;
271 }
272
273
274
275 extern "C" int WINAPI
276 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)
277 {
278 switch (reason) {
279 case DLL_PROCESS_ATTACH:
280 glob_hinst = hinst;
281 break;
282 case DLL_THREAD_ATTACH:
283 break;
284 case DLL_THREAD_DETACH:
285 break;
286 case DLL_PROCESS_DETACH:
287 break;
288 }
289 return TRUE;
290 }
291

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26