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

Annotation of /trunk/PTD/PTD.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

1 werner 46 /* PTD.cpp - Privacy Tray Dynamic
2 twoaday 325 * Copyright (C) 2002-2009 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     #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 werner 61 /* We need a special section in the DLL for storing our shared data.
26 twoaday 261 This shared data is required by the hook function because that
27 werner 61 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 werner 46 #pragma data_seg(".SHARDAT")
35 werner 61 #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 werner 46 #pragma data_seg()
45 werner 61 #endif
46     #undef ATTR_SEC
47 werner 46
48     static unsigned *journ_keys = 0;
49 twoaday 305 static unsigned keyidx = 0;
50 werner 46 static unsigned nkeys = 0;
51 twoaday 273 static HHOOK journ_hook = NULL; /* Journaling hook handle. */
52 werner 46
53    
54 twoaday 248
55 werner 46 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 twoaday 273 GetWindowThreadProcessId (curr_hwnd, &proc_id);
66 werner 46 /* 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 twoaday 305 /*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 werner 46
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 twoaday 305 keyidx++;
160     if (keyidx == nkeys) {
161 werner 46 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 twoaday 305 if (journ_keys[keyidx] & 0x8000)
174     em->message = journ_keys[keyidx] & 0x4000 ? WM_SYSKEYDOWN : WM_KEYDOWN;
175 werner 46 else
176 twoaday 305 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 werner 46 em->paramH = 1;
180     em->time = GetTickCount ();
181     return 0;
182     }
183    
184     return CallNextHookEx (journ_hook, code, wparam, lparam);
185 twoaday 248 }
186 werner 46
187    
188    
189     extern "C" BOOL
190     PTD_keyb_send (UINT *keys, UINT n_keys)
191     {
192     MSG msg;
193     journ_keys = keys;
194 twoaday 305 keyidx = 0;
195 twoaday 325 nkeys = n_keys;
196 werner 46
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 twoaday 325 /*FILE *fp;*/
235 werner 46
236 twoaday 248 extern "C" BOOL WINAPI
237 werner 46 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)
238     {
239     switch (reason) {
240     case DLL_PROCESS_ATTACH:
241 twoaday 325 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 werner 46 break;
249 twoaday 325
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 werner 46 case DLL_THREAD_ATTACH:
259     case DLL_THREAD_DETACH:
260     break;
261 twoaday 325
262 werner 46 }
263 twoaday 325
264 werner 46 return TRUE;
265     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26