네 보기 좋다하여 꺾지 말아라

[MFC] SendMessage 본문

프로그래밍/MFC

[MFC] SendMessage

선제 2011. 10. 27. 16:37
클래스간 데이터 전달을 하는 방법이 무엇이 있을까.

1. 전역변수
2. 헤더 include 후 변수 접근
3. SendMessage

SendMessage를 이용하면 클래스간 데이터 전달이 용이함을 알고, 사용해보았다(몇번의 삽질과 함께...)

LRESULT SendMessage(
	UINT message,
	WPARAM wParam = 0,
	LPARAM lParam = 0
) throw();

static LRESULT SendMessage(
	HWND hWnd,	
	UINT message,		// 메시지 이름
	WPARAM wParam,	// 정수형 포인터 전달인자
	LPARAM lParam		// 실수형 포인터 전달인자
) throw();

주로 static을 쓰게 될텐데...

선언해주어야 하는 파트는 3파트.

1. 메시지 등록
- '이런 메시지를 쓰겠습니다.' 하는 부분 
        - 메시지 등록은 이 메시지를 받을 곳 메시지 맵에 등록을 한다. 던져줬는데 받는놈이 뭔지 모르면 그건 스팸일테니... 매시지 맵의 역할에 대해서는 따로 공부..
 
        ex) BEGIN_MESSAGE_MAP(CsendMessageDlg, CDialog)
ON_MESSAGE(메시지 구별자, 처리함수)
      END_MESSAGE_MAP()
 
2. 처리함수 정의
- 위의 처리함수를 정의하는 부분.
 
3. 메시지 전달
- 메시지를 전달하는 부분
ex) ::SendMessage(전달 받을 곳의 핸들(받는사람) , 메시지 구별자, 전달인자1, 전달인자2);
 


흐름

SendMessage - 받는 핸들 찾음 - 처리 함수 호출



#sendMessageDlg.cpp // 부모 Dialog
BEGIN_MESSAGE_MAP(CsendMessageDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDOK, &CsendMessageDlg::OnBnClickedOk)
	ON_BN_CLICKED(IDC_BUTTON1, &CsendMessageDlg::OnBnClickedButton1)
	ON_MESSAGE(UM_TEST_SENDMESSAGE, &CsendMessageDlg::sets)	// 1. 메시지 등록
END_MESSAGE_MAP()

LRESULT	CsendMessageDlg::sets(WPARAM wParam, LPARAM lParam)	// 2. 처리함수 정의
{
	CString *data = (CString*)lParam; 
        // 이렇게 받아옴. 왜냐하면 lParam 은 포인터니까!! CString을 넘긴 주소를 가리키고 있다.
	::MessageBox(NULL, _T("asdf"), (LPCWSTR)data, MB_OK); // 이건 그냥 확인용
}


#Modaless.h
#define UM_TEST_SENDMESSAGE	WM_USER +1	// 메시지 구별자 등록


#Modaless.cpp
// 자식 Dialog
BOOL CModaless::OnInitDialog()
{
	CDialog::OnInitDialog();
	CString *str = new CString("asdf");
	::SendMessage(((CSendMessageDlg*)GetParent())->GetSafeHwnd(), UM_TEST_SENDMESSAGE, 0, (LPARAM)str);
        // ((CSendMessageDlg*)GetParent())->GetSafeHwnd() : 상위 Dialog의 핸들을 가져옴
        // 만약 하위 Dialog에게 보내려면 하위 Dialog의 객체에 sendMessage를 던져주면된다.
        // 그땐 주소(hWnd가 필요없다. :D)
	// 3. 메시지 전달
	return TRUE;
}


여기에서 보면 가장 중요한 부분이 SendMessage 부분인것 같다.

첫번째 전달인자는 받을 클래스의 핸들러가 들어간다. 즉, 받는사람 주소인 셈.
나는 부모 다이얼로그에 전달하기위해서 getparent를 이용해서 핸들러를 받아왔다.

전달인자는 WPARAM 과 LPARAM.
둘다 dword 형으로
WPARAM은 UINT, LPARAM은 LONG 형으로 각각 정수형, 실수형 포인터이다.

끗.

PS. 위 내용은 단순히 라이브러리를 어떻게 쓰는지에 대한 방법을 적은 것이다.
후에 꼭, SendMessage와 PostMessage에 대한 이해를 하는것이 중요하다.

라이브러리를 쓰는 개발자보다는 라이브러리를 만들 수 있는 개발자가 되자.

'프로그래밍 > MFC' 카테고리의 다른 글

[MFC] 포인터 해제?  (0) 2011.11.14
[MFC Dialog] PreTranslateMessage  (0) 2011.10.27
[MFC] SendMessage  (4) 2011.10.27
[MFC Dialog] OnKeyDown message  (0) 2011.10.27
[MFC Dialog] TreeCtrl에 더블클릭 이벤트 주기 ON_NOTIFY  (0) 2011.10.19
[MFC Dialog 메신져] TreeCtrl 탐색  (0) 2011.10.18
4 Comments
  • 좋은내용 2013.12.05 13:40 좋은 내용입니다. 제 블로그로 가져가겠습니다.
  • hyeonk 2014.01.07 16:27 신고 퍼갑니다~
  • 돌고돌아 2014.08.08 16:27 자식 Dialog 에서 아래와 같이 동적 할당한 것을 어디에서 어떻게해야 하는지요?
    CString *str = new CString("asdf");

    부모 Dialog에서 자식에게 또 해제하라는 메세지를 보내야 하나요?
  • 선제 2014.08.24 22:27 신고 C++를 안한지가 오래되어서 정확한 답을 드리기는 어렵지만
    프로그래밍에서 공통으로 통하는건 '결자해지' 인것 같습니다.

    포인터라는건 결국 힙을 공통으로 사용하는 거지만 될 수 있으면 생성한 클래스에서 해제해주는것이 좋은것 같습니다.

    결과적으로 말씀하신것처럼 풀어주시면 될 것 같습니다.

    자식 class가 소멸할때 플래임워크에서 호출되는 메소드가 없다면 명시적으로 소멸할때 해당 클래스가 생성한 메모리를 반환하는 함수를 사용하는것이 좋을 것 같습니다.
댓글쓰기 폼