프로그램/api&mfc2012. 10. 14. 16:05

트레이 아이콘의 사용

윈도우 화면 우측 하단 시계 옆의 작은 아이콘을 트레이 아이콘이라고 하는데트레이아이콘의 생성과 사용하는 법을 살펴보도록 하겠다.


환경 : WinXP SP3 / Visual Studio 2008

 

1.  프로젝트 생성

-       형식 : MFC 응용프로그램

-       이름 : TrayIcon

-       응용프로그램 종류 : 대화상자 기반 (Dialog based)

2.  프로젝트 생성 후리소스 뷰의 아이콘 중 IDR_MAINFRAME을 자신이 원하는 모양으로 바꿔준다

3.  솔루션 뷰의 헤더파일 중 stdafx.h 파일의 아랫쪽 부분에 다음을 입력

(include 작업의 뒤쪽에 해 주는 것이 좋다.)

이것이 바로 사용자 정의 윈도우 메시지의 설정.(9번과 10번 과정을 꼭 해야함)

 

#define WM_DIALOG_SHOWWM_USER + 101  //다이얼로그감추기/보이기

#define WM_APP_EXIT               WM_USER + 102  //다이얼로그종료

#define WM_TRAYICON               WM_USER + 103  //트레이아이콘메시지

 

4.  CTrayIconMng 클래스를 추가한다기본 클래스는 Cobject.

5.  그리고 CTrayIconMng 클래스의 멤버변수와 함수를 추가 해 준다.

 

        // 트레이아이콘이생성되었는지여부 (True : 생성됨)

        bool m_bAdded;

        // 다이얼로그가감춰진상태인지여부 (True : 숨겨짐)

        bool m_bHide;

        // 팝업메뉴생성

        void MakePopupMenu(HWND hWnd, int x, int y);

        // 팝업메뉴의이벤트발생시처리함수

        void ProcTrayMsg(HWND hWnd, WPARAM wParam, LPARAM lParam);

        // 트레이아이콘생성

        BOOL AddTrayIcon(HWND hWnd);

        // 트레이아이콘제거

        BOOL DelTrayIcon(HWND hWnd);

 

6.  CTrayIconMng 클래스의 멤버함수 코드들을 다음과 같이 각각 작성한다.

// 팝업메뉴생성

void CTrayIconMng::MakePopupMenu(HWND hWnd, int x, int y)

{

  //팝업메뉴를생성하고메뉴구성

  HMENU hMenu = CreatePopupMenu();

  if(m_bHide)            //다이얼로그가감춰진상태라면

        AppendMenu(hMenu, MF_STRING, WM_DIALOG_SHOW, _T("다이얼로그보이기"));

    else                 //다이얼로그가숨겨진상태라면

        AppendMenu(hMenu, MF_STRING, WM_DIALOG_SHOW, _T("다이얼로그감추기"));

 

  AppendMenu(hMenu, MF_STRING, WM_APP_EXIT, _T("종료"));

 

  SetForegroundWindow(hWnd);//생성된팝업메뉴밖을클릭할때팝업닫기

  //팝업메뉴띄우기

    TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, hWnd, NULL);

}

 

 

// 팝업메뉴의이벤트발생시처리함수

void CTrayIconMng::ProcTrayMsg(HWND hWnd, WPARAM wParam, LPARAM lParam)

{

  HMENU hMenu = NULL;

    POINT pos;

 

    if(lParam == WM_LBUTTONDOWN)

    {

        GetCursorPos(&pos);

         MakePopupMenu(hWnd, pos.x, pos.y); //팝업메뉴생성및출력

    }

}

 

// 트레이아이콘생성

BOOL CTrayIconMng::AddTrayIcon(HWND hWnd)

{

  if(m_bAdded)           //이미트레이아이콘이있다면종료

         return FALSE;

 

  NOTIFYICONDATA nid;    //아이콘을생성하여설정

    ZeroMemory(&nid, sizeof(NOTIFYICONDATA));

    nid.cbSize = sizeof(NOTIFYICONDATA);

    nid.hWnd = hWnd;

    nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;

    nid.uCallbackMessage = WM_TRAYICON;

    sprintf((char*)nid.szTip, (char*)_T("TrayTest"));

    nid.uID = 0;

    nid.hIcon = theApp.LoadIcon(IDR_MAINFRAME);

 

    if(Shell_NotifyIcon(NIM_ADD, &nid)==0) //트레이아이콘표시

        return FALSE;

  m_bAdded = true;      

    return TRUE;

}

 

// 트레이아이콘제거

BOOL CTrayIconMng::DelTrayIcon(HWND hWnd)

