Search

'Program Visual C++'에 해당되는 글 36건

  1. 2008.02.29 RichEdit 관련
  2. 2007.07.12 VC++ UNICODE Build - Configuration
  3. 2007.05.25 ActiveX 보안관련 설정
  4. 2007.05.21 Tray

RichEdit 관련

Program Visual C++ 2008. 2. 29. 11:37 Posted by HisPark

RichEditCtrl은 다른 콘트롤들과 달리 설정해 줘야 되는게 많네요...

아마도 외부 콘트롤이라서 그런것 같은데, 버전도 1.0, 2.0, 3.0 까지 있는데,

Win98에서는 2.0을, 2000이나 XP는 3.0을 사용하는 것 같습니다.

특이한 것이 DLL의 이름이 1.0은 'RichEd32.dll'이고, 2.0과 3.0은 'RichEd20.dll'로 동일합니다. (뭘로 구분하죠? -_;;)




--------------------------------------------------------------------------------

(1) 일단 RichEditCtrl를 사용하는 프로그램은 CWinApp를 상속받은 클래스내 InitInstance() 함수에서 'AfxInitRichEdit(); "을  추가 해줘야 한다!
  

이것을 왜 해줘야 하는지 위 함수를 추적해보니 아래의 내용을 처럼. 'RichEd32.dll'가 로드 안되어 있으면,

로드를 해주는 함수 LoadLibraryA()를 호출해주더군요...

이걸 안해주니..전혀 엉뚱하게 MFC내 CDialog나 CFormView같은 클래스 생성 함수에서 오류가 뜨더군요...

Windows2000에서 동작확인시에는 'RichEd32.dll' 이 로드되고, 이게 다시 'RichEd20.dll'을 로드하더군요.

  

/*

BOOL PASCAL AfxInitRichEdit()

{

    _AFX_RICHEDIT_STATE* pState = _afxRichEditState;

    if (pState->m_hInstRichEdit == NULL)

        pState->m_hInstRichEdit = LoadLibraryA("RICHED32.DLL");

    return pState->m_hInstRichEdit != NULL;

}

*/

--------------------------------------------------------------------------------

(2) VC6.0 클래스 위자드 내에 RichEditCtrl 사용 메세지중 NM_ 으로 사용되는 메세지는 사용할 수 없다!
  

문서에는 NM_이 아니라 EN_으로 시작되는 Notification Message들에 대해 설명되어 있습니다.

  

NM_CLICK, NM_DBCLICK, NM_KILLFOCUS, NM_OUTOFMEMORY, NM_RCLICK, NM_RDBLCLK, NM_RETURN, NM_SETFOCUS

  

테스트 해보면, 위에 있는 이런 메세지를 클래스 위자드에서 연결을 시켜도 호출자체가 안 일어나더군요.

대신에 아래와 같이 EN_ 으로 시작하는 메세지가 존제하는데,

개인적인 생각으로는 Class Wizards 만든 분(?)이 RichEditCtrl용 메세지를 다른 것들과 혼돈하여

EN_(EditCtrl Notification Message)가 아닌 NM_(Notification Message)으로 사용한 것이 아닌가하는 추축이 듭니다. (믿거나 말거나 -_;;)

아래와 같은 메세지들은 잘 동작합니다.



EN_CORRECTTEXT , EN_DRAGDROPDONE, EN_DROPFILES, EN_IMECHANGE, EN_LINK, EN_MSGFILTER
EN_OBJECTPOSITIONS , EN_PROTECTED, EN_REQUESTRESIZE, EN_SELCHANGE ,EN_ALIGNLTR , EN_ALIGNRTL , EN_OLEOPFAILED , EN_SAVECLIPBOARD , EN_STOPNOUNDO
  
음...하여간 RichEditCtrl은 OS에서 제공한다뿐이지 다른 콘트롤과는 확연히 다른 콘트롤이라는 생각을 가지고 있어야 할 것 같습니다.




--------------------------------------------------------------------------------

(3) RichEditCtrl에서 마우스나 키보드 관련 이벤트를 사용하고자 하는 경우에는 다음과 같은 절차를 따른다.
  

