C++小案例分享 : 兩支視窗程式單向傳遞訊息 (Transferring message from a program to the other)

本文展示以C++ (Borlad C++ Cuilder 6) 設計兩支視窗程式單向傳遞訊息的作法 — prg1傳訊息給prg2。

This article is presenting how to design two programs within BCB to let one can transfer message to the other.

1__僅prg1傳給prg2_run

第一支程式 :prg1視窗畫面:(The Form of the first program : prg1.exe)

1__僅prg1傳給prg2_prg1視窗

prg1程式碼:

程式檔:Unit1_prg1.cpp (僅關鍵內容)

//---------------------------------------------------------------------------
#include "fstream.h"
HANDLE prg2Handle;
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn2Click(TObject *Sender)
{
  // SendMessage 傳送下欄字串訊息給prg2
  prg2Handle = FindWindow("TForm1","prg2");
  if (prg2Handle == NULL){
    ShowMessage("! prg2尚未執行喔 !");
  }
  else{ 
    char Msg[255];
    sprintf(Msg,"%s",FormatDateTime("hh:nn:ss:z",Now())+" 從prg1: "+Edit1->Text.Trim());
    COPYDATASTRUCT *pcp = new COPYDATASTRUCT;
    pcp->dwData = 0;
    pcp->cbData = sizeof(Msg);
    pcp->lpData = &Msg;
    SendMessage(FindWindow("TForm1","prg2"),WM_COPYDATA, (WPARAM)NULL, (LPARAM)pcp);
    delete pcp;
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
  // 執行prg2
  prg2Handle = FindWindow("TForm1","prg2");
  if (prg2Handle == NULL){ //若prg2尚未執行則執行之
    WinExec((ExtractFilePath(Application->ExeName)+"\\prg2").c_str(),SW_SHOW);
    prg2Handle = FindWindow("TForm1","prg2"); //再檢查prg2的執行狀態
    if (prg2Handle == NULL)
      ShowMessage("! 找不到或是無法執行 prg2 喔 !");
  }
  else
    ShowMessage("* prg2 已在執行中 *");
}
//---------------------------------------------------------------------------

第二支程式 :prg2視窗畫面:(The Form of the second program : prg2.exe)

1__僅prg1傳給prg2_prg2視窗

prg2程式碼:

程式檔:Unit1_prg2.h (僅關鍵內容)

//---------------------------------------------------------------------------
class TForm1 : public TForm
{
  protected:
  /* --- VCL_MESSAGE_HANDLER ---
  This macro can be used to redefine message handlers for events. 
  VCL_MESSAGE_HANDLER is defined for compliance when the ATL library is
  used. The ATL also declares a MESSAGE_HANDLER macro and 
  the VCL_MESSAGE_HANDLER rename prevents a naming conflict. 
  If the ATL library is not being used, the macro name reverts to 
  MESSAGE_HANDLER.
  英文解說出自: http://docwiki.embarcadero.com/RADStudio/Seattle/en/MESSAGE_HANDLER
  因為ATL中同樣包含了一個MESSAGE_HANDLER的宏定義,這與VCL發生了衝突。
  為了解決這個問題,Borland改用VCL_MESSAGE_HANDLER這樣的寫法。
  當您沒有使用ATL的時候,MESSAGE_HANDLER將轉換成VCL_MESSAGE_HANDLER。
  如果您使用了ATL的話,就會有問題。所以建議始終使用VCL_MESSAGE_HANDLER的寫法,
  以免出現問題。
  中文解說出自: http://dascan.pixnet.net/blog/post/15460182-vcl%E6%B6%88%E6%81%AF%E6%A9%9F%E5%88%B6
  */
  BEGIN_MESSAGE_MAP
    VCL_MESSAGE_HANDLER(WM_COPYDATA, TMessage, getmsg)
  END_MESSAGE_MAP(TForm)
  void __fastcall getmsg(TMessage & Msg);
};
//---------------------------------------------------------------------------

程式檔:Unit1_prg2.cpp (僅關鍵內容)

//---------------------------------------------------------------------------
#include "fstream.h"
//---------------------------------------------------------------------------
void __fastcall TForm1::getmsg(TMessage & Msg)
{
  PCOPYDATASTRUCT pcp;
  pcp = (PCOPYDATASTRUCT)Msg.LParam;
  char* TraceMsg;
  TraceMsg = (char*)pcp->lpData;
  String STRTEMP=TraceMsg;
  Memo1->Lines->Add(STRTEMP);
}
//---------------------------------------------------------------------------

本文程式碼原始檔及展示檔在此

Tagged: ,

發表留言