void CSystemTray::MaximiseFromTray(HWND hWnd) { #ifndef _WIN32_WCE if (GetDoWndAnimation()) { RECT rectTo; ::GetWindowRect(hWnd, &rectTo); RECT rectFrom; GetTrayWndRect(&rectFrom); ::SetParent(hWnd, NULL); DrawAnimatedRects(hWnd, IDANI_CAPTION, &rectFrom, &rectTo); } else ::SetParent(hWnd, NULL); SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) | WS_VISIBLE); RedrawWindow(hWnd, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME | RDW_INVALIDATE | RDW_ERASE); // Move focus away and back again to ensure taskbar icon is recreated if (::IsWindow(m_hWndInvisible)) SetActiveWindow(m_hWndInvisible); SetActiveWindow(hWnd); SetForegroundWindow(hWnd); #endif }
void AnimateToTray(HWND hWnd) { HWND hCaptionWindow; RECT rcFrom, rcTo; TCHAR windowText[512]; WNDCLASSEX wcex; HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); int xInc, yInc, captionWidth; if(GetDoAnimateMinimize()) { // Get the rect of the tray and the window. Note that the window rect // is still valid even though the window is hidden GetTrayWndRect(&rcTo); GetWindowRect(hWnd,&rcFrom); GetWindowText(hWnd, windowText, sizeof(windowText)); wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = CaptionWndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = (HICON)SendMessage(hWnd, WM_GETICON, ICON_BIG, 0); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW); wcex.lpszMenuName = NULL; wcex.lpszClassName = L"Caption Window"; wcex.hIconSm = (HICON)SendMessage(hWnd, WM_GETICON, ICON_SMALL, 0); if(!RegisterClassEx(&wcex)) return; hCaptionWindow = CreateWindow(L"Caption Window", windowText, WS_VISIBLE | WS_POPUPWINDOW | WS_CAPTION, rcFrom.left, rcFrom.top, 0, 0, NULL, NULL, hInstance, NULL); captionWidth = GetSystemMetrics(SM_CYCAPTION) + 3; SetWindowPos(hCaptionWindow, NULL, 0, 0, 220, captionWidth, SWP_NOMOVE | SWP_NOZORDER); xInc = (rcTo.left - rcFrom.left) / ANIMATE_TRAY_NUMFRAMES; yInc = (rcTo.top + captionWidth - rcFrom.top) / ANIMATE_TRAY_NUMFRAMES; for(int i = 0; i < ANIMATE_TRAY_NUMFRAMES; i++) { Sleep(ANIMATE_TRAY_FRAMERATE); SetWindowPos(hCaptionWindow, NULL, rcFrom.left+=xInc, rcFrom.top+=yInc, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } DestroyWindow(hCaptionWindow); UnregisterClass(L"Caption Window", hInstance); } }
// 自动调整对话框大小 void CMsgTipDlg::SetDlgAutoSize() { int nMsgSenderCnt = 0; if (m_lpQQClient != NULL) { CMessageList * lpMsgList = m_lpQQClient->GetMessageList(); if (lpMsgList != NULL) nMsgSenderCnt = lpMsgList->GetMsgSenderCount(); } int cyListCtrl = nMsgSenderCnt * m_nListItemHeight + 5; int cxDlg = 212; int cyDlg = cyListCtrl + 36 + 22; int cxScreen = ::GetSystemMetrics(SM_CXFULLSCREEN); int cyScreen = ::GetSystemMetrics(SM_CYFULLSCREEN); CRect rcTrayWnd; GetTrayWndRect(&rcTrayWnd); int nLeft, nTop; if (rcTrayWnd.top == rcTrayWnd.left && rcTrayWnd.bottom > rcTrayWnd.right) // 左边 { nLeft = rcTrayWnd.right + 2; nTop = m_rcTrayIcon.top - (cyDlg - m_rcTrayIcon.Width()) / 2; if (nTop + cyDlg > cyScreen) nTop = cyScreen - cyDlg; } else if (rcTrayWnd.top == rcTrayWnd.left && rcTrayWnd.bottom < rcTrayWnd.right) // 上边 { nLeft = m_rcTrayIcon.left - (cxDlg - m_rcTrayIcon.Width()) / 2; nTop = rcTrayWnd.bottom + 2; if (nLeft + cxDlg > cxScreen) nLeft = cxScreen - cxDlg; } else if (rcTrayWnd.top > rcTrayWnd.left) // 下边 { nLeft = m_rcTrayIcon.left - (cxDlg - m_rcTrayIcon.Width()) / 2; nTop = rcTrayWnd.top - cyDlg - 2; if (nLeft + cxDlg > cxScreen) nLeft = cxScreen - cxDlg; } else // 右边 { nLeft = rcTrayWnd.left - cxDlg - 2; nTop = m_rcTrayIcon.top - (cyDlg - m_rcTrayIcon.Width()) / 2; if (nTop + cyDlg > cyScreen) nTop = cyScreen - cyDlg; } SetWindowPos(HWND_TOPMOST, nLeft, nTop, cxDlg, cyDlg, SWP_NOACTIVATE); Invalidate(); }
void Gui::MinToTray(const HWND hWnd) { if (DoAnimation() && ::IsWindowVisible(hWnd)) { RECT rcFrom = { 0 }, rcTo = { 0 }; ::GetWindowRect(hWnd, &rcFrom); GetTrayWndRect(rcTo); ::DrawAnimatedRects(hWnd, IDANI_CAPTION, &rcFrom, &rcTo); } ::ShowWindow(hWnd, SW_HIDE); }
void MinimizeWndToTray(HWND hWnd) { if(!IsWindowVisible(hWnd)) return; if(GetDoAnimateMinimize()) { RECT rcFrom,rcTo; GetWindowRect(hWnd,&rcFrom); GetTrayWndRect(&rcTo); DrawAnimatedRects(hWnd,IDANI_CAPTION,&rcFrom,&rcTo); } ShowWindow(hWnd,SW_HIDE); }
void CSystemTray::MinimiseToTray(HWND hWnd) { #ifndef _WIN32_WCE if (GetDoWndAnimation()) { RECT rectFrom, rectTo; GetWindowRect(hWnd, &rectFrom); GetTrayWndRect(&rectTo); DrawAnimatedRects(hWnd, IDANI_CAPTION, &rectFrom, &rectTo); } RemoveTaskbarIcon(hWnd); SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) &~ WS_VISIBLE); #endif }
void RestoreWndFromTray(HWND hWnd) { if(IsWindowVisible(hWnd)) return; if(GetDoAnimateMinimize()) { RECT rcFrom,rcTo; GetTrayWndRect(&rcFrom); GetWindowRect(hWnd,&rcTo); DrawAnimatedRects(hWnd,IDANI_CAPTION,&rcFrom,&rcTo); } ShowWindow(hWnd,SW_SHOW); SetActiveWindow(hWnd); SetForegroundWindow(hWnd); }
void Gui::RestoreFromTray(const HWND hWnd, BOOL bForceMax) { if (DoAnimation()) { RECT rcFrom = { 0 }, rcTo = { 0 }; GetTrayWndRect(rcFrom); ::GetWindowRect(hWnd, &rcTo); ::DrawAnimatedRects(hWnd, IDANI_CAPTION, &rcFrom, &rcTo); } BOOL bZoomed = (IsZoomed(hWnd) || bForceMax); ::ShowWindow(hWnd, bZoomed ? SW_SHOWMAXIMIZED : SW_RESTORE); ::SetActiveWindow(hWnd); ::SetForegroundWindow(hWnd); }
BOOL CTrayIconPosition::FindOutPositionOfIconDirectly(const HWND a_hWndOwner, const int a_iButtonID, CRect& a_rcIcon) { HWND hWndTray = GetTrayNotifyWnd(TRUE); if (hWndTray == NULL) { return FALSE; } DWORD dwTrayProcessID = (DWORD)-1; GetWindowThreadProcessId(hWndTray, &dwTrayProcessID); if(dwTrayProcessID == DWORD(-1)) { return FALSE; } HANDLE hTrayProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID); if(hTrayProc == NULL) { return FALSE; } int iButtonsCount = SendMessage(hWndTray, TB_BUTTONCOUNT, 0, 0); LPVOID lpData = VirtualAllocEx(hTrayProc, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE); if( lpData == NULL || iButtonsCount < 1 ) { CloseHandle(hTrayProc); return FALSE; } BOOL bIconFound = FALSE; for(int iButton=0; iButton<iButtonsCount; iButton++) { DWORD dwBytesRead = 0; TBBUTTON buttonData; SendMessage(hWndTray, TB_GETBUTTON, iButton, (LPARAM)lpData); ReadProcessMemory(hTrayProc, lpData, &buttonData, sizeof(TBBUTTON), &dwBytesRead); if(dwBytesRead < sizeof(TBBUTTON)) { continue; } DWORD dwExtraData[2] = { 0,0 }; dwBytesRead = 0; ReadProcessMemory(hTrayProc, (LPVOID)buttonData.dwData, dwExtraData, sizeof(dwExtraData), &dwBytesRead); if(dwBytesRead < sizeof(dwExtraData)) { continue; } HWND hWndOfIconOwner = (HWND) dwExtraData[0]; int iIconId = (int) dwExtraData[1]; if(hWndOfIconOwner != a_hWndOwner || iIconId != a_iButtonID) { continue; } if( buttonData.fsState & TBSTATE_HIDDEN ) { break; } RECT rcPosition = {0,0}; SendMessage(hWndTray, TB_GETITEMRECT, iButton, (LPARAM)lpData); dwBytesRead = 0; ReadProcessMemory(hTrayProc, lpData, &rcPosition, sizeof(RECT), &dwBytesRead); if(dwBytesRead < sizeof(RECT)) { continue; } MapWindowPoints(hWndTray, NULL, (LPPOINT)&rcPosition, 2); a_rcIcon = rcPosition; bIconFound = TRUE; break; } if(bIconFound == FALSE) { a_rcIcon = GetTrayWndRect(); a_rcIcon.left -= 16 + 2; if (a_rcIcon.Height () > 16) { a_rcIcon.top += (a_rcIcon.Height () - 16) / 2; a_rcIcon.bottom = a_rcIcon.top + 16; } } VirtualFreeEx(hTrayProc, lpData, NULL, MEM_RELEASE); CloseHandle(hTrayProc); return bIconFound; }
BOOL CTrayIconPosition::GetTrayIconPositionVisualScan(CPoint& a_ptPoint, Precision a_ePrec) { //let's find the time from last tray icon position calculation int iTotalSec = (m_tLastUpdate - CTime::GetCurrentTime()).GetTotalSeconds(); if(iTotalSec < 0) { iTotalSec = -iTotalSec; } Precision prec; if(a_ePrec == Default) { prec = m_prDefaultPrecision; } else { prec = a_ePrec; } BOOL bUpdateRequired = FALSE; if(prec == Low && iTotalSec > m_iPrecisions[0] || prec == Medium && iTotalSec > m_iPrecisions[1] || prec == High && iTotalSec > m_iPrecisions[2] ) { bUpdateRequired = TRUE; } if(bUpdateRequired) { m_rtRectangleOfTheTray = GetTrayWndRect(); if(FindOutPositionOfIcon(AfxGetApp()->LoadIcon(IDI_BLANK_BLACK)) == TRUE) { //we were able to find position of icon in tray - that's GREAT! m_tLastUpdate = CTime::GetCurrentTime(); a_ptPoint = m_ptPosition; return TRUE; } else { //We were unable to locate our icon - this is not a tragedy - usually there is a solution: if(m_osVer.dwPlatformId == VER_PLATFORM_WIN32_NT && m_osVer.dwMajorVersion >= 5) { //We're under Win XP //It's quite possible that icon is hidden now let's return Left-Center point of tray - it's most likely WinXP hide-tray-icons button. a_ptPoint = m_rtRectangleOfTheTray.CenterPoint(); a_ptPoint.x = m_rtRectangleOfTheTray.left + 6; } else { //we're not under XP - I have no idea why but we were unable to locate our icon - let's retunr center of the tray area a_ptPoint = m_rtRectangleOfTheTray.CenterPoint(); } return FALSE; } } else { a_ptPoint = m_ptPosition; } return TRUE; }
//First tracking method: attaches to Tray process and reads data directly, is fast and reliable but will fail if user uses non standard tray software //It was suggested by Neal Andrews with VB example: http://www.codeproject.com/shell/ctrayiconposition.asp?select=999036&forumid=14631&df=100#xx999036xx //Ported to C++ by Ireneusz Zielinski BOOL CTrayIconPosition::FindOutPositionOfIconDirectly(const HWND a_hWndOwner, const int a_iButtonID, CRect& a_rcIcon) { //first of all let's find a Tool bar control embed in Tray window HWND hWndTray = GetTrayNotifyWnd(TRUE); if (hWndTray == NULL) { return FALSE; } //now we have to get an ID of the parent process for system tray DWORD dwTrayProcessID = -1; GetWindowThreadProcessId(hWndTray, &dwTrayProcessID); if(dwTrayProcessID <= 0) { return FALSE; } HANDLE hTrayProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID); if(hTrayProc == NULL) { return FALSE; } //now we check how many buttons is there - should be more than 0 int iButtonsCount = SendMessage(hWndTray, TB_BUTTONCOUNT, 0, 0); //We want to get data from another process - it's not possible to just send messages like TB_GETBUTTON with a localy //allocated buffer for return data. Pointer to localy allocated data has no usefull meaning in a context of another //process (since Win95) - so we need to allocate some memory inside Tray process. //We allocate sizeof(TBBUTTON) bytes of memory - because TBBUTTON is the biggest structure we will fetch. But this buffer //will be also used to get smaller pieces of data like RECT structures. LPVOID lpData = VirtualAllocEx(hTrayProc, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE); if( lpData == NULL || iButtonsCount < 1 ) { CloseHandle(hTrayProc); return FALSE; } BOOL bIconFound = FALSE; for(int iButton=0; iButton<iButtonsCount; iButton++) { //first let's read TBUTTON information about each button in a task bar of tray DWORD dwBytesRead = -1; TBBUTTON buttonData; SendMessage(hWndTray, TB_GETBUTTON, iButton, (LPARAM)lpData); ReadProcessMemory(hTrayProc, lpData, &buttonData, sizeof(TBBUTTON), &dwBytesRead); if(dwBytesRead < sizeof(TBBUTTON)) { continue; } //now let's read extra data associated with each button: there will be a HWND of the window that created an icon and icon ID DWORD dwExtraData[2] = { 0,0 }; ReadProcessMemory(hTrayProc, (LPVOID)buttonData.dwData, dwExtraData, sizeof(dwExtraData), &dwBytesRead); if(dwBytesRead < sizeof(dwExtraData)) { continue; } HWND hWndOfIconOwner = (HWND) dwExtraData[0]; int iIconId = (int) dwExtraData[1]; if(hWndOfIconOwner != a_hWndOwner || iIconId != a_iButtonID) { continue; } //we found our icon - in WinXP it could be hidden - let's check it: if( buttonData.fsState & TBSTATE_HIDDEN ) { break; } //now just ask a tool bar of rectangle of our icon RECT rcPosition = {0,0}; SendMessage(hWndTray, TB_GETITEMRECT, iButton, (LPARAM)lpData); ReadProcessMemory(hTrayProc, lpData, &rcPosition, sizeof(RECT), &dwBytesRead); if(dwBytesRead < sizeof(RECT)) { continue; } MapWindowPoints(hWndTray, NULL, (LPPOINT)&rcPosition, 2); a_rcIcon = rcPosition; bIconFound = TRUE; break; } if(bIconFound == FALSE) { a_rcIcon = GetTrayWndRect(); //we failed to detect position of icon - let's return fail safe cooridinates of system tray } VirtualFreeEx(hTrayProc, lpData, NULL, MEM_RELEASE); CloseHandle(hTrayProc); return bIconFound; }