초기화 함수(OnInitDialog() 혹은 OnInitUpdate())에서 받고자 하는 메세지의 종류에 대해 이벤트 마스크 플래그를  별도로 설정 해줘야 합니다. (문서 안 읽고, 클래스 위자드만 보면, 그냥 해주면 되는 것 같은 착각이 들기도 합니다..-_;:)

  

    CRichEditCtrl *pWndRichEditCtrl = (CRichEditCtrl*)GetDlgItem(IDC_RICHEDIT1);

    pWndRichEditCtrl->SetEventMask(pWndRichEditCtrl->GetEventMask() | ENM_MOUSEEVENTS | ENM_SCROLLEVENTS | ENM_KEYEVENTS);
    // 다른 것도 추가로 사용하고자 한다면 이벤트 마스크 플래그를 더 추가해주면 됩니다.


그리고, 'EN_MSGFILTER' 메세지 처리용 함수를 아래와 같이 유사(?)하게 구현한다  
  

void CxFormView::OnMsgfilterRichedit1(NMHDR* pNMHDR, LRESULT* pResult)
{
    MSGFILTER *pMsgFilter = reinterpret_cast<MSGFILTER *>(pNMHDR);
    // TODO: The control will not send this notification unless you override the
    // CFormView::OnInitDialog() function to send the EM_SETEVENTMASK message
    // to the control with either the ENM_KEYEVENTS or ENM_MOUSEEVENTS flag
    // ORed into the lParam mask.

    // TODO: Add your control notification handler code here
    switch(pMsgFilter->msg)
    {
    case WM_RBUTTONDOWN:    // 마우스 우측버턴에 대한 처리를 해주고자 하는 경우.
        OnRclickRichedit1(&pMsgFilter->nmhdr, pResult);    // NM_RCLICK 함수형태로 된 함수 콜~
        break;
    }
    *pResult = 0;
}

  

void CxFormView::OnRclickRichedit1(NMHDR* pNMHDR, LRESULT* pResult)
{
    // TODO: Add your control notification handler code here
    AfxMessageBox("아직 기능 구현 중입니다.");
    *pResult = 0;
}




** 아래 내용은 참고하시고 보시면 더 좋을 것 같습니다.



좋은 하루 되십시요.


--------------------------------------------------------------------------------



Platform SDK: Windows User Interface


About Rich Edit Controls
The original specification for rich edit controls is Rich Edit 1.0; the current specification is Rich Edit 3.0. Each version of rich edit is a superset of the preceding one, except that only Asian builds of Rich Edit 1.0 have a vertical text option. Before creating a rich edit control, you should call the LoadLibrary function to verify which version of Rich Edit is installed. The following table shows which DLL corresponds with which version of rich edit. Note that the name of the file did not change from version 2.0 to version 3.0. This allows version 2.0 to be upgraded to version 3.0 without breaking existing code.



Rich Edit version DLL
1.0 Riched32.dll
2.0 Riched20.dll
3.0 Riched20.dll


Windows NT/Windows 2000

Microsoft® Windows NT® version 4.0 includes Rich Edit 1.0 and 2.0. Microsoft Windows®  2000 includes Rich Edit 3.0 with a Rich Edit 1.0 emulator.

Windows 98

Windows 98 includes Rich Edit 1.0 and 2.0.

Windows 95

Windows 95 includes only Rich Edit 1.0. However, Riched20.dll is compatible with Windows 95 and may be installed if an application that uses Rich Edit 2.0 has been installed.



--------------------------------------------------------------------------------

Creating a Rich Edit Control
To create a rich edit control, call the CreateWindowEx function, specifying the rich edit window class. If you are using Rich Edit 1.0 (Riched32.dll), specify RichEdit for the window class parameter. If you are using Rich Edit 2.0 or later (Riched20.dll), specify RICHEDIT_CLASS for the window class parameter.

Rich edit controls support most of the window styles used with edit controls as well as additional styles. You should specify the ES_MULTILINE window style if you want to allow more than one line of text in the control.



--------------------------------------------------------------------------------


