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

Annotation of /trunk/PTD/PTD.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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


1 werner 46 /* PTD.cpp - Privacy Tray Dynamic
2 twoaday 305 * Copyright (C) 2002-2007 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     #include <ocidl.h>
23     #include <olectl.h>
24    
25     #include "wptJPG.h"
26    
27     HINSTANCE glob_hinst;
28    
29 werner 61 /* We need a special section in the DLL for storing our shared data.
30 twoaday 261 This shared data is required by the hook function because that
31 werner 61 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 werner 46 #pragma data_seg(".SHARDAT")
39 werner 61 #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 werner 46 #pragma data_seg()
49 werner 61 #endif
50     #undef ATTR_SEC
51 werner 46
52     static unsigned *journ_keys = 0;
53 twoaday 305 static unsigned keyidx = 0;
54 werner 46 static unsigned nkeys = 0;
55 twoaday 273 static HHOOK journ_hook = NULL; /* Journaling hook handle. */
56 werner 46
57    
58 twoaday 248 void dns_cleanup (void);
59    
60    
61 werner 46 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 twoaday 273 GetWindowThreadProcessId (curr_hwnd, &proc_id);
72 werner 46 /* 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 twoaday 305 /*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 werner 46
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 twoaday 248 dns_cleanup ();
145 werner 46 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 twoaday 305 keyidx++;
167     if (keyidx == nkeys) {
168 werner 46 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 twoaday 305 if (journ_keys[keyidx] & 0x8000)
181     em->message = journ_keys[keyidx] & 0x4000 ? WM_SYSKEYDOWN : WM_KEYDOWN;
182 werner 46 else
183 twoaday 305 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 werner 46 em->paramH = 1;
187     em->time = GetTickCount ();
188     return 0;
189     }
190    
191     return CallNextHookEx (journ_hook, code, wparam, lparam);
192 twoaday 248 }
193 werner 46
194    
195    
196     extern "C" BOOL
197     PTD_keyb_send (UINT *keys, UINT n_keys)
198     {
199     MSG msg;
200     journ_keys = keys;
201 twoaday 305 keyidx = 0;
202 werner 46 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 twoaday 165 POINT sizewnd;
248     RECT rwnd;
249 werner 46 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 twoaday 165 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 werner 46
266     ReleaseDC (hwnd, hdc);
267     jpg.freePictureData ();
268     return rc;
269     }
270    
271    
272 twoaday 248 extern "C" BOOL WINAPI
273 werner 46 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)
274     {
275     switch (reason) {
276     case DLL_PROCESS_ATTACH:
277 twoaday 248 glob_hinst = hinst;
278 werner 46 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