본문 바로가기
[ Program ]/자체숙제프로젝트

1-6. 나에게 윈도우메세지전송2 (문자열)

by 관이119 2013. 12. 18.

 

저번에 간단한 값을 윈도우 메세지 전송을 해봤으니 이번에는 나에게 문자열을 보내 봅시다!

 

프로그램간 데이터 전송할려다가 삼천포로 계속 빠지고 있지만 이렇게 해야됩니다!

 

공부하는거니깐요~

 

 

일단 저번에 만들어 놨던 걸 열어 봅시다.

 

 

요렇게 기존에는 간단한 숫자만 전송 했습니다.

 

문자열을 전송해봅시다! 두둥!

 

 

//SendMessage(WM_TEST_MESSAGE, 100, 200);

 CEdit *editbox =(CEdit *)GetDlgItem(IDC_EDIT1);
 
 CString str;
 editbox ->GetWindowText(str);

 char tempar[1024] = {0,};
 strcpy_s(tempar,str);
   
    HWND hWnd = ::FindWindow(NULL, CString("TestTrans"));
    if (hWnd)
    {
  COPYDATASTRUCT cpd;
  cpd.dwData = 0;
  cpd.cbData = sizeof(str);//str.GetLength();
  cpd.lpData = (void*)str.GetBuffer(cpd.cbData);
  ::SendMessage(hWnd, WM_COPYDATA, (WPARAM)::GetDesktopWindow(), (LPARAM)&cpd);
 }

 /*
 -Question
  Does someone know what the difference is between GetWindowTextA and GetWindowText? What is the letter 'A'?

 -Anser
  GetWindowText is a preprocessor define:
  i.e.
  #define GetWindowText GetWindowTextA
  in a non-Unicode build, GetWindowText and GetWindowTextA are the same thing. 
  In a Unicode build, GetWindowText is defined as GetWindowTextW. 
  All Windows API functions that take strings as parameters have two versions,
  an "A" version (ANSI) and a "W" version (Wide). 
  The "A" version takes char *, and the "W" version takes a wchar_t *
 */

 /*
 -Question
  Can someone explain what PVOID is and how it is used in a function like:
  BOOL DoSomething(PVOID pMemPhy)

 -Anser
  void pointer, same as
  void *pMemPhyaka "Pointer to something, but it's up to you to figure it out".
  BOOL DoSomething ( PVOID pMemPhy )
  {
   strcpy((char *)pMemPhy, "I love buffer overflows!");
   return TRUE;
  }
 */

 

위사진에 있는 소스 코드입니다.

일단 아래 두개는 다른데서 설명 찾아서 붙여놓은거라서 일단 무시해봅시다.

 

//SendMessage(WM_TEST_MESSAGE, 100, 200);

 CEdit *editbox =(CEdit *)GetDlgItem(IDC_EDIT1);
 
 CString str;
 editbox ->GetWindowText(str);

 char tempar[1024] = {0,};
 strcpy_s(tempar,str);
   
    HWND hWnd = ::FindWindow(NULL, CString("TestTrans"));
    if (hWnd)
    {
  COPYDATASTRUCT cpd;
  cpd.dwData = 0;
  cpd.cbData = sizeof(str);//str.GetLength();
  cpd.lpData = (void*)str.GetBuffer(cpd.cbData);
  ::SendMessage(hWnd, WM_COPYDATA, (WPARAM)::GetDesktopWindow(), (LPARAM)&cpd);
 }

 

위쪽내용만 떼냈습니다.

이렇게 해도 무슨내용인지 하나도 알수 없습니다.

하나씩 차근차근 살펴봅시다.

 

CEdit *editbox =(CEdit *)GetDlgItem(IDC_EDIT1);

 

CString str;
 editbox ->GetWindowText(str);

 

이부분은 저번에 한적이 있습니다.

에디트박스의 텍스트를 가져오는 부분입니다.

 

그바로 아래줄의 요두개는 제가 보낼값이 잘들어가나 디버깅해서 테스트 해볼려고 넣은 내용이라서 무시하셔도 됩니다.

내용은 그냥 단순히 문자열 배열에 위 str 의 내용을 복사하는 내용입니다.

char tempar[1024] = {0,};
 strcpy_s(tempar,str);

 

자그럼 위쪽 내용은 이해가 되고 이제 요거 남았습니다.

 

HWND hWnd = ::FindWindow(NULL, CString("TestTrans"));
    if (hWnd)
    {
  COPYDATASTRUCT cpd;
  cpd.dwData = 0;
  cpd.cbData = sizeof(str);//str.GetLength();
  cpd.lpData = (void*)str.GetBuffer(cpd.cbData);
  ::SendMessage(hWnd, WM_COPYDATA, (WPARAM)::GetDesktopWindow(), (LPARAM)&cpd);
 }

 

