home *** CD-ROM | disk | FTP | other *** search
/ PC World 2003 May / PCWorld_2003-05_cd.bin / Software / Vyzkuste / rbtray / rbtray.c < prev    next >
C/C++ Source or Header  |  2000-04-20  |  10KB  |  398 lines

  1. #include <windows.h>
  2. #include "rbtray.h"
  3.  
  4. #define MAXCOUNT 64
  5. #define MAXTEXT  64
  6.  
  7.  typedef BOOL (*RegHook)(HMODULE hLib);
  8.  typedef void (*UnRegHook)(void);
  9.  
  10. static HWND hwndHook;
  11. static HINSTANCE thisInstance;
  12. static HWND list[MAXCOUNT];
  13. static HWND CurrentWindow;
  14. static HMODULE hLib;
  15.  
  16. #ifdef DBG
  17. #define D(X,Y) dbg(X,LOWORD((DWORD)(Y)))
  18. #define WS_WINDOW_STYLE (WS_OVERLAPPEDWINDOW | WS_VISIBLE)
  19. #define MAX_MSG 250
  20. LPSTR text[MAX_MSG];
  21. WORD value[MAX_MSG];
  22. static int count=0;
  23. void
  24. OutText()
  25. {
  26.     char txt[60];
  27.     HDC hdc;
  28.     PAINTSTRUCT ps ;
  29.     int i;
  30.     hdc=BeginPaint(hwndHook,&ps);
  31.     SetTextAlign(hdc,TA_LEFT | TA_TOP | TA_NOUPDATECP);
  32.     for(i=0;i<count;i++)
  33.     {
  34.         wsprintf(txt,"%20s %08lX",text[i],value[i]);
  35.         TextOut(hdc,1,15*(i+1),txt,strlen(txt));
  36.     };
  37.     EndPaint(hwndHook,&ps) ;
  38. };
  39. void
  40. dbg(LPSTR str,WORD num)
  41. {
  42.     PostMessage(FindWindow(NAME,NAME),WM_DBG,(WPARAM)num,(LPARAM)str);
  43.     ShowWindow(FindWindow(NAME,NAME),SW_SHOWMAXIMIZED);
  44.     PostMessage(FindWindow(NAME,NAME),WM_PAINT,0,0);
  45. };
  46. #else
  47. #define D(X,Y)
  48. #define WS_WINDOW_STYLE WS_OVERLAPPED
  49. #endif
  50.  
  51. void
  52. TrayPrg(LPSTR Cmd)
  53. {
  54.     STARTUPINFO si;
  55.     PROCESS_INFORMATION pi;
  56.     D(Cmd,0);
  57.     si.cb=sizeof(STARTUPINFO);
  58.     si.lpReserved=NULL;
  59.     si.lpDesktop=NULL;
  60.     si.lpTitle=NULL;
  61.     si.dwFlags=STARTF_USESHOWWINDOW;
  62.     si.wShowWindow=SW_SHOWMINNOACTIVE;
  63.     si.cbReserved2=0;
  64.     si.lpReserved2=NULL;
  65. //    if(CreateProcess(NULL,Cmd,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi))
  66. //       SetProcessId(pi.dwThreadId);
  67. //    D("Thread created",pi.dwThreadId);
  68. }
  69.  
  70. BOOL CALLBACK
  71. UpdMenu(HWND  hwnd,LPARAM lParam)
  72. {
  73.     int i;
  74.     BOOL flag=lParam;
  75.     HMENU hSysMenu=GetSystemMenu(hwnd, FALSE);
  76.     for(i=0;i<GetMenuItemCount(hSysMenu) && hSysMenu;i++)
  77.         if(GetMenuItemID(hSysMenu,i)==IDM_TRAY) flag=FALSE;
  78.     if (hSysMenu && lParam && flag)
  79.     {
  80.         InsertMenu (hSysMenu, GetMenuItemID(hSysMenu,0),MF_STRING,IDM_TRAY,"Minimize in tray");
  81.         InsertMenu (hSysMenu, GetMenuItemID(hSysMenu,1),MF_SEPARATOR,IDM_TRAY+1, NULL) ;
  82.     }
  83.     if (hSysMenu && lParam==FALSE && flag==FALSE)
  84.     {
  85.         DeleteMenu (hSysMenu,IDM_TRAY,MF_BYCOMMAND);    
  86.         DeleteMenu (hSysMenu,IDM_TRAY+1,MF_BYCOMMAND);    
  87.     }
  88.     return TRUE;
  89. }
  90.  
  91. int
  92. FindInTray(HWND hwnd)
  93. {
  94.   int i;
  95.   for (i = MAXCOUNT - 1; i >= 0; i--)
  96.     if (list[i] == hwnd) break;
  97.   return i;
  98. }
  99.  
  100. static void
  101. DelFromTray(int i)
  102. {
  103.   NOTIFYICONDATA nid;
  104.  
  105.   if (i < 0)
  106.     return;
  107.   nid.cbSize = sizeof(NOTIFYICONDATA);
  108.   nid.hWnd   = hwndHook;
  109.   nid.uID    = (UINT)list[i];
  110.   list[i] = 0;
  111.   Shell_NotifyIcon(NIM_DELETE, &nid);
  112. }
  113.  
  114. static void
  115. ShowIt(HWND hwnd)
  116. {
  117.   ShowWindow(hwnd, SW_SHOW);
  118.   ShowWindow(hwnd, SW_RESTORE);
  119.   SetForegroundWindow(hwnd);
  120. }
  121.  
  122. static void
  123. ShowTheWindow(HWND hwnd)
  124. {
  125.   if ((GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD))
  126.   {
  127.     HWND parent = hwnd;
  128.     do
  129.       parent = GetParent(parent);
  130.       while (parent && FindInTray(parent) < 0);
  131.     if (parent)
  132.       ShowTheWindow(parent);
  133.   }
  134.   ShowIt(hwnd);
  135.   DelFromTray(FindInTray(hwnd));
  136.   D("Restored",hwnd);
  137.  
  138. }
  139.  
  140. static void
  141. CloseTheWindow(HWND hwnd)
  142. {
  143.   SetForegroundWindow(hwnd);
  144.   SendMessage(hwnd, WM_CLOSE, 0, 0);
  145.   if (!IsWindow(hwnd)) DelFromTray(FindInTray(hwnd));
  146.  
  147. }
  148. HICON
  149. GetWindowIcon(HWND hwnd)
  150. {
  151.   HICON icon;
  152.   if (icon = (HICON)SendMessage(hwnd, WM_GETICON, ICON_SMALL, 0))
  153.     return icon;
  154.   if (icon = (HICON)SendMessage(hwnd, WM_GETICON, ICON_BIG, 0))
  155.     return icon;
  156.   if (icon = (HICON)GetClassLong(hwnd, GCL_HICONSM))
  157.     return icon;
  158.   if (icon = (HICON)GetClassLong(hwnd, GCL_HICON))
  159.     return icon;
  160.   return LoadIcon(NULL, IDI_WINLOGO);
  161. }
  162.  
  163. void
  164. ExecuteMenu()
  165. {
  166.     HMENU hMenu;
  167.     POINT point;
  168.  
  169.     hMenu=CreatePopupMenu();
  170.     if(!hMenu)
  171.     {
  172.         MessageBox(NULL, "Error crerating menu", "RBTray",MB_OK);
  173.         return;
  174.     };
  175.     AppendMenu(hMenu,MF_STRING,IDM_ABOUT,   "About RBTray\0");
  176.     AppendMenu(hMenu,MF_SEPARATOR,0,NULL);//------------------
  177.     AppendMenu(hMenu,MF_STRING,IDM_RESTORE, "Restore window\0");
  178.     AppendMenu(hMenu,MF_STRING,IDM_CLOSE,   "Close window\0");
  179.     AppendMenu(hMenu,MF_STRING,IDM_DESTROY, "Kill window\0");
  180.     AppendMenu(hMenu,MF_SEPARATOR,0,NULL);//------------------
  181.     AppendMenu(hMenu,MF_STRING,IDM_EXIT,    "Exit RBTray\0");
  182.  
  183.     GetCursorPos (&point);
  184.     SetForegroundWindow (hwndHook);
  185.  
  186.     TrackPopupMenu (hMenu, TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RIGHTALIGN | TPM_BOTTOMALIGN,
  187.                     point.x, GetSystemMetrics(SM_CYSCREEN), 0, hwndHook, NULL);
  188.  
  189.     PostMessage (hwndHook, WM_USER, 0, 0);
  190.     DestroyMenu(hMenu);
  191. }
  192.  
  193. BOOL CALLBACK
  194. AboutDlgProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam )
  195. {
  196.     switch( Msg )
  197.     {
  198.         case WM_INITDIALOG:
  199.             SetDlgItemText(hWnd,IDC_EDIT,"nike@zmail.ru");
  200.         break;
  201.  
  202.         case WM_CLOSE:
  203.             PostMessage( hWnd, WM_COMMAND, IDCANCEL, 0l );
  204.         break;
  205.  
  206.         case WM_COMMAND:
  207.             switch( LOWORD(wParam) )
  208.             {
  209.                 case IDOK:
  210.                     EndDialog( hWnd, TRUE );
  211.                 break;
  212.  
  213.                 case IDCANCEL:
  214.                     EndDialog( hWnd, FALSE );
  215.                 break;
  216.  
  217.             }
  218.         break;
  219.         default:
  220.             return FALSE;
  221.     }
  222.     return TRUE;
  223. }
  224.  
  225. void
  226. DestroyTheWindow(HWND hwnd)
  227. {
  228.     DWORD pID;
  229.     HANDLE hProc;
  230.  
  231.     GetWindowThreadProcessId(hwnd,&pID);
  232.     hProc=OpenProcess(PROCESS_ALL_ACCESS,TRUE,pID);
  233.     if(TerminateProcess(hProc,1)) DelFromTray(FindInTray(hwnd));
  234. }
  235.  
  236. LRESULT CALLBACK
  237. HookWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  238. {
  239.     NOTIFYICONDATA nid;
  240.     int i;
  241.   DWORD ProcessId;
  242.   switch (msg) {
  243.     case WM_COMMAND:
  244.         switch (LOWORD(wParam))
  245.         {
  246.            case IDM_RESTORE:
  247.               ShowTheWindow(CurrentWindow);
  248.               break;
  249.            case IDM_EXIT:
  250.                SendMessage(hwndHook,WM_DESTROY,0,0);
  251.                break;
  252.            case IDM_CLOSE:
  253.                CloseTheWindow(CurrentWindow);
  254.                break;
  255.            case IDM_ABOUT:
  256.                DialogBox(thisInstance, MAKEINTRESOURCE(IDD_DIALOG1), hwndHook, (DLGPROC)AboutDlgProc );
  257.                break;
  258.            case IDM_DESTROY:
  259.                if(MessageBox(NULL,"Kill the window?","RBTray",MB_YESNO | MB_ICONWARNING )==IDYES)DestroyTheWindow(CurrentWindow);
  260.                break;
  261.         };
  262.         break;
  263.     case WM_MYCMD:
  264.       for(i=MAXCOUNT-1;i>=0;i--)
  265.         if(!list[i])break;
  266.       if (i < 0)break;
  267.       list[i]=(HWND)lParam;
  268.       nid.cbSize           = sizeof(NOTIFYICONDATA);
  269.       nid.hWnd             = hwndHook;
  270.       nid.uID              = (UINT)lParam;
  271.       nid.uFlags           = NIF_MESSAGE | NIF_ICON | NIF_TIP;
  272.       nid.uCallbackMessage = WM_TRAYCMD;
  273.       nid.hIcon            = GetWindowIcon((HWND)lParam);
  274.       ShowWindow((HWND)lParam, SW_HIDE);
  275.       ShowWindow((HWND)lParam, SW_MINIMIZE);
  276.       GetWindowText((HWND)lParam, nid.szTip, MAXTEXT);
  277.       Shell_NotifyIcon(NIM_ADD, &nid);
  278.       ShowWindow((HWND)lParam, SW_HIDE);
  279.       D("Trayed",(HWND)lParam);
  280.       break;
  281.     case WM_DELTRAY:
  282.       CloseTheWindow((HWND)wParam);
  283.       D("Closed",(HWND)lParam);
  284.       break;
  285.     case WM_TRAYCMD:
  286.       switch ((UINT)lParam) {
  287.         case WM_LBUTTONDOWN:
  288.           ShowTheWindow((HWND)wParam);
  289.           break;
  290.         case WM_RBUTTONDOWN:
  291.             CurrentWindow=(HWND)wParam;
  292.             ExecuteMenu();
  293.           break;
  294.         case WM_MOUSEMOVE:
  295.           if (!IsWindow((HWND)wParam))
  296.             DelFromTray(FindInTray((HWND)wParam));
  297.           else {
  298.             nid.uID              = (UINT)wParam;
  299.             nid.uFlags           = NIF_ICON | NIF_TIP;
  300.             nid.hIcon            = GetWindowIcon((HWND)wParam);
  301.             GetWindowText((HWND)wParam, nid.szTip, MAXTEXT);
  302.             Shell_NotifyIcon(NIM_MODIFY, &nid);
  303.             }
  304.         }
  305.         break;
  306.     case WM_DESTROY:
  307.       for (i = MAXCOUNT - 1; i >= 0; i--)
  308.         if (list[i])
  309.         {
  310.           ShowIt(list[i]);
  311.           DelFromTray(i);
  312.         }
  313.       UnRegisterHook();
  314.       FreeLibrary(hLib);
  315.       EnumWindows((WNDENUMPROC)UpdMenu,FALSE);
  316.       PostQuitMessage(0);
  317.       break;
  318.     #ifdef DBG
  319.     case WM_DBG:
  320.         if(count<MAX_MSG)
  321.         {
  322.             text[count]=(LPSTR)lParam;
  323.             value[count++]=(WORD)wParam;
  324.             OutText();
  325.         };
  326.         break;
  327.     case WM_PAINT:
  328.       OutText();
  329.       break;
  330.     #endif
  331.     }
  332.   return DefWindowProc(hwnd, msg, wParam, lParam);
  333. }
  334.  
  335. int WINAPI
  336. WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR szCmdLine, int iCmdShow)
  337. {
  338.     WNDCLASS wc;
  339.     MSG msg;
  340.  
  341.     thisInstance = hInstance;
  342.     hwndHook = FindWindow(NAME, NAME);
  343.     if (hwndHook)
  344.     {
  345.         if(strstr(szCmdLine,"--exit"))
  346.             SendMessage(hwndHook, WM_CLOSE, 0, 0);
  347.         else
  348.             if(strlen(szCmdLine)!=0)
  349.                 TrayPrg(szCmdLine);
  350.         return 0;
  351.     };
  352.     if (!(hLib = LoadLibrary("RBHook.dll")))
  353.     {
  354.         MessageBox(NULL, "Error loading RBHook.dll", "RBTray", MB_OK
  355.             | MB_ICONHAND);
  356.         return FALSE;
  357.     }
  358.     if (!RegisterHook(hLib))
  359.     {
  360.         MessageBox(NULL, "Error setting hook procedure", "RBTray", MB_OK | MB_ICONHAND);
  361.         return FALSE;
  362.     }
  363.     wc.hCursor        = NULL;
  364.     wc.hIcon          = NULL;
  365.     wc.lpszMenuName   = NULL;
  366.     wc.lpszClassName  = NAME;
  367.     wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  368.     wc.hInstance      = hInstance;
  369.     wc.style          = 0;
  370.     wc.lpfnWndProc    = HookWndProc;
  371.     wc.cbWndExtra     = sizeof(HWND) + sizeof(HWND);
  372.     wc.cbClsExtra     = 0;
  373.     if (!RegisterClass(&wc))
  374.     {
  375.         MessageBox(NULL,"Error creating window class", "RBTray", MB_OK | MB_ICONHAND);
  376.         return 2;
  377.     }
  378.     if (!(hwndHook = CreateWindow(NAME, NAME,
  379.             WS_WINDOW_STYLE,
  380.             0, 0, 0, 0,
  381.             (HWND) NULL,
  382.             (HMENU) NULL,
  383.             (HINSTANCE)hInstance,
  384.             (LPVOID) NULL)))
  385.     {
  386.         MessageBox(NULL, "Error creating window", "RBTray", MB_OK);
  387.         return 3;
  388.     }
  389.     EnumWindows((WNDENUMPROC)UpdMenu,TRUE);
  390.     if(strlen(szCmdLine))TrayPrg(szCmdLine);
  391.     while (IsWindow(hwndHook) && GetMessage(&msg, hwndHook, 0, 0))
  392.     {
  393.         TranslateMessage(&msg);
  394.         DispatchMessage(&msg);
  395.     }
  396.     return 0;
  397. }
  398.