프로그램 시작시 다이얼로그를 숨기고 트레이아이콘만 나오게 설정하는 프로그램을 만들어 보신분은 조금은 고생하셨을 거라고 생각합니다.
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







프로젝트는 대화 상자 기반으로 해서 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





포털사이트라면 사소한 문제라도 일으키지 않으려고 노력을 해야한다고 생각합니다. 그런데 네이버측은 사소한 문제라고 생각할 수도 있지만, 링크 연결을 잘못 하면 사용자 입장에서는 짜증이 날 수 밖에 없습니다.

인터넷 익스플로러8을 사용해본 사람이라면 "뭐 이런게 있어?" 라고 하면서
버그 투성이인 IE8에 대해  욕을 남발할 것입니다. 저만 그런가?
그래서 IE7로 다운그레이드를 하려고 네이버에서 IE7을 검색을 했습니다.


많은 사람이 검색을 하여서 그런지 자동완성 기능까지 지원하더군요.


여러가지 방법으로 익스플로러7 사이트 연결을 지원하는 네이버에 감사하면서 이때까지만 해도 입에 미소를 띄고있는 야이노마였습니다.

컴퓨터를 오랫동안 사용해서인지 웹서핑으로 나오는 안내문, 경고메시지 등의 메시지는 무엇을 말하는지 알고 있는 야이노마는 기계같이 예/아니오 를 선택하는 경지까지 되었습니다.


신의 경지인 야이노마는 링로로 연결된 사이트에서 자연스럽게 다른 글씨는 눈에 띄지 않고 다운받기 링크만 보이더군요. 위의 그림의 노란색 박스에 버젓이 익스플로러8이라고 써있는데도 불구하고 다운받기 글씨만 제 눈에 들어오는 것은 왜일까요?

자연스럽게 다운받기 링크를 통해서 실행파일을 다운받아서 설치하는 중간에 익스플로러8을 다운받을 것을 알았습니다. 그때는 저의 검색 실수라고 생각하고 자책을 하면서 다시 익스플로러7을 다운받기 위해 네이버로 접속을 했습니다.

그런데 정확하게 익스플로러7로 검색을 해서 링크로 연결된 사이트로 이동을 했는데 어이없게도 익스플로러8 사이트로 연결이 되는 것입니다. 검색을 잘못했다고 자책을 했던 야이노마는 어이가 없었습니다. 우리나라에서(만) 최대 포털사이트라고 하는 네이버가 이런 링크 문제를 일으킬 줄은 몰랐네요.

이런 사소한 문제를 완만히 해결해 주십사 네이버 고객센터에 문의 메일을 날리고 오는 야이노마였습니다.

야이노마

» Contact Me: yainoma00@gmail.com






2년가까이 사용하고 있던 노트북이 그만 아프다고 하소연을 해서 A/S를 받았습니다. 델노트북이라서 오프라인 서비스센터는 서울에 한군데 밖에 없어서 출장 서비스를 받았습니다. 그 덕택에 A/S 기사분과 여러가지 이야기를 하면서 노트북 분해하는 것을 지켜보았습니다.

노트북 먼지청소는 하시나요?  ☞  http://pangsan.tistory.com/56

위의 링크를 보시면 알겠지만 저는 호기심반, 짜증 반으로 노트북을 분해했던 적이 있었습니다.

야이노마: 전에 제가 노트북을 분해했던 일이 있었습니다. 먼지 청소하려고 분해했었는데 처음이라서 정말 어렵더군요 ^^
기술자: 아 그러셨군요. 나사를 보니 분해했던 흔적이 있어서 알고는 있었습니다.

전에 노트북 분해를 하면서 싸구려 중국산 드라이버를 사용했던 것이 그 문제였습니다. 나사가 마모된다는 소리는 들어봤어도 드라이버가 마모되는 경우는 처음 경험했거든요. 드라이버가 마모되는 바람에 덩달아 나사까지 마모가 되어서 나사 상태가 많이 안 좋았던 것을 보고 A/S 기사분은 이미 알고 계시더라구요.



중국산 드라이버를 원망하면서 드라이버를 사기위해 철문점에서 드라이버를 보고 있었습니다. 드라이버 구경하는 저에게 철물점 주인 아저씨가 신신당부 하신말이 있습니다.

주인아찌: 중국산은 왠만해선 사지마세요. 한두푼 아끼려다가 나사 다 망가집니다.

A/S 기사분과 이런 저런 이야기를 하는 중에 기사분이 저에게 하는말이 있었습니다.

기술자: 노트북은 분해를 하면 할수록 수명이 줄어드는것 같아요.

한편으로는 수궁이 가기도 하지만, 한편으로는 잘 수긍이 가지 않았습니다. 그래서 왜냐고 질문을 하니 이런 대답을 해 주더군요.
노트북은 데스크탑과 다르기 때문에 고장나면 혼자서 수리가 거의 불가능합니다. 노트북 구조가 간단한 노트북은 괜찮지만, 구조가 복잡한 노트북은 기술자들도 고치기 싫어해요. 그만큼 노트북 분해/조립은 어렵기 때문에 초보자들이 분해하면 할수록 알게 모르게 문제점이 발생하게 됩니다.
그리고 제가 분해 했을때 잘못했던 점을 3가지 지적해 주더군요.

1. 나사 위치가 다르다.
    ▷나사의 크기는 똑같지 않고 들쑥날쑥해서 잘못된 위치에 나사를 조립했습니다.
2. 깨진 부위가 있다.
   
억지로 분해하려다가 생긴 불상사입니다.
3. 나사가 확실히 조여지지 않았다.
  
급히 조립을 하느라 확실히 나사가 조여지지 않았습니다.

누구나 실수할 수 있는 부분이고 이런 사소한 문제(?)때문에 노트북이 고장이 난다고 신신당부를 하더라구요. 노트북 초보자 분은 노트북 분해하시는데 좀더 신중을 기해야 하고, 왠만해서는 분해를 하지 말기를 당부하더군요. 노트북 원본 상태로 보존하면 A/S 기사들도 고치는 것이 한결 수월하다고 합니다.

야이노마

» Contact Me: yainoma00@gmail.com





링크을 클릭하실때 단순히 마우스 좌클릭으로만 하시나요?
저는 링크를 클릭할때 마우스만 이용해서 클릭을 하기도 하지만 키보드 + 마우스를 이용해서 클릭을 하면 링크 열리는 것을 바꿀 수 있습니다.

 링크 옵션
현재창( IE&파폭 )
새로운창( IE/파폭 )
마우스 좌클릭  현재탭  로운창/로운
 Shift + 좌클릭
 새로운창  새로운창/새로운
 Ctrl + 좌클릭
 새로운  새로운/로운
 휠 마우스
 새로운  새로운탭/로운

위의 표는 대표적인 웹 브라우져인 익스플로러와 파이어폭스를 예를들어 설명한 것 입니다. 저는 주로 Ctrl + 좌클릭 방식을 이용하여 새탭으로 여는 방법을 많이 사용합니다.

야이노마

» Contact Me: yainoma00@gmail.com