무슨내용인고 하니

저번포스팅중에 spy++ 사용하는 법을 설명 했었습니다.

그걸로 현재 우리가 테스트 중인 프로그램의 캡션을 보면 TestTrans 이라고 나옵니다.

꼭 spy++ 에서 안봐도 창타이틀에 보면 그렇게 나와있긴합니다 ^^;;;

아무튼!

HWND hWnd = ::FindWindow(NULL, CString("TestTrans"));

요부분은 TestTrans 인 이름을 가지는 윈도우창의 핸들을 가져와라! 이말입니다.

( 핸들은 쉽게 생각해서 대상에 접근할수있는 주소입니다.)

 

그러면  if (hWnd)  이부분은 핸들이 존재하면 이라고 읽으시면 되겠고..

그다음은

COPYDATASTRUCT cpd;
  cpd.dwData = 0;
  cpd.cbData = sizeof(str);//str.GetLength();
  cpd.lpData = (void*)str.GetBuffer(cpd.cbData);

 

COPYDATASTRUCT 형태의 구조체를 정의 하는 부분입니다.

cbData 에 사이즈를 넣고

lpData 에 데이터를 넣습니다.

참고로 cbData에 사이즈를 잘못지정하면 받는부분에서 쓰레기값이 넘어옵니다!

 

그리고나서

::SendMessage(hWnd, WM_COPYDATA, (WPARAM)::GetDesktopWindow(), (LPARAM)&cpd);

 

메세지를 보내는데!

저번과 다르게 :: 이 붙었습니다.

이건 사실 저도 내용을 아직은 잘모르겠습니다.

대충 여기저기서 읽은내용은 지역변수를 사용할때 :: 을 쓴다고 하는데 일단 넘어가고 따로 또 공부 하겠습니다.

일단 내용은 http://stackoverflow.com/questions/11442293/when-to-use-and-when-to-use 

여기에서 참조 할수 있습니다.

그리고 난데없이 WM_COPYDATA 라는걸 사용하는데

이건 COPYDATASTRUCT  구조체를 보낼때 사용하는 전용이름표라고 생각하시면 되겠습니다.

 

그리고 세번째 인자에 (WPARAM)::GetDesktopWindow() 이렇게 보내는데 이거도 사실 잘모르겠습니다.

이건 NULL 로 해도 정상적으로 넘어가니 일단 이렇게 쓰고 나중에 내요을 찾아 보기로 하겠습니다.

그리고 마지막으로 대망의 COPYDATASTRUCT 구조체를 4번째로 넘겨 줍니다.

 

자 이제 엉성하지만 보내는 내용은 완성입니다!

밑에 /* */ 로 감싸놓은 주석은 공부하면서 찾아놓은 내용인데 그냥 한번 읽어보고 넘어가시면 되겠습니다(?)

 

 

그림도없이 너무 긴내용을 써놔서 일일이 다 찾고 설명하다가는 제가 지루해서 안되겠습니다!

 

 

이제 받는 내용을 만들어 봅시다.

 

 

앞에서 한번 똑같이 해봤으니 세세하게 설명 안하겠습니다!

 

TestTransDlg.h 로 가서 아래 내용을 추가해 줍시다.

LRESULT ReceiveData(WPARAM wParam, LPARAM lParam);

 

 

 

그리고 이전에 했던대로 원래 Dlg 파일로 돌아와서

MessageMap 에서도

ON_MESSAGE(WM_COPYDATA, ReceiveData)

요렇게 추가해 줍시다.

 

 

 

그러면 실제 ReceiveData 함수를 추가해줘야 겠죠?

 

LRESULT CTestTransDlg::ReceiveData(WPARAM wParam, LPARAM lParam)
{

 COPYDATASTRUCT *pCDS = (COPYDATASTRUCT*)lParam;

 CString str;
    str = (LPCSTR)pCDS->lpData;
 
 char tempar[1024] = {0,};

 strcpy_s(tempar,str);

    MessageBox(tempar, _T("메시지 확인"), MB_OK);

 return 0;
}

 

요렇게 끝부분에 추가해줍시다.

그리고 나서 실행하면!

 

 

 

요렇게 입력한 값을 메세지박스로 띄울수 있습니다.

 

이번에는 설렁설렁 넘어간 내용이 많은데 저도 찾아보고 공부하면서 한다고 제대로 이해안된 내용들도 많이 있습니다.

차차 프로젝트를 진행하면서 알아 가기로 하고 요정도에서 일단 문자전송은 끝내겠습니다!

 

댓글