프로그램 시작시 다이얼로그를 숨기고 트레이아이콘만 나오게 설정하는 프로그램을 만들어 보신분은 조금은 고생하셨을 거라고 생각합니다.
ShowWindow(SW_HIDE)
을 삽입하면 다이얼로그를 숨기고 트레이아이콘만 나오게 할 수 있을 거라고 쉽게 생각하기 마련입니다. 저도 그와 같은 생각으로 소스코드의 여러군데에 삽입해 보았지만 아무 소용이 없었습니다. 그래서 다른 방법으로 다이얼로그를 제어해야한다는 것을 깨달았습니다.

 WindowPosChanging 메시지를 이용한 숨기기
 

WindowPosChanging 메시지는 윈도우의 크기, 위치, Z-order 순서 변경할때 발생하는 메시지입니다. 윈도우의 변화가 있으면 발생하는 메시지입니다.

WindowPosChanging 메시지의 멤버변수를 보면 flags 멤버변수가 있습니다. 이 변수는 윈도우의 위치에 대한 다양한 설정 값을 가지고 있습니다.
SWP_DRAWFRAME  프레임을 그린다.
SWP_FRAMECHANGED
SWP_HIDEWINDOW  윈도우를 숨긴다.
SWP_NOACTIVATE  윈도우를 활성화 시키지 않는다.
SWP_NOCOPYBITS  클라이언트 영역과 관련된 모든 정보를 무시한다.
SWP_NOMOVE  현재 위치를 유지한다. (x,y 파라미터를 무시한다.)
SWP_NOOWNERZORDER  소유주 윈도우의 Z-order를 변경하지 않는다.
SWP_NOREDRAW  윈도우를 새로 그리지 않는다. 어떠한 페인팅 관련 메시지도 포스트 되지 않는다.
SWP_NOREPOSITION  SW_NOOWNERZORDER 플래그와 같음
SWP_NOSENDCHANGING  윈도우가 WM_WINDOWPOSCHANGING 메시지를 받는 것을 막는다.
SWP_NOSIZE  사이즈를 변경하지 않는다. (cx, cy 파라미터를 무시한다.)
SWP_NOZORDER  Z-order를 변경하지 않는다.
SWP_SHOWWINDOW  윈도우를 출력한다.
다이얼로그가 생성될때 flags 가 SWP_SHOWWINDOW 값으로 설정되어질 것 입니다. 설정되어 있는 flags 값을 삭제하면 다이얼로그는 보이지 않을 것입니다.

[MFC] 트레이 아이콘 등록  ☞  http://pangsan.tistory.com/161

1. m_bShowStatus 멤버변수 선언
     
protected:
    bool m_bShowStatus;
다이얼로그 시작시 m_bShowStatus 변수값을 false 값으로 설정합니다.

2. OnWindowPosChanging 메시지를 작성한다.
     
void CTrayDlg::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
    CDialog::OnWindowPosChanging(lpwndpos);

    // TODO: 여기에 메시지 처리기 코드를 추가합니다.
    if( m_bShowStatus == true ) {
        lpwndpos->flags |= SWP_SHOWWINDOW;
    }
    else {
        lpwndpos->flags &= ~SWP_SHOWWINDOW;
    }
}
m_bShowStatus 가 true 값이면 윈도우를 보이게 하고, false 값이면 윈도우를 숨깁니다.
LRESULT CTrayDlg::TrayIconMessage(WPARAM wParam, LPARAM lParam)
{
    // 등록된 TrayIcon 클릭하면 Show....
    if(lParam == WM_LBUTTONDBLCLK) {
        ShowWindow(SW_SHOW);
        m_bShowStatus = true;
    }
    return 0L;
}
이대로 설정해두면 다이얼로그는 계속 숨김상태로 됩니다. 다이얼로그를 보이게 설정하려면 위의 소소크드처럼 트레이아이콘을 클릭하여 다이얼로그를 보이게 하는 메서드를 만들어서 m_bShowStatus 에 true 값을 설정해두면 다이얼로그를 보이게 만들 수 있습니다.
저작자 표시
신고

야이노마

» Contact Me: yainoma00@gmail.com




  1. 오곡

    2013.03.13 18:14 신고


    좋은 내용 잘봤습니다

  2. 고니파

    2013.05.03 10:31 신고


    심플하고 확실하네요 잘봤습니다. ^^



프로젝트는 대화 상자 기반으로 해서 TrayIcon 이름으로 Visual Studio 2005 기반에서 만들었습니다.


위의 그림에서 빨간색으로 밑줄친 CTrayIconDig 클래스의 메서드와 멤버변수를 수정해주시면 됩니다.

1. TrayIconDlg.h 헤더파일 수정
     

#define  WM_TRAYICON_MSG WM_USER + 1 삽입해준다.

2. m_bTrayStatus 멤버변수 선언
     

m_bTrayStatus 멤버변수는 트레이아이콘이 활성화 되어있는지를 확인하기 위한 체크변수입니다.
<TrayIconDlg.h>

protected:
    bool m_bTrayStatus;
3. OnInitDialog 수정
     
<TrayIconDlg.cpp>

