최상단 광고

2012년 4월 9일 월요일

트레이 아이콘 만들기


우선 Dialog Based기반으로 한 프로젝트에서 해본다.트레이 아이콘을 만들기 위해서는 우선 헤더에 사용자 메시지를 추가해야 한다.
#define  UM_TRAYICON  WM_USER+7

class Login : public StandardDialog
{
...
}
그리고 헤더 메시지맵에 추가한다.
// Implementation
protected:
 // Generated message map functions
 //{{AFX_MSG(Login)
 afx_msg void OnConfirm();
 virtual void OnCancel();
 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
 virtual BOOL OnInitDialog();
 afx_msg void OnExit();
 afx_msg void OnClose();
 afx_msg void OnLathe();
 afx_msg void OnDestroy();
 afx_msg void OnExit2();
 afx_msg void OnShow();
 afx_msg void OnMymenuMsg();
 //}}AFX_MSG
//이곳은 자동으로 생성되는 코드가 아닌 사용자가 직접 정의해주는 부분이다.
 LONG TrayIconShow(WPARAM wParam,LPARAM lParam); //<--메시지 맵 추가 

 DECLARE_MESSAGE_MAP()
};
다음으로 cpp파일부분의 메시지 맵에 추가한다.
BEGIN_MESSAGE_MAP(Login, StandardDialog)
 //{{AFX_MSG_MAP(Login)
 ON_BN_CLICKED(IDC_CONFIRM, OnConfirm)
 ON_WM_SETCURSOR()
 ON_BN_CLICKED(IDC_EXIT, OnExit)
 ON_BN_CLICKED(IDC_CLOSE, OnClose)
 ON_BN_CLICKED(IDC_LATHE, OnLathe)
 ON_WM_DESTROY()
 ON_COMMAND(ID_EXIT2, OnExit2)
 ON_COMMAND(ID_SHOW, OnShow)
 ON_COMMAND(ID_MYMENU_MSG, OnMymenuMsg)
 //}}AFX_MSG_MAP
 ON_MESSAGE(UM_TRAYICON,TrayIconShow)  //<--추가 부분END_MESSAGE_MAP()

특정버튼을 클릭했을떄 트레이 아이콘이 만들어진다면
그 함수부분에 다음과 같이 코딩한다.
void Login::OnOK()
{
    ShowWindow(SW_HIDE);
    NOTIFYICONDATA nid; //<--NOTIFYICONDATA 구조체를 사용
    nid.cbSize = sizeof(nid);
    nid.hWnd = m_hWnd;    //현재 다이얼로그의 윈도우 핸들
    nid.uID = IDI_MYICON;   //아이콘의 리소스ID
    nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
    nid.uCallbackMessage = UM_TRAYICON; //우리가 만든 메시지
    nid.hIcon = AfxGetApp()->LoadIcon(IDI_MYICON);
    lstrcpy(nid.szTip,"트레이아이콘"); // 툴팁
    // taskBar상태영역에 아이콘 추가,삭제,수정할때 시스템에 메시지 전달
    Shell_NotifyIcon(NIM_ADD,&nid); //<--중요부분
    SendMessage(WM_SETICON,(WPARAM)TRUE,(LPARAM)nid.hIcon);
}
그리고 위의 헤더에서 정의했던 TrayIconShow함수를 구현한다.
여기서는 오른족 마우스를 트레이 아이콘에 클릭했을경우 메뉴가 나타나게 한다.
LONG Login::TrayIconShow(WPARAM wParam, LPARAM lParam)
{
    if(lParam == WM_RBUTTONDOWN) //오른쪽 마우스 클릭시
    {
       //메뉴를 로드한다.
        CMenu menu, *pMenu;
        CPoint pt;
        menu.LoadMenu(IDR_MYMENU);
        pMenu = menu.GetSubMenu(0);
        GetCursorPos(&pt);
        pMenu->TrackPopupMenu(TPM_RIGHTALIGN,pt.x,pt.y,this);
    }
 //트레이 아이콘을 더블클릭했을때 윈도우가 보여지게 한다.
  if(lParam == WM_LBUTTONDBLCLK)
  {
     ShowWindow(SW_SHOW); //윈도우를 보여준다.
   }
    return 0L;
}
//OnDestroy()함수에서 트레이아이콘을 파괴한다.
void Login::OnDestroy()
{
 StandardDialog::OnDestroy();
 CDialog::OnDestroy();
    // TODO: Add your message handler code here
    if(m_bLoad)
    {
        NOTIFYICONDATA nid;
        nid.cbSize = sizeof(nid);
        nid.hWnd = m_hWnd;
 
        nid.uID = IDI_MYICON;
        Shell_NotifyIcon(NIM_DELETE,&nid);//<-중요부분
    }
 // TODO: Add your message handler code here
}
//닫기 버튼을 클릭하면 WM_CLOSE메시지가 발생하며 OnClose()함수가 호출되어진다.
void Login::OnClose()
{
 // TODO: Add your control notification handler code here
 ShowWindow(SW_HIDE); //닫기 버튼을 클릭했을때 윈도우를 숨긴다.
}

