1. 헤더파일에 소스코드 추가
     

typedef BOOL(WINAPI *SLWA)(HWND,COLORREF,BYTE,DWORD);

2. 투명 다이얼로그 메서드 만들기
     

void CSampleDlg::SetTransparent(int percent)
{
    SLWA pSetLayeredWindowAttributes = NULL;

    HINSTANCE hmodUSER32 = LoadLibrary("USER32.DLL");
    pSetLayeredWindowAttributes =
    (SLWA)GetProcAddress(hmodUSER32,"SetLayeredWindowAttributes");

    HWND hwnd = this->m_hWnd;
    SetWindowLong(hwnd,GWL_EXSTYLE,GetWindowLong(hwnd,GWL_EXSTYLE) | WS_EX_LAYERED);
    pSetLayeredWindowAttributes(hwnd, 0, percent, LWA_ALPHA);
}
3. 투명 다이얼로그 적용하기
     

SetTransparent( 100 );
투명도를 100으로 설정한 다이얼로그 모습입니다.
투명도는 0에서 255까지 설정할 수 있습니다.



야이노마

» Contact Me: yainoma00@gmail.com





ShellExecute 사용 방법      

HINSTANCE ShellExecute(    
     HWND hwnd,
     LPCTSTR lpOperation,
     LPCTSTR lpFile,
     LPCTSTR lpParameters,
     LPCTSTR lpDirectory,
     INT nShowCmd
);

hwnd : 핸들값을 받는다. ( 보통 NULL로 지정한다. )
lpOperation : 수행할 동작을 지정한다. ( 프로그램 실행시에는 "open"을 사용한다. )
lpFile : 수행할 프로그램의 파일명을 적는다. ( 절대경로를  지정한다. )
lpParameters : 프로그램 수행시 파라메터를 지정한다.( 파라메터가 없다면 NULL로 지정한다. )
lpDirectory : 파일의 경로를 적어준다.(  lpFile에 절대경로를 적으므로 NULL로 지정한다. )
nShowCmd : 프로그램 수행시 윈도우 크기 등 지정한다.

ShellExecute 사용예제
     
// 그림판 실행
ShellExecute(NULL, "open", "C:\\WINDOWS\\system32\\mspaint.exe", NULL, NULL, SW_SHOW);
// 네이트온 실행
ShellExecute(NULL, "open", "C:/Program Files/NATEON/BIN/NATEON.exe", NULL, NULL, NULL);

야이노마

» Contact Me: yainoma00@gmail.com





1. CFileDialog 사용 방법
     
CFileDialog( BOOL bOpenFileDialog,
             LPCTSTR lpszDefExt = NULL,
             LPCTSTR lpszFileName = NULL,
             DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
             LPCTSTR lpszFilter = NULL,
             CWnd* pParentWnd = NULL );

bOpenFileDialog     TRUE면 Open dialog, FALSE면 Save as dialog
lpszDefExt              기본파일확장자로 선언이 되면 해당하는 확장자를 가진 파일만 나온다.
lpszFileName         파일명 에디트 박스에 초기화될 파일명
dwFlags                  dialog box 기본 FLAG, m_ofn.Flags에 등록된다
                                OFN_NOCHANGEDIR             디렉토리변경불가
                                OFN_HIDEREADONLY            읽기전용파일은 숨김
                                OFN_OVERWRITEPROMPT   존재하는 파일 덮어쓰기전에 확인하기
                                OFN_FILEMUSTEXIST           반드시 존재하는 파일명만 입력받음
                                OFN_ALLOWMULTISELECT   다중선택가능
                                OFN_ENABLESIZING             파일열기 대화상자의 크기 조절가능
dwFlags(*1)          
lpszFilter                연속된 문자열쌍으로 파일 확장자를 원하는 타입으로 나오게 할수 있다
pParentWnd            다이얼로그 소유 윈도우 포인터

2. CFileDialog 사용예
     

    char *szFilter = "비트맵(*.bmp)|*.bmp|JPEG(*.jpg)|*.jpg||";
    CFileDialog imageSave( FALSE, NULL, m_SaveTab.GetFileName(), OFN_FILEMUSTEXIST, szFilter, NULL );
   
    // 확장자 BMP = 0, JPG = 1
    int nSelected = 1;   
    TCHAR* szExtension[2] = { ".bmp", ".jpg" };

    imageSave.m_ofn.nFilterIndex = (DWORD)nSelected;
    if( imageSave.DoModal() == IDOK ) {
        CString strFileName = imageSave.GetFileName();
        CString strFileExt = imageSave.GetFileExt();
       
        // 콤보상자에서 확장자를 선택했을 시
        if( strFileExt == "" ) {   
            // 선택된 파일 확장자의 인덱스를 가져온다.
            nSelected = (int)imageSave.m_ofn.nFilterIndex;
            // 인덱스에 맞는 확장자를 FileName에 붙인다.
            strFileName += szExtension[nSelected-1];   
        }

야이노마

» Contact Me: yainoma00@gmail.com





다이얼로그의 BOrder 속성을 None으로 설정하면 타이틀바가 제거된 다이얼로그를 만들 수 있습니다. 다이얼로그는 타이틀바를 마우스 좌클릭으로 드레그 해야하는데 타이틀 바가 없으니 이동이 불가능합니다. 이때 다이얼로그 영역을 좌클릭해서 드레그 할 수 있게 구현해 보겠습니다.

1. WM_LBUTTONDOWN 메시지 추가
     

왼쪽 마우스를 누른상태에서 드레그를 하기 위해 WM_LBUTTONDOWN 메시지를 추가합니다.

2. 좌클릭시 발생하는 메시지를 보내는 소스코드 추가
     

void XXXX::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
    SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, 0 );

    CDialog::OnLButtonDown(nFlags, point);
}
SendMessage( WM_NCLBUTTONDOWN, HTCAPTION, 0 ); 왼쪽 마우스를 클릭했을 시 타이틀바 부분을 클릭한 것처럼 인식하게 만든다.

야이노마

» Contact Me: yainoma00@gmail.com





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





소스 코딩을 하면 그 프로그램에 맞는 툴을 사용하게 됩니다. 영어 울렁증이 있는 분은 영어로 된 툴을 쓰는 것을 꺼려하기 때문에 한글로 된 툴을 많이 사용합니다. 한글로 된 툴을 사용하면 에러메시지까지 한글로 출력이 되는 경우가 있습니다.

에러메시지가 한글로 출력된다면 그때만은 편할지 모르지만, 다른 영문툴을 상용할때 영어로 된 에러메시지를 보면 어떤 에러메시지인지 잘 알지 못합니다. 그래서 에러메시지만큼은 영문으로 보는 것을 강력히 추천합니다.

그 이유는 어느 회사에서 어느 툴로 개발할지 모르기 때문에 그때 한글을 지원하는 툴이 아니라면 상당히 고생을 할 것이라고 생각하기 때문입니다. 저도 영어 울렁증이 있지만 영문으로 에러메시지를 보다보면 어느정도 에러메시지의 뜻을 알수 있게 되더군요. 영문 에러메시지에 익숙해 진다면 어느 툴을 사용하더라도 영어 울렁증으로 힘들어하는 것은 많이 줄어들 것이라고 생각합니다.

서론이 너무 길었네요. 이제 본론으로 넘어갈게요.

 에러메시지만 영문으로 출력하기
 


위의 그림처럼 한글로 나오는 에러메시지를 영문으로 바꿔보겠습니다.


Visual Studio 설치 폴더 → VC
→ bin[각주:1] 폴더로 이동하게 되면 위의 그림처럼 여러가지 파일들이 보일 것입니다. 그 중에서 1042, ko 폴더를 삭제 해 주시면 에러메시지만 영문으로 출력할 수 있습니다.

1042, ko 폴더를 삭제해 주는 것보다 다른곳에 백업을 해 두시고 삭제를 하는 것이 좋을 것 입니다. 그 이유는 에러메시지를 한글로 보고 싶으면 삭제했던 파일을 백업 파일로 복원하기 위해서 입니다.


간단히 폴더 2개를 삭제하는 것으로 위와 같이 에러메시지만 영문으로 나타나게 할 수 있습니다.



  1. Visual Studio 2005의 경우 경로를 디폴트로 지정된 것을 사용하였다면 C:Program FilesMicrosoft Visual Studio 8VCbin 위치가 되겠습니다. [본문으로]

야이노마

» Contact Me: yainoma00@gmail.com





VC++ 6.0 에서 VS2005 로 넘어 오면서 많은 기능이 추가 되었지만, 없어진 기능이 있습니다. 그중에서 WM_INITDIALOG는 메세지가 아니라서 이벤트 처리하는 부분이 사라졌습니다.
그래서 다이얼로그를 직접 오버라이드 해서 사용해야 합니다.

1. 해당파일.h 파일의 protected: 아래에 OnInitDialog() 메서드를 선언합니다.

protected:
 virtual BOOL OnInitDialog();


2. 해당파일.cpp 파일에 OnInitDialog() 메서드를 정의 합니다.

BOOL 클래스명::OnInitDialog()
{
 CDialog::OnInitDialog();    

 // TODO: 여기에 명령 처리기 코드를 추가합니다.
return TRUE;
}

야이노마

» Contact Me: yainoma00@gmail.com





VC++ 6.0 에서는 클래스위자드를 이용하여 이벤트 처리를 할 수 있었으나, VS2005 에서는 클래스위자드가 없어졌습니다. 더 편하게 만든다고 했지만 오히려 더 불편한 감이 있네요.

 이벤트 처리는 어떻게???  


클래스뷰의 해당 클래스를 선택하고 마우스 우클릭 속성( ALT+ENTER ) 를 누르시면 속성창이 활성화 됩니다.


속성창의 번개 모양[각주:1]을 클릭하시면 이벤트 처리를 하실 수 있습니다.  그런데 툴바의 ID 값은 나타나지 않아서 툴바에 대한 이벤트 처리를 할 수 없습니다.

그래서 편법을 이용하여 툴바에 해당하는 이벤트 처리를 해야합니다.

1. 리소스 뷰 창을 연다.
2. Menu → IDR_MAINFRAME 메뉴를 생성한다.
3. 메뉴의 ID 값을 툴바의 ID 값과 일치 시킨다.
4. 클래스 뷰에서 메뉴에 해당하는 이벤트를 처리한다.
5. 메뉴를 삭제한다.


저는 이런식으로 해결을 하고 있습니다. 근본적인 해결책을 모르기 때문에 이런 방법으로 해결할 수 밖에 없었습니다. 근본적인 해결책을 아시는 분은 알려주시면 감사합니다.





  1. 왼쪽 그림의 빨간 네모 박스 [본문으로]

야이노마

» Contact Me: yainoma00@gmail.com




1