Miscellaneous Notification Messages
A rich edit control's parent window can process notification messages to monitor events affecting the control. Rich edit controls support all of the notification messages used with edit controls as well as several additional ones. You can determine which notification messages a rich edit control sends its parent window by setting its event mask.

To set the event mask for a rich edit control, use the EM_SETEVENTMASK message. You can retrieve the current event mask for a rich edit control by using the EM_GETEVENTMASK message. For a list of event mask flags, see Rich Edit Control Event Mask Flags.

A rich edit control's parent window can filter all keyboard and mouse input to the control by processing the EN_MSGFILTER notification message. The parent window can prevent the keyboard or mouse message from being processed or can change the message by modifying the specified MSGFILTER structure.

An application can process the EN_PROTECTED notification message to detect when the user attempts to modify protected text. To mark a range of text as protected, you can set the protected character effect. For more information, see Text Formatting.

You can enable the user to drop files in a rich edit control by processing the EN_DROPFILES notification message. The specified ENDROPFILES structure contains information about the files being dropped.

For lists of the edit control and rich edit control notification messages, see Rich Edit Notification Messages and Edit Control Notification Messages.




--------------------------------------------------------------------------------

Rich Edit Control Event Mask Flags
The event mask specifies which notification messages a rich edit control sends to its parent window. The event mask can be none or a combination of these values.



Value Meaning
ENM_CHANGE Sends EN_CHANGE notifications.
ENM_CORRECTTEXT Sends EN_CORRECTTEXT notifications.
ENM_DRAGDROPDONE Sends EN_DRAGDROPDONE notifications.
ENM_DROPFILES Sends EN_DROPFILES notifications.
ENM_IMECHANGE Rich Edit 1.0 only: Sends EN_IMECHANGE notifications when the IME conversion status has changed. Only for Asian-language versions of the operating system.
ENM_KEYEVENTS Sends EN_MSGFILTER notifications for keyboard events.
ENM_LINK Rich Edit 2.0 and later: Sends EN_LINK notifications when the mouse pointer is over text that has the CFE_LINK and one of several mouse actions is performed.
ENM_MOUSEEVENTS Sends EN_MSGFILTER notifications for mouse events.
ENM_OBJECTPOSITIONS Sends EN_OBJECTPOSITIONS notifications.
ENM_PROTECTED Sends EN_PROTECTED notifications.
ENM_REQUESTRESIZE Sends EN_REQUESTRESIZE notifications.
ENM_SCROLL Sends EN_HSCROLL and EN_VSCROLL notifications.
ENM_SCROLLEVENTS Sends EN_MSGFILTER notifications for mouse wheel events.
ENM_SELCHANGE Sends EN_SELCHANGE notifications.
ENM_UPDATE Sends EN_UPDATE notifications.
Rich Edit 2.0 and later: this flag is ignored and the EN_UPDATE notifications are always sent. However, if Rich Edit 3.0 emulates Rich Edit 1.0, you must use this flag to send EN_UPDATE notifications..




The default event mask is ENM_NONE in which case no notification messages are sent to the parent window. You can retrieve and set the event mask for a rich edit control by using the EM_GETEVENTMASK and EM_SETEVENTMASK messages.



'Program Visual C++' 카테고리의 다른 글

AfxBeginThread 사용법?  (0) 2009.05.05
Microsoft Platform SDK  (0) 2009.02.25
VC++ UNICODE Build - Configuration  (0) 2007.07.12
ActiveX 보안관련 설정  (0) 2007.05.25
Tray  (0) 2007.05.21

VC++ UNICODE Build - Configuration

Program Visual C++ 2007. 7. 12. 09:40 Posted by HisPark
1.
메뉴의 Build - Configuration을 선택하면
대화상자가 나오는데 여기서 Add를 눌러줍니다.
그러면 새 설정 이름과 어떤 설정을 복사해서 새 설정을 만들지 선택하게 됩니다.
여기서 적당한 이름을 주세요.

2. Project Settings에서
C/C++ 탭을 선택하신 다음에
Preprocessor Definitions에 _UNICODE를 추가해주세요.

