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

Annotation of /trunk/PTD/PTD.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 261 - (hide annotations)
Sat Sep 30 10:24:23 2006 UTC (18 years, 5 months ago) by twoaday
File size: 8533 byte(s)


1 werner 46 /* PTD.cpp - Privacy Tray Dynamic
2 twoaday 248 * Copyright (C) 2002-2006 Timo Schulz
3 werner 46 *
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 werner 61 /* We need a special section in the DLL for storing our shared data.
35 twoaday 261 This shared data is required by the hook function because that
36 werner 61 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 werner 46 #pragma data_seg(".SHARDAT")
44 werner 61 #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 werner 46 #pragma data_seg()
54 werner 61 #endif
55     #undef ATTR_SEC
56 werner 46
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 twoaday 248 void dns_cleanup (void);
64    
65    
66 werner 46 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 twoaday 248 dns_cleanup ();
150 werner 46 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 twoaday 248 }
198 werner 46
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 twoaday 165 POINT sizewnd;
253     RECT rwnd;
254 werner 46 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 twoaday 165 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 werner 46
271     ReleaseDC (hwnd, hdc);
272     jpg.freePictureData ();
273     return rc;
274     }
275    
276    
277 twoaday 248 extern "C" BOOL WINAPI
278 werner 46 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)
279     {
280     switch (reason) {
281     case DLL_PROCESS_ATTACH:
282 twoaday 248 glob_hinst = hinst;
283 werner 46 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