BOOL CTrayIconDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다.

    // IDM_ABOUTBOX는 시스템 명령 범위에 있어야 합니다.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
    //  프레임워크가 이 작업을 자동으로 수행합니다.
    SetIcon(m_hIcon, TRUE);            // 큰 아이콘을 설정합니다.
    SetIcon(m_hIcon, FALSE);        // 작은 아이콘을 설정합니다.

    // TODO: 여기에 추가 초기화 작업을 추가합니다.
    m_bTrayStatus = false;
    TraySetting();

    return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
}
▷ m_bTrayStatus = false;
트레이 아이콘 상태를 비활성화 상태로 표시한다.
TraySetting();
트레이 아이콘 세팅을 한다.
< NOTIFYICONDATA 구조체 >

BOOL WINAPI Shell_NontifyIcon(DWORD dwMessage, PNOTIFYICONDATA pnid);

    * dwMessage로는 다음과 같은 값을 입력할 수 있습니다.
      NIM_ADD : 트레이에 새로운 아이콘 추가
    * NIM_DELETE : 트레이 영역의 아이콘 제거
    * NIM_MODIFY : 트레이 영역에 있는 아이콘 수정

typedef struct _NOTIFYICONDATA
{
    DWORD    cbSize;
    HWND    hWnd;
    UINT    uID;
    UINT    uFlags;
    UINT    uCallbackMessage;
    HICON    hIcon;
    char    szTip[64];
} NOTIFYICONDATA, *PNOTIFYICONDATA;

    * cbSize: 구조체의 크기
    * hWnd: 윈도우 핸들
    * uID: 아이콘 식별자, 호출한 애플리케이션의 아이콘을 다른것과 구별해서 식별할수 있게 해주는 사용자 정의값
    * uFlags: NIF_MESSAGE : uCallbackMessage 사용 NIF_ICON : hIcon 사용 NIF_TIP : szTip 사용
    * uCallbackMessage: 아이콘이 hWnd윈도우와 통신하기 위해서 사용할 메시지 ID. 메시지는 WM_APP의 오프셋으로 선언되는 사용자 정의 메시지이다.
    * hIcon: 화면에 그릴 아이콘의 핸들.
    * szTip: 아이콘의 툴팁을 위한 텍스트.
4. TraySetting 메서드를 작성한다.
     
<TrayIconDlg.h>

public:
    void TraySetting(void);
<TrayIconDlg.cpp>

void CTrayIconDlg::TraySetting(void)
{
    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_bTrayStatus = true;
}
5. OnSysCommand 수정한다.
   

<TrayIconDlg.cpp>

void CTrayIconDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else if( nID == SC_MINIMIZE )
    {
        ShowWindow(SW_HIDE);
    }
    else
    {
        CDialog::OnSysCommand(nID, lParam);
    }
}
최소화 버튼을 클릭하면 트레이아이콘으로 되도록 설정하는 부분입니다.


리소스 뷰 → Dialog IDD_TRAYICON_DIALOG 이동하여 Minimize Box 을 True 값으로 바꾼다.
다이얼로그에 최소화 버튼을 추가하는 부분입니다.

6. BEGIN_MESSAGE_MAP 을 수정한다.
     
<TrayIconDlg.cpp>

BEGIN_MESSAGE_MAP(CTrayIconDlg, CDialog)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    //}}AFX_MSG_MAP
    ON_MESSAGE(WM_TRAYICON_MSG, TrayIconMessage)
    ON_WM_DESTROY()
END_MESSAGE_MAP()

ON_MESSAGE(WM_TRAYICON_MSG, TrayIconMessage) 을 추가한다.

7. TrayIconMessage 메서드를 작성한다.
     
<TrayIconDlg.h>

protected:
    LRESULT TrayIconMessage(WPARAM wParam, LPARAM lParam);
<TrayIconDlg.cpp>

LRESULT CTrayIconDlg::TrayIconMessage(WPARAM wParam, LPARAM lParam)
{
    // 등록된 트레이 아이콘을 클릭하면 다이얼로그를 볼수있게 한다.
    if(lParam == WM_LBUTTONDBLCLK) {
        ShowWindow(SW_SHOW);
    }
    return 0L;
}
8. OnDestroy 수정한다.
     
<TrayIconDlg.cpp>

void CTrayIconDlg::OnDestroy()
{
    CDialog::OnDestroy();

    // TODO: 여기에 메시지 처리기 코드를 추가합니다.
    if(m_bTrayStatus) {
        NOTIFYICONDATA  nid;
        nid.cbSize = sizeof(nid);
        nid.hWnd = m_hWnd; // 메인 윈도우 핸들
        nid.uID = IDR_MAINFRAME;
        // 작업 표시줄(TaskBar)의 상태 영역에 아이콘을 삭제한다.
        Shell_NotifyIcon(NIM_DELETE, &nid);
    }
}
다이얼로그를 종료할때 트레이 아이콘이 있으면 트레이아이콘을 삭제해야합니다.

TrayIconDlg.cpp  [ 다운로드 ]
TrayIconDlg.h  [ 다운로드 ]

저작자 표시
신고

야이노마

» Contact Me: yainoma00@gmail.com




1