/[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 33 by twoaday, Tue Oct 25 07:46:20 2005 UTC revision 61 by werner, Wed Nov 2 14:48:01 2005 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-2005 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   * You should have received a copy of the GNU General Public License
17   * along with WinPT; if not, write to the Free Software Foundation,   * along with WinPT; if not, write to the Free Software Foundation,
18   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA   * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19   */   */
20    
21  #include <windows.h>  #ifdef HAVE_CONFIG_H
22  #include <stdio.h>  #include <config.h>
23  #include <ocidl.h>  #endif
24  #include <olectl.h>  
25    #include <windows.h>
26  #include "wptJPG.h"  #include <windows.h>
27    #include <stdio.h>
28  HINSTANCE glob_hinst;  #include <ocidl.h>
29    #include <olectl.h>
30  /* We need a special section in the DLL for storing our shared data */  
31  #pragma data_seg(".SHARDAT")  #include "wptJPG.h"
32  static HHOOK    cbt_hook = NULL;    /* CTB hook handle. */  
33  static DWORD    tray_proc_id = 0;   /* WinPT PID */  HINSTANCE glob_hinst;
34  static HWND     shell_traywnd = 0;  /* Tray window handle. */  
35  static HWND     curr_focus = NULL;  /* Current window focus handle. */  /* We need a special section in the DLL for storing our shared data.
36  static HWND     rebar_w32 = NULL;     This shared data is required by the hook function becuase theat
37  static HWND     mstask_swc = NULL;     function is called in the context of the actual thread running the
38  static HWND     systab_c32 = NULL;     hook and thus we need a way to communicate the result of our hook
39  #pragma data_seg()     function back to us.  We use a shared data segment for this. */
40    #ifdef __GNUC__
41  static unsigned *journ_keys = 0;  #define ATTR_SEC __attribute__((section (".SHARDAT"), shared))
42  static unsigned key_idx = 0;  #else
43  static unsigned nkeys = 0;  #define ATTR_SEC
44  static HHOOK journ_hook = NULL;     /* Journaling hook  handle. */  #pragma data_seg(".SHARDAT")
45    #endif
46    static HHOOK cbt_hook      ATTR_SEC = NULL; /* CTB hook handle. */
47  static LRESULT CALLBACK  static DWORD tray_proc_id  ATTR_SEC = 0;    /* WinPT PID */
48  PTD_CBT_proc (int code, WPARAM wparam, LPARAM lparam)  static HWND  shell_traywnd ATTR_SEC = 0;    /* Tray window handle. */
49  {  static HWND  curr_focus    ATTR_SEC = NULL; /* Current window focus handle. */
50      HWND curr_hwnd = NULL;        static HWND  rebar_w32     ATTR_SEC = NULL;
51      DWORD proc_id = 0;  static HWND  mstask_swc    ATTR_SEC = NULL;
52        static HWND  systab_c32    ATTR_SEC = NULL;
53      if (code >= 0 && code == HCBT_SETFOCUS) {  #ifndef __GNUC__
54          /* A window is about to receive the keyboard focus */            #pragma data_seg()
55            #endif
56          curr_hwnd = (HWND)wparam;  #undef ATTR_SEC
57          GetWindowThreadProcessId( curr_hwnd, &proc_id );  
58          /* Only if the current window is different from this window list,  
59             we set the new focus. For more information read the hint in  static unsigned *journ_keys = 0;
60             PTD_initialize. */  static unsigned key_idx = 0;
61          if ((proc_id != tray_proc_id)  static unsigned nkeys = 0;
62               && (curr_hwnd != NULL)  static HHOOK journ_hook = NULL;     /* Journaling hook  handle. */
63               && (curr_hwnd != curr_focus)  
64               && (curr_hwnd != shell_traywnd)  
65               && (curr_hwnd != systab_c32)  static LRESULT CALLBACK
66               && (curr_hwnd != mstask_swc)  PTD_CBT_proc (int code, WPARAM wparam, LPARAM lparam)
67               && (curr_hwnd != rebar_w32)) {  {
68              curr_focus = curr_hwnd;      HWND curr_hwnd = NULL;      
69          }      DWORD proc_id = 0;
70      }      
71            if (code >= 0 && code == HCBT_SETFOCUS) {
72      return  CallNextHookEx (cbt_hook , code, wparam, lparam);          /* A window is about to receive the keyboard focus */          
73  }          
74            curr_hwnd = (HWND)wparam;
75            GetWindowThreadProcessId( curr_hwnd, &proc_id );
76  /* Return the last selected window */          /* Only if the current window is different from this window list,
77  HWND             we set the new focus. For more information read the hint in
78  PTD_get_curr_hwnd (void)             PTD_initialize. */
79  {          if ((proc_id != tray_proc_id)
80      return curr_focus;               && (curr_hwnd != NULL)
81  }               && (curr_hwnd != curr_focus)
82                 && (curr_hwnd != shell_traywnd)
83                 && (curr_hwnd != systab_c32)
84  /* Initialize CTB hook and try to find the system windows. */               && (curr_hwnd != mstask_swc)
85  BOOL               && (curr_hwnd != rebar_w32)) {
86  PTD_initialize (void)              curr_focus = curr_hwnd;
87  {          }
88      tray_proc_id = GetCurrentProcessId ();      }
89      cbt_hook = SetWindowsHookEx (WH_CBT, PTD_CBT_proc, glob_hinst, 0);      
90      if (cbt_hook == NULL)      return  CallNextHookEx (cbt_hook , code, wparam, lparam);
91          return FALSE;  }
92        
93      /* Okay, what are we doing here:  
94       * In the past I used the Spy++ application to find out why the old current  /* Return the last selected window */
95       * window doesn't work on so much systems. Now we try to use the computer  extern "C" HWND
96       * based training hook, more precise the HCBT_SETFOCUS to find out the  PTD_get_curr_hwnd (void)
97       * last window focus. But to succeed we need to ignore some windows  {
98       * because otherwise our own window or a window from the taskbar      return curr_focus;
99       * would be recognized.  }
100       *  
101       * Here is what the Spy++ says about the windows order:  
102       * Shell_TrayWnd  /* Initialize CTB hook and try to find the system windows. */
103       *  \ ReBarWindow32  extern "C" BOOL
104       *                \ MSTaskSwWClass  PTD_initialize (void)
105       *                               \ SysTabControl32  {
106       *      tray_proc_id = GetCurrentProcessId ();
107       * As a result we need to ignore those windows to prevent failured      cbt_hook = SetWindowsHookEx (WH_CBT, PTD_CBT_proc, glob_hinst, 0);
108       * in the code.      if (cbt_hook == NULL)
109       */          return FALSE;
110      shell_traywnd = FindWindowEx (NULL, NULL, "Shell_TrayWnd", NULL);      
111      rebar_w32 = FindWindowEx (shell_traywnd, NULL, "ReBarWindow32", NULL);  
112      mstask_swc = FindWindowEx (rebar_w32, NULL, "MSTaskSwWClass", NULL);      /* Okay, what are we doing here:
113      systab_c32 = FindWindowEx (mstask_swc, NULL, "SysTabControl32", NULL);       * 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      /*log_foo ("tray_proc_id=%u cbt_hook=%p shell_traywnd=%p rebar_w32=%p "       * based training hook, more precise the HCBT_SETFOCUS to find out the
116                 "mstask_swc=%p systab_c32=%p",       * last window focus. But to succeed we need to ignore some windows
117                 tray_proc_id, cbt_hook, shell_traywnd, rebar_w32,       * because otherwise our own window or a window from the taskbar
118                 mstask_swc, systab_c32);*/       * would be recognized.
119             *
120      return TRUE;       * Here is what the Spy++ says about the windows order:
121  }       * Shell_TrayWnd
122         *  \ ReBarWindow32
123         *                \ MSTaskSwWClass
124  /* Remove the CTB hook from the system and reset all variables. */       *                               \ SysTabControl32
125  void       *
126  PTD_delete (void)       * As a result we need to ignore those windows to prevent failured
127  {       * in the code.
128      if (!cbt_hook)       */
129          return;      shell_traywnd = FindWindowEx (NULL, NULL, "Shell_TrayWnd", NULL);
130      UnhookWindowsHookEx (cbt_hook);      rebar_w32 = FindWindowEx (shell_traywnd, NULL, "ReBarWindow32", NULL);
131      cbt_hook = NULL;      mstask_swc = FindWindowEx (rebar_w32, NULL, "MSTaskSwWClass", NULL);
132      shell_traywnd = NULL;      systab_c32 = FindWindowEx (mstask_swc, NULL, "SysTabControl32", NULL);
133      tray_proc_id = 0;      
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  /* Return if the CTB hook is currently used. */                 mstask_swc, systab_c32);*/
138  int      
139  PTD_is_used (void)      return TRUE;
140  {  }
141      return shell_traywnd && cbt_hook;  
142  }  
143    /* Remove the CTB hook from the system and reset all variables. */
144    extern "C" void
145  static LRESULT CALLBACK  PTD_delete (void)
146  PTD_playback_proc (int code, WPARAM wparam, LPARAM lparam)  {
147  {      if (!cbt_hook)
148      LPEVENTMSG em;          return;
149            UnhookWindowsHookEx (cbt_hook);
150      if (code == HC_SKIP) {      cbt_hook = NULL;
151          key_idx++;      shell_traywnd = NULL;
152          if (key_idx == nkeys) {      tray_proc_id = 0;
153              UnhookWindowsHookEx (journ_hook);  }
154              journ_hook = NULL;  
155          }  
156          return 0;  /* Return if the CTB hook is currently used. */
157      }  extern "C" int
158      else if (code == HC_GETNEXT) {  PTD_is_used (void)
159          /* Here is an overview what the event message struct can contain:  {
160           * message - WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, WM_SYSKEYDOWN:      return shell_traywnd && cbt_hook;
161           * paramL - specifies the virtual key code of the key that was pressed.  }
162           * paramH - specifies the scan code.                              
163           */  
164          em = (LPEVENTMSG )lparam;  static LRESULT CALLBACK
165          if (journ_keys[key_idx] & 0x8000)  PTD_playback_proc (int code, WPARAM wparam, LPARAM lparam)
166              em->message = journ_keys[key_idx] & 0x4000 ? WM_SYSKEYDOWN : WM_KEYDOWN;  {
167          else      LPEVENTMSG em;
168              em->message = journ_keys[key_idx] & 0x4000 ? WM_SYSKEYUP : WM_KEYUP;      
169          em->paramL = LOBYTE( journ_keys[key_idx] )      if (code == HC_SKIP) {
170              | (MapVirtualKey (LOBYTE (journ_keys[key_idx]), 0) << 8);          key_idx++;
171          em->paramH = 1;          if (key_idx == nkeys) {
172          em->time = GetTickCount ();              UnhookWindowsHookEx (journ_hook);
173          return 0;              journ_hook = NULL;
174      }          }
175                return 0;
176      return CallNextHookEx (journ_hook, code, wparam, lparam);      }
177  } /* PTD_Playback_proc */      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  BOOL           * paramH - specifies the scan code.                            
182  PTD_keyb_send (UINT *keys, UINT n_keys)           */
183  {          em = (LPEVENTMSG )lparam;
184      MSG msg;          if (journ_keys[key_idx] & 0x8000)
185      journ_keys = keys;              em->message = journ_keys[key_idx] & 0x4000 ? WM_SYSKEYDOWN : WM_KEYDOWN;
186      key_idx = 0;          else
187      nkeys =  n_keys;                  em->message = journ_keys[key_idx] & 0x4000 ? WM_SYSKEYUP : WM_KEYUP;
188                em->paramL = LOBYTE( journ_keys[key_idx] )
189      if (journ_hook)              | (MapVirtualKey (LOBYTE (journ_keys[key_idx]), 0) << 8);
190          return FALSE;          em->paramH = 1;
191                em->time = GetTickCount ();
192      while (GetAsyncKeyState (VK_MENU) & 0x8000          return 0;
193              || GetAsyncKeyState (VK_SHIFT) & 0x8000      }
194              || GetAsyncKeyState (VK_CONTROL) & 0x8000) {      
195          if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {      return CallNextHookEx (journ_hook, code, wparam, lparam);
196              if (msg.message == WM_QUIT) {  } /* PTD_Playback_proc */
197                  PostMessage (msg.hwnd, msg.message, msg.wParam, msg.lParam);  
198                  return FALSE;  
199              }  
200              TranslateMessage (&msg);  extern "C" BOOL
201              DispatchMessage (&msg);  PTD_keyb_send (UINT *keys, UINT n_keys)
202          }  {
203      }      MSG msg;
204      journ_hook = SetWindowsHookEx (WH_JOURNALPLAYBACK,      journ_keys = keys;
205                                     (HOOKPROC)PTD_playback_proc,      key_idx = 0;
206                                     glob_hinst, 0);      nkeys =  n_keys;    
207      if (journ_hook == NULL)      
208          return FALSE;      if (journ_hook)
209                return FALSE;
210      while (journ_hook) {      
211          if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {      while (GetAsyncKeyState (VK_MENU) & 0x8000
212              if (msg.message == WM_QUIT) {              || GetAsyncKeyState (VK_SHIFT) & 0x8000
213                  if (journ_hook)              || GetAsyncKeyState (VK_CONTROL) & 0x8000) {
214                      UnhookWindowsHookEx (journ_hook);          if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
215                  PostMessage (msg.hwnd, msg.message, msg.wParam, msg.wParam);              if (msg.message == WM_QUIT) {
216              }                  PostMessage (msg.hwnd, msg.message, msg.wParam, msg.lParam);
217              TranslateMessage (&msg);                  return FALSE;
218              DispatchMessage (&msg);              }
219          }              TranslateMessage (&msg);
220      }              DispatchMessage (&msg);
221                }
222      return TRUE;      }
223  }      journ_hook = SetWindowsHookEx (WH_JOURNALPLAYBACK,
224                                       (HOOKPROC)PTD_playback_proc,
225                                       glob_hinst, 0);
226  /* Return version of the PTD library. */      if (journ_hook == NULL)
227  const char *          return FALSE;
228  PTD_get_version (void)      
229  {      while (journ_hook) {
230      return "0.8.1";          if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
231  }              if (msg.message == WM_QUIT) {
232                    if (journ_hook)
233                        UnhookWindowsHookEx (journ_hook);
234  /* Display a JPG picture in the given window at the given point. */                  PostMessage (msg.hwnd, msg.message, msg.wParam, msg.wParam);
235  int              }
236  PTD_jpg_show (HWND hwnd, POINT *p, LPCSTR name)              TranslateMessage (&msg);
237  {              DispatchMessage (&msg);
238      CJPG jpg;          }
239      HDC hdc;      }
240      POINT p2;      
241      BOOL rc;      return TRUE;
242    }
243      rc = jpg.load (name);  
244      if (!rc)  
245          return -1; /* XXX: use real return code. */  /* Display a JPG picture in the given window at the given point. */
246      hdc = GetWindowDC (hwnd);  extern "C" int
247      rc = jpg.updateSizeOnDC (hdc);  PTD_jpg_show (HWND hwnd, POINT *p, LPCSTR name)
248      if (!rc) {  {
249          ReleaseDC (hwnd, hdc);      CJPG jpg;
250          return -2; /* XXX: use real return code. */      HDC hdc;
251      }      POINT p2;
252        BOOL rc;
253      p2.x = jpg.m_Width;  
254      p2.y = jpg.m_Height;      rc = jpg.load (name);
255      rc = jpg.show (hdc, p, &p2, 0, 0);      if (!rc)
256            return -1; /* XXX: use real return code. */
257      ReleaseDC (hwnd, hdc);      hdc = GetWindowDC (hwnd);
258      jpg.freePictureData ();      rc = jpg.updateSizeOnDC (hdc);
259      return rc;      if (!rc) {
260  }          ReleaseDC (hwnd, hdc);
261            return -2; /* XXX: use real return code. */
262        }
263                    
264  BOOL WINAPI      p2.x = jpg.m_Width;
265  DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)      p2.y = jpg.m_Height;
266  {      rc = jpg.show (hdc, p, &p2, 0, 0);
267      switch (reason)  {  
268      case DLL_PROCESS_ATTACH:      ReleaseDC (hwnd, hdc);
269          glob_hinst = hinst;      jpg.freePictureData ();
270          break;      return rc;
271      case DLL_THREAD_ATTACH:    }
272          break;  
273      case DLL_THREAD_DETACH:    
274          break;                  
275      case DLL_PROCESS_DETACH:  extern "C" int WINAPI
276          break;  DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserv)
277      }  {
278      return TRUE;      switch (reason)  {
279  }      case DLL_PROCESS_ATTACH:
280            glob_hinst = hinst;
281            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    

Legend:
Removed from v.33  
changed lines
  Added in v.61

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26