home *** CD-ROM | disk | FTP | other *** search
Wrap
// TaskSwitcherWnd.cpp: implementation of the CTaskSwitcherWnd class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "TaskSwitcherWnd.h" #include <shellapi.h> ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CTaskSwitcherWnd::CTaskSwitcherWnd() { m_nMaxTextLength = 40; m_nNextID = 0; m_vActiveWindows.resize(0); m_ptMenuPopup.x = 0; m_ptMenuPopup.y = 0; // m_nSnapPixels = 5; OnDisplayChange(); } CTaskSwitcherWnd::~CTaskSwitcherWnd() { m_vActiveWindows.clear(); m_vActiveWindows.resize(0); if(m_hWnd) DestroyWindow(m_hWnd); UnregisterClass(m_pWindowClass,m_hInstance); } LRESULT CTaskSwitcherWnd::WndProc(HWND hWnd,UINT nMessage,WPARAM wParam,LPARAM lParam) {// begin WndProc switch(nMessage) {// begin nMessage switch case WM_ADDTASK: OnAddTask(wParam); break; case WM_MENUITEMCLICKED: OnMenuItemClicked(wParam,lParam); break; case WM_DESTROY: OnDestroy(); break; case WM_MOVE: return OnMove(); // case WM_MOVING: // OnMoving(wParam,lParam); // break; // case WM_LBUTTONDOWN: // return PostMessage(m_hWnd,WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(LOWORD(lParam),HIWORD(lParam))); }// end nMessage swtich return CSnapWnd::WndProc(hWnd, nMessage, wParam, lParam); }// end WndProc void CTaskSwitcherWnd::OnDestroy() {// begin OnDestroy // save the window position RECT rRect = {NULL}; GetWindowRect(m_hWnd,&rRect); POINT pt = {rRect.left,rRect.top}; CTaskModuleData tmdSettings; tmdSettings.SetPos("wnd",pt); m_hWnd = NULL; // exit the program PostQuitMessage(0); }// end OnDestroy LRESULT CTaskSwitcherWnd::OnShowTasks(WPARAM wParam, LPARAM lParam) {// begin OnShowTasks POINT pt = {LOWORD(lParam),HIWORD(lParam)}; DisplayTasks(); return 0; }// end OnShowTasks void CTaskSwitcherWnd::OnMenuItemClicked(WPARAM wParam,LPARAM lParam) {// begin OnMenuItemClicked // get the window handle HWND hAssocWnd = (HWND)lParam; // if minimized restore if(IsIconic(hAssocWnd)) ShowWindowAsync(hAssocWnd,SW_SHOWNORMAL); SetActiveWindow(hAssocWnd); SwitchToThisWindow(hAssocWnd,1); }// end OnMenuItemClicked void CTaskSwitcherWnd::OnAddTask(WPARAM wParam) {// begin OnAddTask HWND hWnd = (HWND)wParam; // check if the window is already there for(int i = 0;i < m_vActiveWindows.size();i++) { // skip if already in the list if(hWnd == m_vActiveWindows[i]) return; } // save corresponding window handle m_vActiveWindows.resize(m_vActiveWindows.size()+1); m_vActiveWindows[m_vActiveWindows.size()-1] = hWnd; }// end OnAddTask 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) {// begin Init unsigned long int nRtnVal = CMyWindow::Init(m_hWnd,pWindowName,dwExStyle,dwStyle,x,y,nWidth,nHeight,hMenu,nCmdShow); // create the button 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); SIZE sSize = {16,16}; m_tbTasks.Create(IDC_BUTTON_TASKS,m_hWnd,m_hInstance,BI_SIZE|BI_CENTERIMAGE,sSize); m_tbTasks.SetTextStyles(DT_CENTER|DT_VCENTER|DT_NOCLIP|DT_SINGLELINE); m_tbTasks.LoadCtrlImage(IDI_ICON_MAIN); // move the windows into position LoadWindowPlacement(m_hWnd,"wnd"); LoadWindowPlacement(m_tbTasks.GetSafeHwnd(),"task-button"); // load the settings CTaskModuleData tmdSettings; m_nMaxTextLength = tmdSettings.GetMaxTextLength(); COLORREF crButtonColor = tmdSettings.GetColor("task-button"); // load the button color if(crButtonColor != 0) m_tbTasks.SetColor(crButtonColor); // calculate the popup menu position CalculateMenuPos(); // display the window ShowWindow(m_hWnd,SW_SHOWNORMAL); return nRtnVal; }// end Init void CTaskSwitcherWnd::DisplayTasks() {// begin DisplayTasks const int ID_OFFSET = 1; // free the old menu CImageMenu imMenu; imMenu.Init(m_hWnd); // add all the current windows char *pName = NULL; for(int j = 0;j < m_vActiveWindows.size();j++) {// begin add window pName = NULL; if(!IsWindow(m_vActiveWindows[j]) || !IsWindowVisible(m_vActiveWindows[j])) {// begin remove destroyed windows m_vActiveWindows.erase(&m_vActiveWindows[j]); j--; continue; }// end remove destroyed windows int nLength = GetWindowTextLength(m_vActiveWindows[j]); pName = new char[nLength+1]; GetWindowText(m_vActiveWindows[j],pName,nLength+1); // if the name is longer than 20 character truncate if(lstrlen(pName) > m_nMaxTextLength && m_nMaxTextLength > 5) {// begin truncate pName[m_nMaxTextLength] = '\0'; pName[m_nMaxTextLength-1] = '.'; pName[m_nMaxTextLength-2] = '.'; pName[m_nMaxTextLength-3] = '.'; }// end truncate HICON hIcon =(HICON)SendMessage(m_vActiveWindows[j],WM_GETICON,(WPARAM)ICON_SMALL,0); if(!hIcon) hIcon = (HICON)GetClassLong(m_vActiveWindows[j],GCL_HICONSM); if(!hIcon) // last resort, get some kind of picture hIcon =(HICON)SendMessage(m_vActiveWindows[j],WM_GETICON,(WPARAM)ICON_BIG,0); HMENU hTempMenu = NULL; /* // get the window's system menu HMENU hSysMenu = GetSystemMenu(m_vActiveWindows[j],FALSE); // let application modify menu SendMessage( m_vActiveWindows[j], WM_INITMENU, (WPARAM) hSysMenu, 0 ); SendMessage( m_vActiveWindows[j], WM_INITMENUPOPUP, (WPARAM) hSysMenu, MAKELPARAM( 0, TRUE ) ); if(hSysMenu) {// begin system menu SetActiveWindow(m_vActiveWindows[j]); hTempMenu = CreatePopupMenu(); int nItems = GetMenuItemCount(hSysMenu); for(int i = 0;i < nItems;i++) {// begin copy system menu MENUITEMINFO mii = {NULL}; char pBuffer[MAX_PATH] = {NULL}; mii.fMask = MIIM_CHECKMARKS|MIIM_DATA|MIIM_ID|MIIM_STATE|MIIM_TYPE|MIIM_SUBMENU; mii.dwTypeData = pBuffer; mii.cch = MAX_PATH-1; mii.cbSize = sizeof(MENUITEMINFO); GetMenuItemInfo(hSysMenu,i,true,&mii); // get by index AppendMenu(hTempMenu,NULL,i,""); SetMenuItemInfo(hTempMenu,i,true,&mii); }// end copy system menu }// end system menu */ imMenu.AppendMenu(j+ID_OFFSET,pName,(HICON)DuplicateIcon(m_hInstance,hIcon),MF_POPUP,hTempMenu); // imMenu.AppendMenu(j+ID_OFFSET,pName,(HICON)DuplicateIcon(m_hInstance,hIcon)); if(pName) delete []pName; }// end add window // convert to screen coordinates int nMenuSel = imMenu.TrackPopupMenu(TPM_LEFTALIGN|TPM_TOPALIGN|TPM_NONOTIFY|TPM_RETURNCMD,m_ptMenuPopup.x,m_ptMenuPopup.y,m_hWnd)-ID_OFFSET; if(nMenuSel > 0-ID_OFFSET && nMenuSel < m_vActiveWindows.size()) SendMessage(m_hWnd,WM_MENUITEMCLICKED,(WPARAM)0,(LPARAM)m_vActiveWindows[nMenuSel]); else if(nMenuSel > 0-ID_OFFSET) {// begin send message to owner window for(int i = 0;i < imMenu.GetItemCount();i++) {// begin find window if(imMenu.GetSubMenu(i) == imMenu.GetCurrentMenu()) {// begin send message SendMessage(m_vActiveWindows[i],WM_SYSCOMMAND,(WPARAM)nMenuSel,(LPARAM)MAKELPARAM(0,0)); // bring the window to the front if it isn't minimized if(!IsIconic(m_vActiveWindows[i])) OnMenuItemClicked((WPARAM)0,(LPARAM)m_vActiveWindows[i]); SetActiveWindow(NULL); SetFocus(m_vActiveWindows[i]); }// end send message }// end find window }// end send message to owner window }// end DisplayTasks /* void CTaskSwitcherWnd::OnMenuItemContextMenu(WPARAM wParam,LPARAM lParam) {// begin OnMenuItemContextMenu // get the window handles HWND hItemWnd = GetParent((HWND)wParam); unsigned long int nID = (unsigned long int)lParam; if(!hAssocWnd) return; POINT pt = {NULL}; GetCursorPos(&pt); // get the window's system menu HMENU hSysMenu = GetSystemMenu(hAssocWnd,FALSE); // let application modify menu SendMessage( hAssocWnd, WM_INITMENU, (WPARAM) hSysMenu, 0 ); SendMessage( hAssocWnd, WM_INITMENUPOPUP, (WPARAM) hSysMenu, MAKELPARAM( 0, TRUE ) ); // display it int nMenuSel = 0; if(hSysMenu) {// begin create our radial menu SetActiveWindow(hAssocWnd); HMENU hTempMenu = CreatePopupMenu(); int nItems = GetMenuItemCount(hSysMenu); for(int i = 0;i < nItems;i++) { MENUITEMINFO mii = {NULL}; char pBuffer[MAX_PATH] = {NULL}; mii.fMask = MIIM_CHECKMARKS|MIIM_DATA|MIIM_ID|MIIM_STATE|MIIM_TYPE|MIIM_SUBMENU; mii.dwTypeData = pBuffer; mii.cch = MAX_PATH-1; mii.cbSize = sizeof(MENUITEMINFO); GetMenuItemInfo(hSysMenu,i,true,&mii); // get by index AppendMenu(hTempMenu,NULL,i,""); SetMenuItemInfo(hTempMenu,i,true,&mii); } nMenuSel = TrackPopupMenu(hTempMenu,TPM_RIGHTALIGN|TPM_TOPALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD|TPM_NONOTIFY,pt.x,pt.y,0,hItemWnd,NULL); DestroyMenu(hTempMenu); // nMenuSel = TrackPopupMenu(hSysMenu,TPM_RIGHTALIGN|TPM_TOPALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD|TPM_NONOTIFY,pt.x,pt.y,0,hItemWnd,NULL); // send this command to the main window if(nMenuSel) {// begin item selected SendMessage(hAssocWnd,WM_SYSCOMMAND,(WPARAM)nMenuSel,(LPARAM)MAKELPARAM(pt.x,pt.y)); // bring the window to the front if it isn't minimized if(!IsIconic(hAssocWnd)) OnMenuItemClicked(wParam,lParam); SetActiveWindow(NULL); SetFocus((HWND)wParam); }// end item selected }// end create our radial menu }// end OnMenuItemContextMenu */ void CTaskSwitcherWnd::DisplayLastError(void) {// begin DisplayLastError LPVOID lpMsgBuf = NULL; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the string. MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION ); // Free the buffer. LocalFree( lpMsgBuf ); }// end DisplayLastError unsigned long int CTaskSwitcherWnd::OnCommand(WPARAM wParam, LPARAM lParam) {// begin OnCommand int nID = LOWORD(wParam); switch(nID) {// begin wParam switch case IDC_BUTTON_TASKS: OnButtonTasks(); break; }// end wParam switch return CMyWindow::OnCommand(wParam,lParam); }// end OnCommand void CTaskSwitcherWnd::OnButtonTasks(void) {// begin OnButtonTasks POINT pt = {NULL}; GetCursorPos(&pt); OnShowTasks(0,MAKELPARAM(pt.x,pt.y)); }// end OnButtonTasks void CTaskSwitcherWnd::LoadWindowPlacement(HWND hWnd,const char *pName) {// begin LoadWindowPlacement // command combo unsigned long int nFlags = SWP_NOOWNERZORDER; CTaskModuleData tmdSettings; POINT ptPos = tmdSettings.GetPos(pName); SIZE szSize = tmdSettings.GetSize(pName); // ignore the size if it is less than 1 if(szSize.cx < 1 || szSize.cy < 1) nFlags |= SWP_NOSIZE; // ignore the position if it is less than 0 if(ptPos.x < 0 || ptPos.y < 0) nFlags |= SWP_NOMOVE; SetWindowPos(hWnd,NULL,ptPos.x,ptPos.y,szSize.cx,szSize.cy,nFlags); }// end LoadWindowPlacement LRESULT CTaskSwitcherWnd::OnMove(void) {// begin OnMove CalculateMenuPos(); return 0; }// end OnMove void CTaskSwitcherWnd::CalculateMenuPos(void) {// begin CalculateMenuPos RECT rWndRect = {NULL}; GetWindowRect(m_hWnd,&rWndRect); m_ptMenuPopup.x = rWndRect.left; m_ptMenuPopup.y = rWndRect.bottom; }// end CalculateMenuPos