{

  NOTIFYICONDATA nid;

 

    ZeroMemory(&nid, sizeof(NOTIFYICONDATA));

    nid.cbSize = sizeof(NOTIFYICONDATA);

    nid.hWnd = hWnd;

    nid.uFlags = NULL;

    if(Shell_NotifyIcon(NIM_DELETE, &nid)==0) //트레이아이콘삭제

        return FALSE;

    return TRUE;

 

}

7.  CTrayIconDlg 에 멤버 변수 및 함수 추가       

// 트레이아이콘관리용객체

  CTrayIconMng m_myTray;

  // 트레이아이콘보이기/숨기기여부

  bool m_bHide;

  long OnTrayIcon(WPARAM wParam, LPARAM lParam);

  void OnAppExit(void);

void OnDialogShow(void);

 

8.  CTrayIconDlg  OnInitDialog() 함수의 마지막부분에 다음을 추가하여 프로그램이 시작됨과 동시에 트레이아이콘을 추가하게끔 함  

m_Tray.m_bHide = m_bHide;

        m_Tray.AddTrayIcon(GetSafeHwnd());

        return TRUE;  // 컨트롤에 대한 포커스를 설정하지 않을 경우 TRUE를 반환합니다.

 

9.  CTrayIconDlg 에 다음의 함수를 추가 이들은 사용자 메시지 핸들러 역할을 한다

long OnTrayIcon(WPARAM wParam, LPARAM lParam);

void OnAppExit();

void OnToggleShow();

 

10. CTrayIconDlg의 메시지 맵에서 사용자 메시지 핸들러와 연결을 시켜준다

 

BEGIN_MESSAGE_MAP(CMyMessengerDlg, CDialog)

        ON_MESSAGE(WM_TRAYICON, OnTrayIcon)

        ON_COMMAND(WM_APP_EXIT, OnAppExit)

ON_COMMAND(WM_DIALOG_SHOW, OnDialogShow)

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

 

11. CTrayIconDlg 클래스의 함수들을 다음과 같이 지정 해 준다.

(이때, .cpp 파일에 #include "TrayIconMng.h" 가 포함되어야 한다)

 

//트레이아이콘을클릭했을때의메시지핸들러

long CTrayIconDlg::OnTrayIcon(WPARAM wParam, LPARAM lParam)

{

  m_myTray.ProcTrayMsg(GetSafeHwnd(), wParam, lParam);

  return 0;

}

 

//트레이아이콘팝업메뉴의종료메뉴메시지핸들러

void CTrayIconDlg::OnAppExit(void)

{

  m_myTray.DelTrayIcon(GetSafeHwnd());

  CDialog::OnCancel();

}

 

//트레이아이콘보이기/숨기기메뉴메시지핸들러

void CTrayIconDlg::OnDialogShow(void)

{

  if(!m_bHide) ShowWindow(false);       //보이는상태라면숨기고

  else ShowWindow(true);                //숨겨진상태라면보이게

  m_bHide = !m_bHide;

  m_myTray.m_bHide = m_bHide;

}

 

12.  컴파일 및 실행

Posted by wrnly
프로그램/api&mfc2012. 5. 19. 20:45

MFC 트레이 아이콘 등록 및 윈도우 감추기
+   [Computer Language/MFC]   |  2007/08/04 21:38  

윈도우 우측 하단에 트레이 아이콘을 등록하는 방법이다.

우선 프로젝트에 현재 트레이 상태를 알수 있는 BOOL 변수를 선언한다.

Protected 에 선언 변수 이름은 m_bIsTrayIcon 로 하겠다.



다음 트레이아이콘을 등록하는 함수를 만든다. 함수 이름은 RegistTrayIcon 로 하겠다.
Private 로 선언


그리고 코딩한다.
void CTrayDlg::RegistTrayIcon()
{
 NOTIFYICONDATA  nid;
 nid.cbSize = sizeof(nid);
 nid.hWnd = m_hWnd; // 메인 윈도우 핸들
 nid.uID = IDR_MAINFRAME;  // 아이콘 리소스 ID
 nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; // 플래그 설정
 nid.uCallbackMessage = WM_TRAYICON_MSG; // 콜백메시지 설정
 nid.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); // 아이콘 로드

 char strTitle[256];
 GetWindowText(strTitle, sizeof(strTitle)); // 캡션바에 출력된 문자열 얻음
 lstrcpy(nid.szTip, strTitle); 
 Shell_NotifyIcon(NIM_ADD, &nid);
 SendMessage(WM_SETICON, (WPARAM)TRUE, (LPARAM)nid.hIcon);
 m_bIsTrayIcon = TRUE;
}

