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

Diff of /trunk/PTD/PTD.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by twoaday, Mon Jan 31 11:02:21 2005 UTC revision 325 by twoaday, Fri Sep 25 15:51:28 2009 UTC
# Line 1  Line 1 
1  /* PTD.cpp - Privacy Tray Dynamic  /* PTD.cpp - Privacy Tray Dynamic
2   *      Copyright (C) 2002-2005 Timo Schulz   *      Copyright (C) 2002-2009 Timo Schulz
3   *   *
4   * This file is part of WinPT.   * This file is part of WinPT.
5   *   *
6   * WinPT is free software; you can redistribute it and/or modify   * 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   * 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   * the Free Software Foundation; either version 2 of the License, or
9   * (at your option) any later version.   * (at your option) any later version.
10   *   *
11   * WinPT is distributed in the hope that it will be useful,   * WinPT is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.   * GNU General Public License for more details.
15   *   */
16   * You should have received a copy of the GNU General Public License  #ifdef HAVE_CONFIG_H
17   * along with WinPT; if not, write to the Free Software Foundation,  #include <config.h>
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA  #endif
19   */  
20    #include <windows.h>
21  #include <windows.h>  #include <stdio.h>
22  #include <stdio.h>  
23    HINSTANCE glob_hinst;
24  HINSTANCE glob_hinst;  
25    /* We need a special section in the DLL for storing our shared data.
26  /* We need a special section in the DLL for storing our shared data */     This shared data is required by the hook function because that
27  #pragma data_seg(".SHARDAT")     function is called in the context of the actual thread running the
28  static HHOOK cbt_hook = NULL;     hook and thus we need a way to communicate the result of our hook
29  static DWORD tray_proc_id = 0;     function back to us.  We use a shared data segment for this. */
30  static HWND shell_traywnd = 0;  #ifdef __GNUC__
31  static HWND curr_focus = NULL;  #define ATTR_SEC __attribute__((section (".SHARDAT"), shared))
32  static HWND rebar_w32 = NULL;  #else
33  static HWND mstask_swc = NULL;  #define ATTR_SEC
34  static HWND systab_c32 = NULL;  #pragma data_seg(".SHARDAT")
35  #pragma data_seg()  #endif
36    static HHOOK cbt_hook      ATTR_SEC = NULL; /* CTB hook handle. */
37  static unsigned * journ_keys = 0;  static DWORD tray_proc_id  ATTR_SEC = 0;    /* WinPT PID */
38  static unsigned key_idx = 0;  static HWND  shell_traywnd ATTR_SEC = 0;    /* Tray window handle. */
39  static unsigned nkeys = 0;  static HWND  curr_focus    ATTR_SEC = NULL; /* Current window focus handle. */
40  static HHOOK journ_hook = NULL;  static HWND  rebar_w32     ATTR_SEC = NULL;
41    static HWND  mstask_swc    ATTR_SEC = NULL;
42    static HWND  systab_c32    ATTR_SEC = NULL;
43  static LRESULT CALLBACK  #ifndef __GNUC__
44  PTD_CBT_proc (int code, WPARAM wparam, LPARAM lparam)  #pragma data_seg()
45  {  #endif
46      HWND curr_hwnd = NULL;        #undef ATTR_SEC
47      DWORD proc_id = 0;  
48        static unsigned *journ_keys = 0;
49      if (code >= 0 && code == HCBT_SETFOCUS) {  static unsigned keyidx = 0;
50          /* A window is about to receive the keyboard focus */            static unsigned nkeys = 0;
51            static HHOOK journ_hook = NULL;  /* Journaling hook  handle. */
52          curr_hwnd = (HWND)wparam;  
53          GetWindowThreadProcessId( curr_hwnd, &proc_id );  
54          /* Only if the current window is different from this window list,  
55             we set the new focus. For more information read the hint in  static LRESULT CALLBACK
56             PTD_initialize. */  PTD_CBT_proc (int code, WPARAM wparam, LPARAM lparam)
57          if ((proc_id != tray_proc_id)  {
58               && (curr_hwnd != NULL)      HWND curr_hwnd = NULL;      
59               && (curr_hwnd != curr_focus)      DWORD proc_id = 0;
60               && (curr_hwnd != shell_traywnd)      
61               && (curr_hwnd != systab_c32)      if (code >= 0 && code == HCBT_SETFOCUS) {
62               && (curr_hwnd != mstask_swc)          /* A window is about to receive the keyboard focus */          
63               && (curr_hwnd != rebar_w32)) {          
64              curr_focus = curr_hwnd;          curr_hwnd = (HWND)wparam;
65          }          GetWindowThreadProcessId (curr_hwnd, &proc_id);
66      }          /* 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      return  CallNextHookEx (cbt_hook , code, wparam, lparam);             PTD_initialize. */
69  } /* PTD_CBT_proc */          if ((proc_id != tray_proc_id)
70                 && (curr_hwnd != NULL)
71                 && (curr_hwnd != curr_focus)
72  HWND               && (curr_hwnd != shell_traywnd)
73  PTD_get_curr_hwnd (void)               && (curr_hwnd != systab_c32)
74  {               && (curr_hwnd != mstask_swc)
75      return curr_focus;               && (curr_hwnd != rebar_w32)) {
76  } /* PTD_get_curr_hwnd */              curr_focus = curr_hwnd;
77            }
78        }
79  BOOL      
80  PTD_initialize (void)      return  CallNextHookEx (cbt_hook , code, wparam, lparam);
81  {  }
82      tray_proc_id = GetCurrentProcessId( );  
83      cbt_hook = SetWindowsHookEx( WH_CBT, PTD_CBT_proc, glob_hinst, 0 );  
84      if( cbt_hook == NULL )                /* Return the last selected window */
85          return FALSE;  extern "C" HWND
86        PTD_get_curr_hwnd (void)
87      /* Okay, what are we doing here:  {
88       * In the past I used the Spy++ application to find out why the old current window      return curr_focus;
89       * doesn't work on so much systems. Now we try to use the computer based training  }
90       * hook, more precise the HCBT_SETFOCUS to find out the last window focus. But to  
91       * succeed we need to ignore some windows because otherwise our own window or a  
92       * window from the taskbar would be recognized.  /* Initialize CTB hook and try to find the system windows. */
93       *  extern "C" BOOL
94       * Here is what the Spy++ says about the windows order:  PTD_initialize (void)
95       * Shell_TrayWnd  {
96       *  \ ReBarWindow32      tray_proc_id = GetCurrentProcessId ();
97       *                \ MSTaskSwWClass      cbt_hook = SetWindowsHookEx (WH_CBT, PTD_CBT_proc, glob_hinst, 0);
98       *                               \ SysTabControl32      if (cbt_hook == NULL)
99       *          return FALSE;
100       * As a result we need to ignore those windows to prevent failured in the code.      
101       */      /* Okay, what are we doing here:
102      shell_traywnd = FindWindowEx (NULL, NULL, "Shell_TrayWnd", NULL);       * In the past I used the Spy++ application to find out why the old current
103      rebar_w32 = FindWindowEx (shell_traywnd, NULL, "ReBarWindow32", NULL);       * window doesn't work on so much systems. Now we try to use the computer
104      mstask_swc = FindWindowEx (rebar_w32, NULL, "MSTaskSwWClass", NULL);       * based training hook, more precise the HCBT_SETFOCUS to find out the
105      systab_c32 = FindWindowEx (mstask_swc, NULL, "SysTabControl32", NULL);       * 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      /*_log_box ("tray_proc_id=%u cbt_hook=%p shell_traywnd=%p rebar_w32=%p "       * would be recognized.
108                  "mstask_swc=%p systab_c32=%p",       *
109                  tray_proc_id, cbt_hook, shell_traywnd, rebar_w32,       * Here is what the Spy++ says about the windows order:
110                  mstask_swc, systab_c32);*/       * Shell_TrayWnd
111             *  \ ReBarWindow32
112      return TRUE;       *                \ MSTaskSwWClass
113  } /* PTD_initialize */       *                               \ SysTabControl32
114         *
115         * As a result we need to ignore those windows to prevent failured
116  void       * in the code.
117  PTD_delete (void)       */
118  {      shell_traywnd = FindWindowEx (NULL, NULL, "Shell_TrayWnd", NULL);
119      if (!cbt_hook)      rebar_w32 = FindWindowEx (shell_traywnd, NULL, "ReBarWindow32", NULL);
120          return;      mstask_swc = FindWindowEx (rebar_w32, NULL, "MSTaskSwWClass", NULL);
121      UnhookWindowsHookEx (cbt_hook);      systab_c32 = FindWindowEx (mstask_swc, NULL, "SysTabControl32", NULL);
122      cbt_hook = NULL;      
123      shell_traywnd = NULL;      /*debug ("tray_proc_id=%u cbt_hook=%p shell_traywnd=%p rebar_w32=%p "
124      tray_proc_id = 0;               "mstask_swc=%p systab_c32=%p",
125  } /* PTD_delete */               tray_proc_id, cbt_hook, shell_traywnd, rebar_w32,
126                 mstask_swc, systab_c32);*/
127        
128  int      return TRUE;
129  PTD_is_used (void)  }
130  {  
131      return shell_traywnd && cbt_hook;  
132  } /* PTD_is_used */  /* Remove the CTB hook from the system and reset all variables. */
133    extern "C" void
134    PTD_delete (void)
135  LRESULT CALLBACK  {
136  PTD_playback_proc (int code, WPARAM wparam, LPARAM lparam)      if (!cbt_hook)
137  {          return;
138      LPEVENTMSG em;      UnhookWindowsHookEx (cbt_hook);
139            cbt_hook = NULL;
140      if (code == HC_SKIP) {      shell_traywnd = NULL;
141          key_idx++;      tray_proc_id = 0;
142          if (key_idx == nkeys) {  }
143              UnhookWindowsHookEx (journ_hook);  
144              journ_hook = NULL;  
145          }  /* Return if the CTB hook is currently used. */
146          return 0;  extern "C" int
147      }  PTD_is_used (void)
148      else if (code == HC_GETNEXT) {  {
149          /* Here is an overview what the event message struct can contain:      return shell_traywnd && cbt_hook;
150           * message - WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, WM_SYSKEYDOWN:  }
151           * paramL - specifies the virtual key code of the key that was pressed.  
152           * paramH - specifies the scan code.                              
153           */  static LRESULT CALLBACK
154          em = (LPEVENTMSG )lparam;  PTD_playback_proc (int code, WPARAM wparam, LPARAM lparam)
155          if (journ_keys[key_idx] & 0x8000)  {
156              em->message = journ_keys[key_idx] & 0x4000 ? WM_SYSKEYDOWN : WM_KEYDOWN;      LPEVENTMSG em;
157          else      
158              em->message = journ_keys[key_idx] & 0x4000 ? WM_SYSKEYUP : WM_KEYUP;      if (code == HC_SKIP) {
159          em->paramL = LOBYTE( journ_keys[key_idx] )          keyidx++;
160              | (MapVirtualKey (LOBYTE (journ_keys[key_idx]), 0) << 8);          if (keyidx == nkeys) {
161          em->paramH = 1;              UnhookWindowsHookEx (journ_hook);
162          em->time = GetTickCount ();              journ_hook = NULL;
163          return 0;          }
164      }          return 0;
165            }
166      return CallNextHookEx (journ_hook, code, wparam, lparam);      else if (code == HC_GETNEXT) {
167  } /* PTD_Playback_proc */          /* 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  BOOL           * paramH - specifies the scan code.                            
171  PTD_keyb_send (UINT * keys, UINT n_keys)           */
172  {          em = (LPEVENTMSG )lparam;
173      MSG msg;          if (journ_keys[keyidx] & 0x8000)
174                em->message = journ_keys[keyidx] & 0x4000 ? WM_SYSKEYDOWN : WM_KEYDOWN;
175      journ_keys = keys;          else
176      key_idx = 0;              em->message = journ_keys[keyidx] & 0x4000 ? WM_SYSKEYUP : WM_KEYUP;
177      nkeys =  n_keys;              em->paramL = LOBYTE( journ_keys[keyidx] )
178                    | (MapVirtualKey (LOBYTE (journ_keys[keyidx]), 0) << 8);
179      if (journ_hook)          em->paramH = 1;
180          return FALSE;          em->time = GetTickCount ();
181                return 0;
182      while (GetAsyncKeyState (VK_MENU) & 0x8000      }
183              || GetAsyncKeyState (VK_SHIFT) & 0x8000      
184              || GetAsyncKeyState (VK_CONTROL) & 0x8000) {      return CallNextHookEx (journ_hook, code, wparam, lparam);
185          if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {  }
186              if (msg.message == WM_QUIT) {  
187                  PostMessage (msg.hwnd, msg.message, msg.wParam, msg.lParam);  
188                  return FALSE;  
189              }  extern "C" BOOL
190              TranslateMessage (&msg);  PTD_keyb_send (UINT *keys, UINT n_keys)
191              DispatchMessage (&msg);  {
192          }      MSG msg;
193      }      journ_keys = keys;
194      journ_hook = SetWindowsHookEx (WH_JOURNALPLAYBACK,      keyidx = 0;
195                                     (HOOKPROC)PTD_playback_proc,      nkeys = n_keys;    
196                                     glob_hinst, 0);      
197      if (journ_hook == NULL)      if (journ_hook)
198          return FALSE;          return FALSE;
199            
200      while (journ_hook) {      while (GetAsyncKeyState (VK_MENU) & 0x8000
201          if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {              || GetAsyncKeyState (VK_SHIFT) & 0x8000
202              if (msg.message == WM_QUIT) {              || GetAsyncKeyState (VK_CONTROL) & 0x8000) {
203                  if (journ_hook)          if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
204                      UnhookWindowsHookEx (journ_hook);              if (msg.message == WM_QUIT) {
205                  PostMessage (msg.hwnd, msg.message, msg.wParam, msg.wParam);                  PostMessage (msg.hwnd, msg.message, msg.wParam, msg.lParam);
206              }                  return FALSE;
207              TranslateMessage (&msg);              }
208              DispatchMessage (&msg);              TranslateMessage (&msg);
209          }              DispatchMessage (&msg);
210      }          }
211            }
212      return TRUE;      journ_hook = SetWindowsHookEx (WH_JOURNALPLAYBACK,
213  } /* PTD_keyb_send */                                     (HOOKPROC)PTD_playback_proc,
214                                       glob_hinst, 0);
215        if (journ_hook == NULL)
216  const char *          return FALSE;
217  PTD_get_version (void)      
218  {      while (journ_hook) {
219      return "0.8.0";          if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
220  } /* PTD_get_version */              if (msg.message == WM_QUIT) {
221                    if (journ_hook)
222                                        UnhookWindowsHookEx (journ_hook);
223  BOOL WINAPI                  PostMessage (msg.hwnd, msg.message, msg.wParam, msg.wParam);
224  DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)              }
225  {              TranslateMessage (&msg);
226      switch (reason)  {              DispatchMessage (&msg);
227      case DLL_PROCESS_ATTACH:          }
228          glob_hinst = hinst;      }
229          break;      
230      case DLL_THREAD_ATTACH:        return TRUE;
231          break;  }
232      case DLL_THREAD_DETACH:    
233          break;  
234      case DLL_PROCESS_DETACH:  /*FILE *fp;*/
235          break;  
236      }  extern "C" BOOL WINAPI
237      return TRUE;  DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)
238  } /* DllMain */  {
239        switch (reason)  {
240        case DLL_PROCESS_ATTACH:
241            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            break;
249          
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        case DLL_THREAD_ATTACH:  
259        case DLL_THREAD_DETACH:  
260            break;
261            
262        }
263        
264        return TRUE;
265    }

Legend:
Removed from v.2  
changed lines
  Added in v.325

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26