project setting - link - catagory : output - entrypoint symbol -> wWinMainCRTStartup 입력하시면 됩니다..

'Program Visual C++' 카테고리의 다른 글

Microsoft Platform SDK  (0) 2009.02.25
RichEdit 관련  (0) 2008.02.29
ActiveX 보안관련 설정  (0) 2007.05.25
Tray  (0) 2007.05.21
COblist is not safe on Thread  (0) 2007.04.16

ActiveX 보안관련 설정

Program Visual C++ 2007. 5. 25. 14:36 Posted by HisPark
안정성을 보장하는 ActiveX 컨트롤 제작



  일반적인 방식으로(ActiveX 컨트롤 제작에서 설명한 방식) ActiveX 컨트롤을 작성하면, 웹에서 ActiveX 사용의 마지막 부분에 ActiveX 컨트롤과 Html 객체와의 연동 시에 보안 문제가 있다는 것을 설명했다. 이제 그 해결법을 설명하고자 한다.

간단히 설명하면 ActiveX 컨트롤 루틴에 안정성을 보장하는 루틴(안정성을 보장하는 clsid를 레지스트리에 등록하는 루틴)을 추가해야 한다. 먼저 레지스트리에 clsid를 등록하는 함수를 작성하고 실제 ActiveX 컨트롤 제작에서 작성한 컨트롤에 추가를 해보기로 한다.



함수 작성

다음과 같은 내용의 cathelp.h라는 파일을 작성한다.
  

#if !defined(__CATHELP_H)
#define __CATHELP_H

#include "comcat.h"

// Helper function to create a component category and associated
// description
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);

// Helper function to register a CLSID as belonging to a component
// category
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);

#endif



다음과 같은 내용의 cathelp.cpp라는 파일을 작성한다.

#include "stdafx.h"
#include "comcat.h"

// Helper function to create a component category and associated
// description
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)
{
        ICatRegister* pcr = NULL ;
        HRESULT hr = S_OK ;

        hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
                                           NULL,
                                           CLSCTX_INPROC_SERVER,
                                           IID_ICatRegister,
                                           (void**)&pcr);
        if (FAILED(hr))
                return hr;

        // Make sure the HKCR\Component Categories\{..catid...}
        // key is registered
        CATEGORYINFO catinfo;
        catinfo.catid = catid;
        catinfo.lcid = 0x0409 ; // english

        // Make sure the provided description is not too long.
        // Only copy the first 127 characters if it is
        int len = wcslen(catDescription);
        if (len>127)
                len = 127;
        wcsncpy(catinfo.szDescription, catDescription, len);
        // Make sure the description is null terminated
        catinfo.szDescription[len] = '\0';

        hr = pcr->RegisterCategories(1, &catinfo);
        pcr->Release();

        return hr;
}

// Helper function to register a CLSID as belonging to a component
// category
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
// Register your component categories information.
        ICatRegister* pcr = NULL ;
        HRESULT hr = S_OK ;
        hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
                                           NULL,
                                           CLSCTX_INPROC_SERVER,
                                           IID_ICatRegister,
                                           (void**)&pcr);
        if (SUCCEEDED(hr))
        {
                // Register this category as being "implemented" by
                // the class.
                CATID rgcatid[1] ;
                rgcatid[0] = catid;
                hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
        }

        if (pcr != NULL)
                pcr->Release();

        return hr;
}



  위의 루틴의 내용을 이해하기 위해서 노력할 필요는 없다. 단지 "레지스트리에 clsid를 등록하는 함수구나"라고만 이해하고 넘어가기 바란다.



Test Control에 추가

App 파일(여기서는 Test.cpp)를 열어 다음과 같이 위에서 작성한 cathelp.h를 include한다.

#include "cathelp.h"

조금 아래에 다음과 같이 _tlid가 선언되어 있는 것을 볼 수 있을 것이다(_tlid에 할당된 값은 프로그램 마다 다르다).

const GUID CDECL BASED_CODE _tlid =
                { 0x9b548709, 0xc3df, 0x4956, { 0x9f, 0x65, 0x29, 0x28, 0xca, 0xbb, 0x6e, 0xc8 } };

