home *** CD-ROM | disk | FTP | other *** search
/ PC Administrator / spravce.iso / TaskModule / src / TaskSwitcherWnd.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-11-06  |  11.2 KB  |  336 lines

  1. // TaskSwitcherWnd.cpp: implementation of the CTaskSwitcherWnd class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4.  
  5. #include "stdafx.h"
  6. #include "TaskSwitcherWnd.h"
  7. #include <shellapi.h>
  8.  
  9. //////////////////////////////////////////////////////////////////////
  10. // Construction/Destruction
  11. //////////////////////////////////////////////////////////////////////
  12.  
  13. CTaskSwitcherWnd::CTaskSwitcherWnd()
  14. {
  15.     m_nMaxTextLength = 40;
  16.     m_nNextID = 0;
  17.     m_vActiveWindows.resize(0);
  18.     m_ptMenuPopup.x = 0;
  19.     m_ptMenuPopup.y = 0;
  20. //    m_nSnapPixels = 5;
  21.     OnDisplayChange();
  22. }
  23.  
  24. CTaskSwitcherWnd::~CTaskSwitcherWnd()
  25. {
  26.     m_vActiveWindows.clear();
  27.     m_vActiveWindows.resize(0);
  28.     if(m_hWnd)
  29.         DestroyWindow(m_hWnd);
  30.     UnregisterClass(m_pWindowClass,m_hInstance);
  31. }
  32.  
  33. LRESULT CTaskSwitcherWnd::WndProc(HWND hWnd,UINT nMessage,WPARAM wParam,LPARAM lParam)
  34. {// begin WndProc
  35.     switch(nMessage)
  36.     {// begin nMessage switch
  37.     case WM_ADDTASK:
  38.         OnAddTask(wParam);
  39.         break;
  40.     case WM_MENUITEMCLICKED:
  41.         OnMenuItemClicked(wParam,lParam);
  42.         break;
  43.     case WM_DESTROY:
  44.         OnDestroy();
  45.         break;
  46.     case WM_MOVE:
  47.         return OnMove();
  48. //    case WM_MOVING:
  49. //        OnMoving(wParam,lParam);
  50. //        break;
  51. //    case WM_LBUTTONDOWN:
  52. //        return PostMessage(m_hWnd,WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(LOWORD(lParam),HIWORD(lParam)));
  53.     }// end nMessage swtich
  54.     return CSnapWnd::WndProc(hWnd, nMessage, wParam, lParam);
  55. }// end WndProc
  56.  
  57. void CTaskSwitcherWnd::OnDestroy()
  58. {// begin OnDestroy
  59.     // save the window position
  60.     RECT rRect = {NULL};
  61.     GetWindowRect(m_hWnd,&rRect);
  62.     POINT pt = {rRect.left,rRect.top};
  63.     CTaskModuleData tmdSettings;
  64.     tmdSettings.SetPos("wnd",pt);
  65.  
  66.     m_hWnd = NULL;
  67.     // exit the program
  68.     PostQuitMessage(0);
  69. }// end OnDestroy
  70.  
  71. LRESULT CTaskSwitcherWnd::OnShowTasks(WPARAM wParam, LPARAM lParam)
  72. {// begin OnShowTasks
  73.     POINT pt = {LOWORD(lParam),HIWORD(lParam)};
  74.     DisplayTasks();
  75.     return 0;
  76. }// end OnShowTasks
  77.  
  78. void CTaskSwitcherWnd::OnMenuItemClicked(WPARAM wParam,LPARAM lParam)
  79. {// begin OnMenuItemClicked
  80.     // get the window handle
  81.     HWND hAssocWnd = (HWND)lParam;
  82.     // if minimized restore
  83.     if(IsIconic(hAssocWnd))
  84.         ShowWindowAsync(hAssocWnd,SW_SHOWNORMAL);
  85.     SetActiveWindow(hAssocWnd);
  86.     SwitchToThisWindow(hAssocWnd,1);
  87. }// end OnMenuItemClicked
  88.  
  89. void CTaskSwitcherWnd::OnAddTask(WPARAM wParam)
  90. {// begin OnAddTask
  91.     HWND hWnd = (HWND)wParam;
  92.     // check if the window is already there
  93.     for(int i = 0;i < m_vActiveWindows.size();i++)
  94.     {
  95.         // skip if already in the list
  96.         if(hWnd == m_vActiveWindows[i])
  97.             return;
  98.     }
  99.     // save corresponding window handle
  100.     m_vActiveWindows.resize(m_vActiveWindows.size()+1);
  101.     m_vActiveWindows[m_vActiveWindows.size()-1] = hWnd;
  102. }// end OnAddTask
  103.  
  104. unsigned long int CTaskSwitcherWnd::Init(HWND hParent,char *pWindowName, unsigned long int dwExStyle,unsigned long int dwStyle, int x, int y,int nWidth, int nHeight, HMENU hMenu, int nCmdShow)
  105. {// begin Init
  106.     unsigned long int nRtnVal = CMyWindow::Init(m_hWnd,pWindowName,dwExStyle,dwStyle,x,y,nWidth,nHeight,hMenu,nCmdShow);
  107.     // create the button
  108.     CreateWindow("BUTTON","Tasks",WS_VISIBLE|WS_CHILD|BS_ICON|BS_OWNERDRAW|BS_CENTER|BS_VCENTER,0,0,nWidth,nHeight,m_hWnd,(HMENU)IDC_BUTTON_TASKS,NULL,NULL);
  109.     SIZE sSize = {16,16};
  110.     m_tbTasks.Create(IDC_BUTTON_TASKS,m_hWnd,m_hInstance,BI_SIZE|BI_CENTERIMAGE,sSize);
  111.     m_tbTasks.SetTextStyles(DT_CENTER|DT_VCENTER|DT_NOCLIP|DT_SINGLELINE);
  112.     m_tbTasks.LoadCtrlImage(IDI_ICON_MAIN);
  113.     // move the windows into position
  114.     LoadWindowPlacement(m_hWnd,"wnd");
  115.     LoadWindowPlacement(m_tbTasks.GetSafeHwnd(),"task-button");
  116.     // load the settings
  117.     CTaskModuleData tmdSettings;
  118.     m_nMaxTextLength = tmdSettings.GetMaxTextLength();
  119.     COLORREF crButtonColor = tmdSettings.GetColor("task-button");
  120.     // load the button color
  121.     if(crButtonColor != 0)
  122.         m_tbTasks.SetColor(crButtonColor);
  123.     // calculate the popup menu position
  124.     CalculateMenuPos();
  125.     // display the window
  126.     ShowWindow(m_hWnd,SW_SHOWNORMAL);
  127.     return nRtnVal;
  128. }// end Init
  129.  
  130. void CTaskSwitcherWnd::DisplayTasks()
  131. {// begin DisplayTasks
  132.     const int ID_OFFSET = 1;
  133.     // free the old menu
  134.     CImageMenu imMenu;
  135.     imMenu.Init(m_hWnd);
  136.     // add all the current windows
  137.     char *pName = NULL;
  138.     for(int j = 0;j < m_vActiveWindows.size();j++)
  139.     {// begin add window
  140.         pName = NULL;
  141.         if(!IsWindow(m_vActiveWindows[j]) || !IsWindowVisible(m_vActiveWindows[j]))
  142.         {// begin remove destroyed windows
  143.             m_vActiveWindows.erase(&m_vActiveWindows[j]);
  144.             j--;
  145.             continue;
  146.         }// end remove destroyed windows
  147.         int nLength = GetWindowTextLength(m_vActiveWindows[j]);
  148.         pName = new char[nLength+1];
  149.         GetWindowText(m_vActiveWindows[j],pName,nLength+1);
  150.         // if the name is longer than 20 character truncate
  151.         if(lstrlen(pName) > m_nMaxTextLength && m_nMaxTextLength > 5)
  152.         {// begin truncate
  153.             pName[m_nMaxTextLength] = '\0';
  154.             pName[m_nMaxTextLength-1] = '.';
  155.             pName[m_nMaxTextLength-2] = '.';
  156.             pName[m_nMaxTextLength-3] = '.';
  157.         }// end truncate
  158.         HICON hIcon =(HICON)SendMessage(m_vActiveWindows[j],WM_GETICON,(WPARAM)ICON_SMALL,0);
  159.         if(!hIcon)
  160.             hIcon = (HICON)GetClassLong(m_vActiveWindows[j],GCL_HICONSM);
  161.         if(!hIcon)    // last resort, get some kind of picture
  162.             hIcon =(HICON)SendMessage(m_vActiveWindows[j],WM_GETICON,(WPARAM)ICON_BIG,0);
  163.  
  164.     HMENU hTempMenu = NULL;
  165. /*        
  166.     // get the window's system menu
  167.     HMENU hSysMenu = GetSystemMenu(m_vActiveWindows[j],FALSE);
  168.     // let application modify menu
  169.     SendMessage( m_vActiveWindows[j], WM_INITMENU, (WPARAM) hSysMenu, 0 );
  170.     SendMessage( m_vActiveWindows[j], WM_INITMENUPOPUP, (WPARAM) hSysMenu, MAKELPARAM( 0, TRUE ) );
  171.     if(hSysMenu)
  172.     {// begin system menu
  173.         SetActiveWindow(m_vActiveWindows[j]);
  174.         hTempMenu = CreatePopupMenu();
  175.         int nItems = GetMenuItemCount(hSysMenu);
  176.         for(int i = 0;i < nItems;i++)
  177.         {// begin copy system menu
  178.             MENUITEMINFO mii = {NULL};
  179.             char pBuffer[MAX_PATH] = {NULL};
  180.             mii.fMask = MIIM_CHECKMARKS|MIIM_DATA|MIIM_ID|MIIM_STATE|MIIM_TYPE|MIIM_SUBMENU;
  181.             mii.dwTypeData = pBuffer;
  182.             mii.cch = MAX_PATH-1;
  183.             mii.cbSize = sizeof(MENUITEMINFO);
  184.             GetMenuItemInfo(hSysMenu,i,true,&mii);    // get by index
  185.             AppendMenu(hTempMenu,NULL,i,"");
  186.              SetMenuItemInfo(hTempMenu,i,true,&mii);
  187.         }// end copy system menu
  188.     }// end system menu
  189.     */
  190.         imMenu.AppendMenu(j+ID_OFFSET,pName,(HICON)DuplicateIcon(m_hInstance,hIcon),MF_POPUP,hTempMenu);
  191. //        imMenu.AppendMenu(j+ID_OFFSET,pName,(HICON)DuplicateIcon(m_hInstance,hIcon));
  192.         if(pName)
  193.             delete []pName;
  194.     }// end add window
  195.     // convert to screen coordinates
  196.     int nMenuSel = imMenu.TrackPopupMenu(TPM_LEFTALIGN|TPM_TOPALIGN|TPM_NONOTIFY|TPM_RETURNCMD,m_ptMenuPopup.x,m_ptMenuPopup.y,m_hWnd)-ID_OFFSET;
  197.     if(nMenuSel > 0-ID_OFFSET && nMenuSel < m_vActiveWindows.size())
  198.         SendMessage(m_hWnd,WM_MENUITEMCLICKED,(WPARAM)0,(LPARAM)m_vActiveWindows[nMenuSel]);
  199.     else if(nMenuSel > 0-ID_OFFSET)
  200.     {// begin send message to owner window
  201.         for(int i = 0;i < imMenu.GetItemCount();i++)
  202.         {// begin find window
  203.             if(imMenu.GetSubMenu(i) == imMenu.GetCurrentMenu())
  204.             {// begin send message
  205.                 SendMessage(m_vActiveWindows[i],WM_SYSCOMMAND,(WPARAM)nMenuSel,(LPARAM)MAKELPARAM(0,0));
  206.                 // bring the window to the front if it isn't minimized
  207.                 if(!IsIconic(m_vActiveWindows[i]))
  208.                     OnMenuItemClicked((WPARAM)0,(LPARAM)m_vActiveWindows[i]);
  209.                 SetActiveWindow(NULL);
  210.                 SetFocus(m_vActiveWindows[i]);
  211.             }// end send message
  212.         }// end find window
  213.     }// end send message to owner window
  214. }// end DisplayTasks
  215. /*
  216. void CTaskSwitcherWnd::OnMenuItemContextMenu(WPARAM wParam,LPARAM lParam)
  217. {// begin OnMenuItemContextMenu
  218.     // get the window handles
  219.     HWND hItemWnd = GetParent((HWND)wParam);
  220.     unsigned long int nID = (unsigned long int)lParam;
  221.     if(!hAssocWnd)
  222.         return;
  223.     POINT pt = {NULL};
  224.     GetCursorPos(&pt);
  225.     // get the window's system menu
  226.     HMENU hSysMenu = GetSystemMenu(hAssocWnd,FALSE);
  227.     // let application modify menu
  228.     SendMessage( hAssocWnd, WM_INITMENU, (WPARAM) hSysMenu, 0 );
  229.     SendMessage( hAssocWnd, WM_INITMENUPOPUP, (WPARAM) hSysMenu, MAKELPARAM( 0, TRUE ) );
  230.  
  231.     // display it
  232.     int nMenuSel = 0;
  233.     if(hSysMenu)
  234.     {// begin create our radial menu
  235.         SetActiveWindow(hAssocWnd);
  236.         HMENU hTempMenu = CreatePopupMenu();
  237.         int nItems = GetMenuItemCount(hSysMenu);
  238.         for(int i = 0;i < nItems;i++)
  239.         {
  240.             MENUITEMINFO mii = {NULL};
  241.             char pBuffer[MAX_PATH] = {NULL};
  242.             mii.fMask = MIIM_CHECKMARKS|MIIM_DATA|MIIM_ID|MIIM_STATE|MIIM_TYPE|MIIM_SUBMENU;
  243.             mii.dwTypeData = pBuffer;
  244.             mii.cch = MAX_PATH-1;
  245.             mii.cbSize = sizeof(MENUITEMINFO);
  246.             GetMenuItemInfo(hSysMenu,i,true,&mii);    // get by index
  247.             AppendMenu(hTempMenu,NULL,i,"");
  248.              SetMenuItemInfo(hTempMenu,i,true,&mii);
  249.         }
  250.         nMenuSel = TrackPopupMenu(hTempMenu,TPM_RIGHTALIGN|TPM_TOPALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD|TPM_NONOTIFY,pt.x,pt.y,0,hItemWnd,NULL);
  251.         DestroyMenu(hTempMenu);
  252. //        nMenuSel = TrackPopupMenu(hSysMenu,TPM_RIGHTALIGN|TPM_TOPALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD|TPM_NONOTIFY,pt.x,pt.y,0,hItemWnd,NULL);
  253.  
  254.         // send this command to the main window
  255.         if(nMenuSel)
  256.         {// begin item selected
  257.             SendMessage(hAssocWnd,WM_SYSCOMMAND,(WPARAM)nMenuSel,(LPARAM)MAKELPARAM(pt.x,pt.y));
  258.             // bring the window to the front if it isn't minimized
  259.             if(!IsIconic(hAssocWnd))
  260.                 OnMenuItemClicked(wParam,lParam);
  261.             SetActiveWindow(NULL);
  262.             SetFocus((HWND)wParam);
  263.         }// end item selected
  264.     }// end create our radial menu
  265. }// end OnMenuItemContextMenu
  266. */
  267. void CTaskSwitcherWnd::DisplayLastError(void)
  268. {// begin DisplayLastError
  269.     LPVOID lpMsgBuf = NULL;
  270.     FormatMessage( 
  271.         FORMAT_MESSAGE_ALLOCATE_BUFFER | 
  272.         FORMAT_MESSAGE_FROM_SYSTEM | 
  273.         FORMAT_MESSAGE_IGNORE_INSERTS,
  274.         NULL,
  275.         GetLastError(),
  276.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  277.         (LPTSTR) &lpMsgBuf,
  278.         0,
  279.         NULL 
  280.     );
  281.     // Display the string.
  282.     MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
  283.     // Free the buffer.
  284.     LocalFree( lpMsgBuf );
  285. }// end DisplayLastError
  286.  
  287. unsigned long int CTaskSwitcherWnd::OnCommand(WPARAM wParam, LPARAM lParam)
  288. {// begin OnCommand
  289.     int nID = LOWORD(wParam);
  290.     switch(nID)
  291.     {// begin wParam switch
  292.     case IDC_BUTTON_TASKS:
  293.         OnButtonTasks();
  294.         break;
  295.     }// end wParam switch
  296.     return CMyWindow::OnCommand(wParam,lParam);
  297. }// end OnCommand
  298.  
  299. void CTaskSwitcherWnd::OnButtonTasks(void)
  300. {// begin OnButtonTasks
  301.     POINT pt = {NULL};
  302.     GetCursorPos(&pt);
  303.     OnShowTasks(0,MAKELPARAM(pt.x,pt.y));
  304. }// end OnButtonTasks
  305.  
  306. void CTaskSwitcherWnd::LoadWindowPlacement(HWND hWnd,const char *pName)
  307. {// begin LoadWindowPlacement
  308.     // command combo
  309.     unsigned long int nFlags = SWP_NOOWNERZORDER;
  310.     CTaskModuleData tmdSettings;
  311.     POINT ptPos = tmdSettings.GetPos(pName);
  312.     SIZE szSize = tmdSettings.GetSize(pName);
  313.     // ignore the size if it is less than 1
  314.     if(szSize.cx < 1 || szSize.cy < 1)
  315.         nFlags |= SWP_NOSIZE;
  316.     // ignore the position if it is less than 0
  317.     if(ptPos.x < 0 || ptPos.y < 0)
  318.         nFlags |= SWP_NOMOVE;
  319.     SetWindowPos(hWnd,NULL,ptPos.x,ptPos.y,szSize.cx,szSize.cy,nFlags);
  320. }// end LoadWindowPlacement
  321.  
  322. LRESULT CTaskSwitcherWnd::OnMove(void)
  323. {// begin OnMove
  324.     CalculateMenuPos();
  325.     return 0;
  326. }// end OnMove
  327.  
  328. void CTaskSwitcherWnd::CalculateMenuPos(void)
  329. {// begin CalculateMenuPos
  330.     RECT rWndRect = {NULL};
  331.     GetWindowRect(m_hWnd,&rWndRect);
  332.     m_ptMenuPopup.x = rWndRect.left;
  333.     m_ptMenuPopup.y = rWndRect.bottom;
  334. }// end CalculateMenuPos
  335.  
  336.