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

Annotation of /trunk/PTD/PTD.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 61 - (hide 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 werner 46 /* 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 werner 61 /* 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 werner 46 #pragma data_seg(".SHARDAT")
45 werner 61 #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 werner 46 #pragma data_seg()
55 werner 61 #endif
56     #undef ATTR_SEC
57 werner 46
58 werner 61
59 werner 46 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 werner 57
112 werner 46 /* 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 werner 61 extern "C" int WINAPI
276 werner 46 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)
277     {
278     switch (reason) {
279     case DLL_PROCESS_ATTACH:
280 werner 57 glob_hinst = hinst;
281 werner 46 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