Where The Streets Have No Name

트레이 아이콘(TrayIcon) 사라지는 버그 막기 본문

Developement/C, C++, C#

트레이 아이콘(TrayIcon) 사라지는 버그 막기

highheat 2008. 5. 28. 12:52
출처 : http://blog.naver.com/ckpj1/100016767295

1. 요약

요즘 나오는 프로그램에서는 대부분 TrayIcon을 제공합니다.
단순히 프로그램 리스트(태스크 바)에 나오는 것보다는, TrayIcon이 사용자에게 보다 더 편리한 UI를 제공하기 때문입니다. 그런
데, 익스플로어(인터넷 익스플로어가 아닙니다.)의 버그 때문에 <그림 1>과 같이 종종 TrayIcon이 Tray에서 사라지는 경우가 있습
니다. 하지만, 몇몇의 프로그램은 사라지지 않고 계속 남아있는 경우도 볼 수 있습니다. 

<그림 1 - 트레이 아이콘에서 사라지는 모습>

그럼 우리의 프로그램도 익스플로어와는 상관없이 계속 트레이에 있으려면 어떻개 해야할까요? 익스플로어는 자신이 죽었다가 새
로 시작되는 경우 현재 보이는 모든 윈도우에게 멧세지를 보내주는데, 우리는 이 메시지를 등록하여 사용함으로써 트레이 아이콘이 사라지는 버그를 막을 수 있습니다.


2. 본문

트레이 아이콘에 문제가 생길 경우, 예를 들어 익스플로어가 다운되어 재 시작을 될 때에는 익스플로어가 현재 트레이 아이콘에 등
록되어 있는 모든 윈도우에게 보내주는 메시지는 “Taskbar Created"라는 메시지 입니다.

여러분이 그동안 살펴보았단 메세지와 다른 점은 WM_MOUSEMOVE 와 같은 상수값이 아니라, 문자열이라는 점인데, 이런식으로
문자열로 된 메세지는 실제로 있을 수 없습니다. 모든 메세지는 반드시 상수값을 가지고 있어야 합니다. 하지만, 단순한 상수 값으
로 메세지를 표현하기에는 한계가 있기 때문에 특정 문자열로 부터 메세지 상수를 등록하는 방법을 사용할 수 있습니다. 물론,
“Taskbar Created" 도 고유의 메세지 상수값을 윈도우로부터 얻을 수 있습니다.

이때 메시지를 등록하는 함수는 RegisterWindowMessage() 함수 입니다. 이 함수를 사용하여 반환되는 메시지 ID를 가지고 일반
메시지처럼 메시지 핸들러를 등록하여 사용하면 됩니다. 그리고 결과는 확인해 보고 싶으시면, Ctrl+Alt+Del 을 눌러서 익스플로어
(Explorer)를 ‘작업종료’ 시키시면 트레이 아이콘에서 몇몇 아이콘이 사라지는 효과(?)를 보실 수 있습니다.
만일 윈도우즈 NT 계열이라면(Windows 2000 포함) <그림 2>와 같이 작업 관리자를 띄워서 강제로 프로세스를 종료하면 됩니다.

<그림 2 - 작업 관리자>

그리고, 익스플로어를 다시 시작하기 위해서는 '파일|새 작업(실행...)' 를 선택하여 explorer 을 입력하시면 됩니다.

하지만, 우리가 만든 프로그램의 트레이 아이콘은 여전히 트레이에서 살아남는 강한 모습을 보여줄 것입니다.


3. 예제 코드

   
[// 메시지 등록 과정
 UINT g_uShellRestart;
 g_uShellRestart = RegisterWindowsMessage(__Text(“TaskbarCreated”)); 

  // Message Map 에서
 
ON_REGISTERED_MESSAGE(g_uShellRestart, OnTrayShow)
 
  // 메시지를 처리합니다.
 
LRESULT CMyDlg::OnTrayShow(WPARAM wParam, LPARAM lParam)
  {    
     // TrayIcon을 다시 보여줍니다. ShowTray는 Tray를 보여주는 함수입니다.    
     m_Tray.ShowTray();
   }

 

 

정리

 

제대로된 프로그램이라면 작은 기능을 제공하더라도 세세한 부분까지 신경써야 한다고 생각합니다. 비록 작은 기능이지만, 사용자
가 혼란스러워하지 않도록 기능을 구현하는 프로그래머가 되었으면 좋겠네요~