티스토리 뷰

프로그래밍/MFC

트레이 아이콘

에어버스 2020. 10. 22. 16:27

 

리소스에 트레이 팝업메뉴(IDR_MENU_TRAY)와 아이콘(IDI_ICON_ON/OFF)을 추가한다.

 

인터넷 검색을 하니 동적으로 팝업메뉴를 생성하는것이 있는데 이벤트 발생이 안되어 리소스 메뉴를 이용함.

 

다이얼로그 기반 프로그램에서 OnInitDialog() 에서 TraySetting() 호출하여 트레이 아이콘과 팝업 메뉴를 만들어 등록한다.

처음 실행할때 메인 다이얼로그 창이 뜨면 트레이 팝업메뉴에서 창을 열고 닫기 가능하지만, 창을 실행할때 열리지 않게 OnWindowPosChanging() 에서 lpwndpos->flags &= ~SWP_SHOWWINDOW; 로 처리하면 팝업 메뉴에서 창 열기가 안된다. 그래서 프로그램 실행하면 로그인하는 이벤트 처리기에서 ShowWindow(SW_HIDE); 로 창을 숨긴다. 이리 해야 팝업 메뉴에서 창을 열고 닫기 가능하다.

로그인 실패로 서버 연결이 안되면 아이콘을 바꾸도록 처리함.

임의의 버튼을 만들어 클릭 이벤트에서 ShowWindow(SW_HIDE) 처리하면 될듯...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// 다이얼로그 기반 프로그램
#define _MSG_TRAYICON 1032
 
class CKeyPhoneDlg : public CDialogEx
{
...
private:
BOOL m_bTrayStatus;
public:
afx_msg LRESULT OnTrayIconMessage(WPARAM wParam, LPARAM lParam);
};

BOOL m_bTrayStatus; // 멤버변수로 선언

BEGIN_MESSAGE_MAP(CKeyPhoneDlg, CDialogEx)
{
...
ON_MESSAGE(WM_USER + _MSG_TRAYICON, &CKeyPhoneDlg::OnTrayIconMessage)
}
BOOL CKeyPhoneDlg::OnInitDialog()
{
...
    m_bTrayStatus = FALSE;
    TraySetting();
    return TRUE;
}
 
 
void CKeyPhoneDlg::TraySetting()
{
    NOTIFYICONDATA  nid;
    nid.cbSize = sizeof(nid);
    nid.hWnd = m_hWnd; // 메인 윈도우 핸들
    nid.uID = IDI_ICON_ON; // IDR_MAINFRAME;  // 아이콘 리소스 ID
    nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; // 플래그 설정
    nid.uCallbackMessage = WM_USER + _MSG_TRAYICON; // 콜백메시지 설정
    nid.hIcon = AfxGetApp()->LoadIcon(IDI_ICON_ON); //IDR_MAINFRAME); // 아이콘 로드   
 
    TCHAR strTitle[256= L"KeyPhone ON";     // 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;
}
 
void CKeyPhoneDlg::OnDestroy()
{
    CDialogEx::OnDestroy();
 
    // TODO: 여기에 메시지 처리기 코드를 추가합니다.
    if (m_bTrayStatus) 
    {
        NOTIFYICONDATA  nid;
        nid.cbSize = sizeof(nid);
        nid.hWnd = m_hWnd; // 메인 윈도우 핸들
        nid.uID = IDI_ICON_ON; //IDR_MAINFRAME;
        // 작업 표시줄(TaskBar)의 상태 영역에 아이콘을 삭제한다.
        Shell_NotifyIcon(NIM_DELETE, &nid);
    }
}
 
 
LRESULT CKeyPhoneDlg::OnTrayIconMessage(WPARAM wParam, LPARAM lParam)
{
    // WM_USER + _MSG_TRAYICON 사용자정의 메시지 처리기
    // 등록된 트레이 아이콘을 클릭하면 다이얼로그를 볼수있게 한다.
    //if (lParam == WM_LBUTTONDBLCLK) {
    //    ShowWindow(SW_SHOW); // 다이얼로그 보이기
    //}
 
    HMENU hMenu = NULL;
    POINT pos;
    if (lParam == WM_RBUTTONDOWN)
    {
        GetCursorPos(&pos);
        MakePopupMenu(GetSafeHwnd()/*hWnd*/, pos.x, pos.y); //팝업메뉴생성및출력
    }
    return 0L;
}
 
 
void CKeyPhoneDlg::트레이아이콘변경()
{
    NOTIFYICONDATA  nid;
    nid.cbSize = sizeof(nid);
    nid.hWnd = m_hWnd; // 메인 윈도우 핸들
    nid.uID = IDI_ICON_ON; //IDR_MAINFRAME;
    // 작업 표시줄(TaskBar)의 상태 영역에 아이콘을 삭제한다.
    Shell_NotifyIcon(NIM_DELETE, &nid);
 
    nid.cbSize = sizeof(nid);
    nid.hWnd = m_hWnd; // 메인 윈도우 핸들
    nid.uID = IDI_ICON_OFF; // IDR_MAINFRAME;  // 아이콘 리소스 ID
    nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; // 플래그 설정
    nid.uCallbackMessage = WM_USER + _MSG_TRAYICON; // 콜백메시지 설정
    nid.hIcon = AfxGetApp()->LoadIcon(IDI_ICON_OFF); //IDR_MAINFRAME); // 아이콘 로드   
 
    TCHAR strTitle[256= L"KeyPhone OFF";     // char strTitle[256];
    //GetWindowText(strTitle, sizeof(strTitle)); // 캡션바에 출력된 문자열 얻음
 
    lstrcpy(nid.szTip, strTitle);
    Shell_NotifyIcon(NIM_ADD, &nid);
    SendMessage(WM_SETICON, (WPARAM)TRUE, (LPARAM)nid.hIcon);
}
 
void CKeyPhoneDlg::OnTrayOpen()
{
    ShowWindow(SW_SHOW);    
}
 
 
void CKeyPhoneDlg::OnTrayClose()
{
    ShowWindow(SW_HIDE);    
}
 
 
void CKeyPhoneDlg::OnTrayExit()
{
    if (IDNO == AfxMessageBox(TEXT("키폰 프로그램을 종료하겠습니까?"), MB_YESNO))
        return;
 
   CDislogEx::OnOK();
}
 
 
void CKeyPhoneDlg::MakePopupMenu(HWND hWnd, int x, int y)
{
    //////////////////////////////
    /////////////
    ////팝업메뉴를생성하고메뉴구성
    //HMENU hMenu = CreatePopupMenu();
    //if (m_bTrayStatus)            //다이얼로그가감춰진상태라면
    //    AppendMenu(hMenu, MF_STRING, WM_USER + _MSG_SHOWHIDE, _T("다이얼로그보이기"));
    //else                 //다이얼로그가숨겨진상태라면
    //    AppendMenu(hMenu, MF_STRING, WM_USER + _MSG_SHOWHIDE, _T("다이얼로그감추기"));
 
    //AppendMenu(hMenu, MF_STRING, WM_USER + _MSG_EXIT, _T("종료"));
    //SetForegroundWindow(); // hWnd);//생성된팝업메뉴밖을클릭할때팝업닫기
 
    ////팝업메뉴띄우기
    //TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, hWnd, NULL);
    /////////////
    
    // 동적 팝업메뉴 등록이 안되어 리소스 메뉴를 이용한다.
    CMenu menu;
    menu.LoadMenu(IDR_MENU_TRAY);
    SetForegroundWindow(); // hWnd);//생성된팝업메뉴밖을클릭할때팝업닫기, 리소스 메뉴를 이용할때는 팝업메뉴 등록전에 호출해야 한다. 등록 후 호출하면 팝업메뉴 안 닫힘. 20201022
    CMenu* pTrayMenu = menu.GetSubMenu(0);
    pTrayMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, this);    
    //////////////////////////////
}
cs
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28