C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 자료실
C++Builder Programming Resources
[516] WM_COPYDATA를 사용한 C++빌더에서 두개의 application 간 메시지 교환 방법
비베시러 [] 18290 읽음    2010-01-28 23:17
C++빌더에서 두개의 application 간 메시지 교환 방법에 대한 내용입니다.
WM_COPYDATA를 사용하였습니다.
비주얼C++에는 많은 자료가 있는데, 찾아보니 없는것 같아
박지훈님의 도움을 받아 작성하였습니다.
도움을 받은 것이니 아낌없이 공개합니다.

제가 내공이 많지 않아 설명이나 주석등 내용에 오류가 있을 수 있는데,
많이 아시는 분들이 댓글로 수정해주시면 영광이겠네요.

앞으로는 씨빌더도 많은 자료들이 넘쳐나길 바랍니다.

쓰면쓸수록 좋은 툴인것 같은데.....실력이 없어 참 아쉬움이 많습니다.

송신부

1.  통신으로 주고 받을 자료 형 선언

mJigNum     : 지그 번호 Index
mData     : 예비
sData        : 전달 해줄 String 데이터

typedef struct DataInfo{
  int mJigNum;
  int mData;
  char sData[100];
}DINFO, *PINFO;


2. 송신 할 부분에서 하기와 같이 처리한다.
  DINFO myInfo;
  //------------------
  // 송신 데이터 입력
  //------------------
  myInfo.mJigNum =1;
  myInfo.mData =0;
  strcpy(myInfo.sData,"TEST PROGRAM");

  // WM_COPYDATA 메시지를 이용하기 위해서는
  // COPYDATASTRUCT에 값을 실어서 보내고 받는다.
  COPYDATASTRUCT copyData;
  copyData.dwData = 333;    // 임의의 Index임
  copyData.cbData = sizeof(myInfo);
  copyData.lpData = &myInfo;

  // 수신 윈도우 핸들 찾기
  HWND  hTarWnd = FindWindow(NULL, TEXT("Server") );

  // hTarWnd : 보낼 윈도우 핸들
  // Handle   : 내 프로그램 핸들
  SendMessage( hTarWnd, WM_COPYDATA, (WPARAM)Handle, (LPARAM) ©Data);


3. Target의 윈도우 핸들을 얻기 위해 해당 프로그램의 caption 정보를 알아야 한다.
4. SendMessage후 Target에서 메시지를 받았는지 확인 하는 방법 ?

dwData는 임의의 값으로 사용하고, lpData형은 전송될 데이터를 사용자 자료형에 넣고, 이를 lpData에 어드레스를 실어서 SendMessage로 보낸다. cbData는 사용자 자료형의 크기를 넣어 준다.

typedef struct DataInfo{
  int mJigNum;
  int mData;
  char sData[100];
}DINFO, *PINFO;


myInfo.mJigNum =1;
  myInfo.mData =0;
  strcpy(myInfo.sData,"TEST PROGRAM");


COPYDATASTRUCT copyData;
  copyData.dwData = 333;
  copyData.cbData = sizeof(myInfo);
  copyData.lpData = &myInfo;

 
  // 수신 윈도우 핸들 찾기
  HWND  hTarWnd = FindWindow(NULL, TEXT("Server") )
   
   
//메시지 전송
SendMessage( hTarWnd, WM_COPYDATA, (WPARAM)Handle, (LPARAM) ©Data);




수신부

1.  통신으로 주고 받을 자료 형 선언

typedef struct DataInfo{
  int mJigNum;
  int mData;
  char sData[100];
}DINFO, *PINFO;


2. 클래스 선언부에 윈도우 메시지 맵 선언
   비주얼 C++의 경우 Class Wizard를 이용하고, BCB의 경우 코드레벨에서 입력해준다.

BEGIN_MESSAGE_MAP
   // WM_COPYDATA에 대한 메시지 맵 작성
   // TMessage를 사용한다.
   VCL_MESSAGE_HANDLER(WM_COPYDATA, TMessage, GetCopyData );
END_MESSAGE_MAP(TForm);


3. 해당 처리 함수 선언


  void __fastcall GetCopyData(TMessage &Msg);



4. 메시지 처리 함수에서 처리


void __fastcall TForm1::GetCopyData(TMessage &Msg)
{
  Print("Message Received");

  // copy할 데이터 구조체
  DINFO myInfo;

  // 메시지 송수신 구조체
  COPYDATASTRUCT *pCopyData;

  // Msg의 인자중 LParam이 수신 정보이므로, 이것을 가르킨다.
  // WM_COPYDATA를 사용하므로, COPYDATASTRUCTURE가 이것을 가르키게 한다.

  pCopyData = (COPYDATASTRUCT*) Msg.LParam;   // LParam(copydata)를 가르킨다.

  //  COPYDATASTRUCT의 3개 멤버 변수로 access

  int dwdata = pCopyData->dwData;
  Print( "dwdata DATA = ", dwdata );

  int cbdata = pCopyData->cbData;
  Print( "CB DATA = ", cbdata );

  //  COPYDATASTRUCT의 3개 멤버 변수 중
  // lpdata가 string값을 저장했으므로, 이것을 가르킨다.
  // 구조체로 만들었기 때문에 (순서대로 꺼내오기 위해서)

  PINFO cpInfo = (PINFO)pCopyData->lpData;
  int JigNum = cpInfo->mJigNum;
  Print( "JIG NUM= ", JigNum );
  int mData = cpInfo->mData;
  Print( "mData NUM= ", mData );
  AnsiString  sData = cpInfo->sData;
  Print( "sData = " + sData );
}