//메뉴 클릭시 함수구현은 따로 해주어야한다.
만약 Dialog Base기반이 아닌 Single Document나 Multi Document기반으로 했을때는
CMainFrame클래스에서 트레이 아이콘을 설정한다. 예를 보여주지!!
우선
CMainFrame의 헤더위헤 메시지 추가
#if !defined(AFX_MAINFRM_H__D76C111C_99ED_4DD1_8FE2_D3BAE04F60E7__INCLUDED_)
#define AFX_MAINFRM_H__D76C111C_99ED_4DD1_8FE2_D3BAE04F60E7__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define  UM_TRAYICON  WM_USER+7 //TrayIcon 메시지 정의
//트레이 아이콘 생성
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    ...................................................................................
   ...................................................................................
    m_bLoad = TRUE;
    NOTIFYICONDATA nid; //<--NOTIFYICONDATA 구조체를 사용
    nid.cbSize = sizeof(nid);
    nid.hWnd = m_hWnd;    //현재 다이얼로그의 윈도우 핸들
    nid.uID = IDR_MAINFRAME;   //아이콘의 리소스ID
    nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
    nid.uCallbackMessage = UM_TRAYICON; //우리가 만든 메시지
    nid.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    lstrcpy(nid.szTip,"주차관리 시스템(버전1.1)"); // 툴팁
    // taskBar상태영역에 아이콘 추가,삭제,수정할때 시스템에 메시지 전달
    Shell_NotifyIcon(NIM_ADD,&nid); //<--중요부분
    SendMessage(WM_SETICON,(WPARAM)TRUE,(LPARAM)nid.hIcon);
 return 0;
}
헤더의 메시지맵에 다음을 추가
// Generated message map functions
protected:
 //{{AFX_MSG(CMainFrame)
 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
 afx_msg void OnDestroy();
 afx_msg void OnClose();
 afx_msg void OnWindowShow();
 afx_msg void OnWindowHide();
 afx_msg void OnWindowClose();
 //}}AFX_MSG
 LONG TrayIconShow(WPARAM wParam,LPARAM lParam); //<--메시지 맵 추가 

cpp에도 다음을 추가
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
 //{{AFX_MSG_MAP(CMainFrame)
 ON_WM_CREATE()
 ON_WM_DESTROY()
 ON_WM_CLOSE()
 ON_COMMAND(ID_WINDOW_SHOW, OnWindowShow)
 ON_COMMAND(ID_WINDOW_HIDE, OnWindowHide)
 ON_COMMAND(ID_WINDOW_CLOSE, OnWindowClose)
 //}}AFX_MSG_MAP
 ON_MESSAGE(UM_TRAYICON,TrayIconShow)  //<--추가 부분
위의 헤더에 선언했던 TrayIconShow함수 구현
LONG CMainFrame::TrayIconShow(WPARAM wParam, LPARAM lParam)
{
    if(lParam == WM_RBUTTONDOWN) //오른쪽 마우스 클릭시
    {
       //메뉴를 로드한다.
        CMenu menu, *pMenu;
        CPoint pt;
        menu.LoadMenu(IDR_MAINFRAME);
        pMenu = menu.GetSubMenu(1);
        GetCursorPos(&pt);
        pMenu->TrackPopupMenu(TPM_RIGHTALIGN,pt.x,pt.y,this);
    }
 //트레이 아이콘을 더블클릭했을때 윈도우가 보여지게 한다.
  if(lParam == WM_LBUTTONDBLCLK)
  {
     ShowWindow(SW_SHOW); //윈도우를 보여준다.
   }
    return 0L;
}

트레이 아이콘은 리소스를 차지 하기 때문에 나중에 파괴해 주어야 한다.
void CMainFrame::OnDestroy()
{
 CFrameWnd::OnDestroy();
 // TODO: Add your message handler code here

 if(m_bLoad) //트레이 아이콘이 되어있다면
    {
        //리소스 해제
        NOTIFYICONDATA nid;
 
        nid.cbSize = sizeof(nid);
        nid.hWnd = m_hWnd;
 
        nid.uID = IDR_MAINFRAME;
        Shell_NotifyIcon(NIM_DELETE,&nid);//<-중요부분
    }
}

댓글 없음: