출처 : http://cpueblo.com/programming/api/contents/197.html

 

 

프로세스가 강제종료 되었을 때 트레이에 아이콘 잔상이 남게 되는데

시스템트레이를 refresh 해 주면 된다

 

struct TRAYDATA

{

HWND hwnd;

UINT uID;

UINT uCallbackMessage;

DWORD Reserved[2];

HICON hIcon;

};

 

static HWND FindTrayToolbarWindow()

{

      HWND hWnd_ToolbarWindow32 = NULL;

      HWND hWnd_ShellTrayWnd;


      hWnd_ShellTrayWnd = ::FindWindow(_T("Shell_TrayWnd"), NULL);

      if(hWnd_ShellTrayWnd)

      {

            HWND hWnd_TrayNotifyWnd = ::FindWindowEx(hWnd_ShellTrayWnd,NULL,_T("TrayNotifyWnd"), NULL);

                  if(hWnd_TrayNotifyWnd)

                  {

                        HWND hWnd_SysPager = ::FindWindowEx(hWnd_TrayNotifyWnd,NULL,_T("SysPager"), NULL);        // WinXP


                        // WinXP 에서는 SysPager 까지 추적            

                        if(hWnd_SysPager)

                              hWnd_ToolbarWindow32 = ::FindWindowEx(hWnd_SysPager, NULL,_T("ToolbarWindow32"), NULL);

                        // Win2000 일 경우에는 SysPager 가 없이 TrayNotifyWnd -> ToolbarWindow32 로 넘어간다

                        else

                              hWnd_ToolbarWindow32 = ::FindWindowEx(hWnd_TrayNotifyWnd, NULL,_T("ToolbarWindow32"), NULL);

                  }

            }

      return hWnd_ToolbarWindow32;

}

 

BOOL CTesDlg::RefreshTrayIcon()

{

      HANDLE                         m_hProcess;

      LPVOID                         m_lpData;

      TBBUTTON                tb;

      TRAYDATA                tray;

      DWORD                         dwTrayPid;

      int                                TrayCount;


      // Tray 의 윈도우 핸들 얻기

      HWND m_hTrayWnd = FindTrayToolbarWindow();

      if (m_hTrayWnd == NULL)

            return FALSE;

      // Tray 의 개수를 구하고

      TrayCount = (int)::SendMessage(m_hTrayWnd, TB_BUTTONCOUNT, 0, 0);


      // Tray 윈도우 핸들의 PID 를 구한다

      GetWindowThreadProcessId(m_hTrayWnd, &dwTrayPid);


      // 해당 Tray 의 Process 를 열어서 메모리를 할당한다

      m_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTrayPid);

      if (!m_hProcess)

            return FALSE;

 

      // 해당 프로세스 내에 메모리를 할당

      m_lpData = VirtualAllocEx(m_hProcess, NULL, sizeof (TBBUTTON), MEM_COMMIT, PAGE_READWRITE);

      if (!m_lpData)

            return FALSE;

      // Tray 만큼 뺑뺑이

      for(int i = 0; i < TrayCount; i++)

      {

            ::SendMessage(m_hTrayWnd, TB_GETBUTTON, i, (LPARAM)m_lpData);        

 

            // TBBUTTON 의 구조체와 TRAYDATA 의 내용을 얻기

            ReadProcessMemory(m_hProcess, m_lpData, (LPVOID)&tb, sizeof (TBBUTTON), NULL);

            ReadProcessMemory(m_hProcess, (LPCVOID)tb.dwData, (LPVOID)&tray, sizeof (tray), NULL);

            // 각각 트레이의 프로세스 번호를 얻어서

            DWORD dwProcessId = 0;

            GetWindowThreadProcessId(tray.hwnd, &dwProcessId);


            // Process 가 없는 경우 TrayIcon 을 삭제한다

            if (dwProcessId == 0)

            {

                  NOTIFYICONDATA        icon;

                  icon.cbSize        = sizeof(NOTIFYICONDATA);

                  icon.hIcon        = tray.hIcon;

                  icon.hWnd        = tray.hwnd;

                  icon.uCallbackMessage = tray.uCallbackMessage;

                  icon.uID        = tray.uID;

                  Shell_NotifyIcon(NIM_DELETE, &icon);

            }

      }

      // 가상 메모리 해제와 프로세스 핸들 닫기

      VirtualFreeEx(m_hProcess, m_lpData, NULL, MEM_RELEASE);

      CloseHandle(m_hProcess);        

 

return TRUE;

}

'MFC' 카테고리의 다른 글

윈도우 자석효과  (0) 2012.10.05
윈도우 자르기  (0) 2012.10.05
실행중인 프로세스ID로 HWND구하기  (0) 2012.10.05
뮤텍스로 중복실행 방지  (0) 2012.10.05
문자열 파싱  (0) 2012.10.05
Posted by 떡공이
,