메시지 처리함수는 인자로 TMessage형을 받으며, 정의는 하기와 같다. 데이터를 담아서 보내는 파라미터는 LParam이며, WM_COPYDATA 메시지를 사용할 경우에는 COPYDATASTRUCT 구조체를 사용해야 한다.

struct TMessage
{
    Cardinal Msg;
    union
    {
        struct
        {
            Word WParamLo;
            Word WParamHi;
            Word LParamLo;
            Word LParamHi;
            Word ResultLo;
            Word ResultHi;
           
        };
        struct
        {
            int WParam;
            int LParam;
            int Result;
        };
       
    };
      } ;



typedef struct tagCOPYDATASTRUCT {  // cds 
    DWORD dwData;
    DWORD cbData;
    PVOID lpData;
} COPYDATASTRUCT;

dwData
Specifies up to 32 bits of data to be passed to the receiving application.
cbData
Specifies the size, in bytes, of the data pointed to by the lpData member.
lpData
Points to data to be passed to the receiving application. This member can be NULL.


메시지 처리 함수의 인자인 Msg의 Msg.LParam을 COPYDATASTRUCTURE가 가르키도록 하고


pCopyData = (COPYDATASTRUCT*) Msg.LParam;   // LParam(copydata)를 가르킨다.



COPYDATASTRUCTURE 구조체의 멤버 변수는 하기의 방법으로 Access 한다.

  int dwdata = pCopyData->dwData;
  Print( "dwdata DATA = ", dwdata );

  int cbdata = pCopyData->cbData;
  Print( "CB DATA = ", cbdata );

  //  COPYDATASTRUCT의 3개 멤버 변수 중
  // lpdata가 string값을 저장했으므로, 이것을 가르킨다.
  // 구조체로 만들었기 때문에 (순서대로 꺼내오기 위해서)


사용자 정의 메시지를 얻기 위해서 하기의 방법을 이용한다.
COPYDATASTRUCT 포인터 변수를 이용해 사용자 정의 메시지 구조체로 접근한다.


PINFO cpInfo = (PINFO)pCopyData->lpData;


  PINFO cpInfo = (PINFO)pCopyData->lpData;
  int JigNum = cpInfo->mJigNum;
  Print( "JIG NUM= ", JigNum );
  int mData = cpInfo->mData;
  Print( "mData NUM= ", mData );
  AnsiString  sData = cpInfo->sData;
  Print( "sData = " + sData );

<<응용 프로그램 예>>

송신부
수신부
박영목.월천 [gsbsoft]   2010-02-28 20:24 X
간단히 사용할 때 유용하지요. 저도 현재 이 부분 하고 있습니다.
필요해서...  웹하드 할 때도 한번 사용했는 데...

SendMessage 이 놈은 저는 잘 사용하지 않습니다. 응답 올 때까지...

기다리지요... 그래서 대부분은  PostMessage를 사용하지요.

그런데 WM_COPYDATA는 SendMessage 아니면 안되지요.

그런데 문제는 윈도우 핸들은 있는 데 만약 혹 수신 프로그램이... 무한루프나

응답할 수 없는 상태로 되어 있다면 보내는 프로그램도 멈추어 버리는

현상이 일어나지요.

그래서 일정 시간 경과 후 빠져 나오는 놈으로...

LRESULT SendMessageTimeout( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT fuFlags, UINT uTimeout, PDWORD_PTR lpdwResult );


수신쪽도 그럴 경우는 드물지만...

값만 수신 받고 바로  BOOL ReplyMessage(LRESULT lResult); 을 사용해서

송신쪽에 잘 받았다는 리턴값을 보냅니다. 그러면 송신쪽은 바로 다음 일을 처리할 수

있겠지요...  PostMessage를 사용할 수 없으니... 최대한 Postic하게 사용합니다.

제가 WM_COPYDTA를 사용하는 방법이었습니다 ^^
크레브 [kkol]   2010-03-20 08:48 X
좋은 내용이군요.. 박 영목.월천님도 잘 지적해 주셨고요.
저희회사에서 WM_COPYDATA를 잘 사용하고 있습니다.

알고 보면 거의 대부분 많이 사용하고 있는 기능인데도 불구하고

초보자 분들은 모르기 때문에 못쓰는 경우도 있을것 같군요
그런 분들에게 많은 도움이 될것 입니다. ^^

+ -

관련 글 리스트
516 WM_COPYDATA를 사용한 C++빌더에서 두개의 application 간 메시지 교환 방법 비베시러 18290 2010/01/28
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.