바로 아래에 비슷한 3개를 더 등록해야 한다.

두 개는 다음과 같이 안정성을 보장하기 위해 예약된(고정된) clsid이고,

const CATID CATID_SafeForScripting     =
                {0x7dd95801,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
const CATID CATID_SafeForInitializing  =
                {0x7dd95802,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};

나머지 하나는 ctrl 파일(여기서는 testctrl.cpp)에 있는 다음과 같은 내용을 복사해 와서,

IMPLEMENT_OLECREATE_EX(CTestCtrl, "TEST.TestCtrl.1",
        0xd886696, 0xc7ce, 0x11d3, 0xa1, 0x75, 0x8, 0, 0x2b, 0xf1, 0x75, 0x7)

다음과 같이 변경(_ctlid 선언)하면 된다.

const GUID CDECL BASED_CODE _ctlid =
        {0xd886696, 0xc7ce, 0x11d3, 0xa1, 0x75, 0x8, 0, 0x2b, 0xf1, 0x75, 0x7}



이제 App 파일에 있는 다음과 같은 함수에 레지스트리 등록 루틴을 추가하면된다.
  

STDAPI DllRegisterServer(void)
{
        AFX_MANAGE_STATE(_afxModuleAddrThis);

        if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
                return ResultFromScode(SELFREG_E_TYPELIB);

        if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
                return ResultFromScode(SELFREG_E_CLASS);

        return NOERROR;
}




추가한 루틴은 다음과 같다.


  

STDAPI DllRegisterServer(void)
{
        AFX_MANAGE_STATE(_afxModuleAddrThis);

        if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
                return ResultFromScode(SELFREG_E_TYPELIB);

        if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
                return ResultFromScode(SELFREG_E_CLASS);

        if (FAILED( CreateComponentCategory(CATID_SafeForScripting, L"Controls that are safely scriptable") ))
                return ResultFromScode(SELFREG_E_CLASS);

        if (FAILED( CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data") ))
                return ResultFromScode(SELFREG_E_CLASS);

        if (FAILED( RegisterCLSIDInCategory(_ctlid, CATID_SafeForScripting) ))
                return ResultFromScode(SELFREG_E_CLASS);

        if (FAILED( RegisterCLSIDInCategory(_ctlid, CATID_SafeForInitializing) ))
                return ResultFromScode(SELFREG_E_CLASS);

        return NOERROR;
}




위 내용 또한 그대로 사용하면 되므로 이해하기 위해서 너무 많은 노력을 들이지는 말기 바란다.

컴파일을 하고 실행을 하면 보안 대화 상자가 생성되지 않고 잘 동작된다는 것을 알 수 있다.

'Program Visual C++' 카테고리의 다른 글

RichEdit 관련  (0) 2008.02.29
VC++ UNICODE Build - Configuration  (0) 2007.07.12
Tray  (0) 2007.05.21
COblist is not safe on Thread  (0) 2007.04.16
GetPrivateProfileString() WritePrivateProfileString()  (0) 2007.04.03

Tray

Program Visual C++ 2007. 5. 21. 16:06 Posted by HisPark
고수닷넷에 있는 내용입니다.(회원가입을 해야 해서...)

http://www.gosu.net/GosuWeb/Article-detail.aspx?ArticleCode=368

1. 트레이 통지와 관련된 함수와 파라미터
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: 아이콘의 툴팁을 위한 텍스트.
2. 트레이에 아이콘 추가
NOTIFYICONDATA    nid;

// 구조체 초기화
ZeroMemory(&nid, sizeof nid);

// 구조체 설정
nid.cbSize = sizeof nid;
nid.hWnd = hWnd;
nid.uID = ICON_ID;
nid.uFlags = NIF_TIP | NIF_ICON | NIF_MESSAGE;
nid.uCallbackMessage = WM_MESSAGE;
nid.hIcon = hSmallIcon;
lstrcpy(nid.szTip, "Sample");

// 트레이 영역에 추가
Shell_NotifyIcon(NIM_ADD, &nid);

3. 트레이 아이콘 제거
제거시에는 hWnd와 uID멤버만 셋팅하면 됩니다.

NOTIFYICONDATA    nid;

ZeroMemory(&nid, sizeof nid);

nid.cbSize = sizeof nid;
nid.hWnd = hWnd;
nid.uID = ICON_ID;

Shell_NotifyIcon(NIM_DELETE, &nid);

4. 트레이로 부터의 메시지 수신
마우스와 관련된 메시지만 통지합니다.

wParam : 등록시에 설정한 ID(nid.uID).
lParam : 메시지 종류 (WM_LBUTTONUP, ...).
case WM_MESSAGE:
    if(wParam == ICON_ID)
    {
        switch(lParam)
        {
            case WM_RBUTTONUP:
                // 처리
                break;
        }
    }

    break;

5. Context메뉴
일반적으로 트레이에서 오른쪽 버튼을 누르면 context 메뉴를 화면에 표시합니다. 아래는 그러한 일을 하는 코드의 일부입니다.

POINT pt;
GetCursorPos(&pt);

SetForegroundWindow(hWnd);
TrackPopupMenu(menu, TPM_LEFTALIGN, pt.x, pt.y, 0, hWnd, NULL);
PostMessage(hWnd, WM_NULL, 0, 0);

주의할 점은 TrackPopupMenu 앞에 SetForegroundWindow API 를 호출해 주고, 후에 WM_NULL 메시지를 포스트 해주어야 합니다. 그렇지 않을 경우 메뉴가 화면에서 사라지지 않는 버그 현상이 생기게 됩니다.

6. For MFC.
아래는 MFC에서 일반적으로 하게 되는 트레이 작업 영역에 추가 및 삭제를 위한 코드의 일부입니다.

6.1 추가
#define WM_TRAYNOTIFY WM_APP + 1

NOTIFYICONDATA    nid;

::ZeroMemory(&nid, sizeof nid);

nid.cbSize        = sizeof nid;
nid.hIcon        = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
nid.hWnd        = this->m_hWnd;
nid.uID            = IDR_MAINFRAME;
nid.uFlags        = NIF_TIP | NIF_ICON | NIF_MESSAGE;
nid.uCallbackMessage    = WM_TRAYNOTIFY;

lstrcpy(nid.szTip, "Test");

::Shell_NotifyIcon(NIM_ADD, &nid);

6.2 제거
NOTIFYICONDATA    nid;

::ZeroMemory(&nid, sizeof nid);

nid.cbSize    = sizeof nid;
nid.uID        = IDR_MAINFRAME;
nid.hWnd    = this->m_hWnd;

::Shell_NotifyIcon(NIM_DELETE, &nid);

6.3 메시지 처리
ON_MESSAGE(WM_TRAYNOTIFY, OnTrayNotify)

LONG TestDlg::OnTrayNotify(WPARAM wParam, LPARAM lParam)
{
    CMenu    menu, *pTrayMenu;
    CPoint    pt;

    if(wParam == IDR_MAINFRAME)
    {
        switch(lParam)
        {
        case WM_RBUTTONUP:
            menu.LoadMenu(IDR_TRAYMENU);
            pTrayMenu = menu.GetSubMenu(0);

            ::GetCursorPos(&pt);

            SetForegroundWindow();
            pTrayMenu->TrackPopupMenu(TPM_LEFTALIGN, pt.x, pt.y, this, NULL);
            SetForegroundWindow();

            pTrayMenu->DestroyMenu();
            menu.DestroyMenu();
            break;

        case WM_LBUTTONDBLCLK:
            if(!IsWindowVisible())
                ShowWindow(SW_SHOW);

            SetForegroundWindow();
            break;
        }
    }

    return 0;
}

'Program Visual C++' 카테고리의 다른 글

VC++ UNICODE Build - Configuration  (0) 2007.07.12
ActiveX 보안관련 설정  (0) 2007.05.25
COblist is not safe on Thread  (0) 2007.04.16
GetPrivateProfileString() WritePrivateProfileString()  (0) 2007.04.03
Invoke 오버라이드  (0) 2007.03.29