그리고.. 다이얼로그의 헤더파일에 가서

#define  WM_TRAYICON_MSG WM_USER + 1 을 정의 해준다.
본 예에서는 TrayDlg.h 가 되겠다.

다시 TrayDlg.cpp 에 가서
BEGIN_MESSAGE_MAP(CTrayDlg, CDialog)  부분에 다음을 추가한다.
ON_MESSAGE(WM_TRAYICON_MSG, TrayIconMsg)
이 부분을 다시 보면 다음과 같다.

BEGIN_MESSAGE_MAP(CTrayDlg, CDialog)
 //{{AFX_MSG_MAP(CTrayDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 //}}AFX_MSG_MAP
 ON_MESSAGE(WM_TRAYICON_MSG, TrayIconMsg)
END_MESSAGE_MAP()



그리고 함수를 하나더 추가하는데
protected 로 void TrayIconMsg(WPARAM wParam, LPARAM lParam); 함수를 추가한다.
코딩은 다음과 같다.
트레이로 등록된 아이콘을 클릭시 발생하는 함수가 되는 것이다.

// WM_TRAYICON_MSG 이 메세지를 받으면 구동..
void CTrayDlg::TrayIconMsg(WPARAM wParam, LPARAM lParam)
{
 // 등록된 TrayIcon 클릭하면 Show....
 if(lParam == WM_LBUTTONDBLCLK)
 {  
  ShowWindow(SW_SHOW);
 }
}


자 다음으로는 OnSysCommand 라는 함수가 정의 되어 있을 것인데,
이곳에 버튼을 클릭했을시 윈도우를 어떻게 할지 핸들링을 할 수 있다.

void CTrayDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }

/*  상단에 x 버튼을 눌렀을때
 else if(nID == SC_CLOSE)
 {
 
 }
*/
 // 최소화 버튼을 눌렀을때
 else if(nID == SC_MINIMIZE)
 { 
  ShowWindow(SW_HIDE);
 }

 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

위의 코드는 최소화버튼을 눌렀을때 윈도우를 감추게 된다.

그리고 OnInitDialog() 함수로 간다.
이 함수는 다이얼로그가 실행되기 위해서 최초로 동작하는 함수이다.
맨 아래에 이 두줄을 추가한다.
 m_bIsTrayIcon = FALSE;
 RegistTrayIcon();


그리고 마지막으로 프로그램이 종료될때 트레이 아이콘을 종료 해줘야 하므로
OnDestroy 함수를 이용해야 한다.

클래스 위져드(Ctrl+W) 를 열어서 WM_DESTROY 를 선택하고
Add Function 을 클릭, 편집한다.
void CTrayDlg::OnDestroy() 
{
 CDialog::OnDestroy();
 
 // TODO: Add your message handler code here 
 if(m_bIsTrayIcon) // 현재 트레이 아이콘으로 설정되었는지 확인 
 {
  NOTIFYICONDATA  nid;
  nid.cbSize = sizeof(nid);
  nid.hWnd = m_hWnd; // 메인 윈도우 핸들
  nid.uID = IDR_MAINFRAME;

  // 작업 표시줄(TaskBar)의 상태 영역에 아이콘을 삭제한다.
  Shell_NotifyIcon(NIM_DELETE, &nid);
 }

 
}


아참.. 깜박했다. 다이얼로그의 Properties 에서
Styles 의 Minimize box 를 체크해줘야 한다는 것이다~ ㅋ
그래야 오른쪽 상단에 줄이는 버튼이 나오지 -_-;;


첨부파일을 참조하세요~~~

                                              

/////////////////////////

MFC SDI 시작시 창 숨기고 TrayIcon 등록하기  MFC / 프로그래밍 

2010/06/18 02:02

stdafx.h에  

#define  WM_TRAYICON_MSG WM_USER + 1
#define  WM_TRAYICONHIDE WM_USER + 2 추가해준다.

 

MainFrame의 메시지맵에

ON_MESSAGE(WM_TRAYICON_MSG, TrayIconMsg)
 ON_MESSAGE(WM_TRAYICONHIDE, TrayIconHide) 추가해준다.

 

MainFrame의 헤더에 사용자 정의 함수  및 변수 추가해준다.

protected:
 LRESULT TrayIconMsg(WPARAM wParam, LPARAM lParam);
 LRESULT TrayIconHide(WPARAM, LPARAM);

private:

 bool m_bIsTrayIcon;


/////////////////////////////////////////////

한가지더 트레이메시지는 메인프레임에넣잡. 난 폼뷰방식이라그런지 뷰가아니라 메인프레임에서 잘받아짐~!

Posted by wrnly