cppBuilder
Primer
appOperation
windowMessage
appComm

C++ Builder XE4, 10.2 Tokyo > Window Message > 他のアプリに数値を送る > 2つのアプリの実装


動作環境

C++ Builder XE4

Rad Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)


したいこと

あるアプリから別のアプリに数値を送りたい。

以下の例では


  • 子アプリ : カウントダウン

  • 親アプリ : 子アプリへのカウントのフィード

を行う。


参考

(追記 2018/10/24)

下記、VisualStudioのドキュメントであるようだが。。。

static CWnd* PASCAL FindWindow(

LPCTSTR lpszClassName,
LPCTSTR lpszWindowName
);

(下記、強調部分はこちらで強調)


lpszClassName

ウィンドウ クラスの名前 ( WNDCLASS の構造) を指定する NULL で終わる文字列へのポインター。 lpClassName が nullの場合、すべてのクラス名に一致します


「すべてのクラス名に一致」、つまり、起動中のソフトウェア全てが対象になる、

という理解。


子アプリ (Receiver)


UnitReceiver.h

//---------------------------------------------------------------------------

#ifndef UnitReceiverH
#define UnitReceiverH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------

#define WM_IDX (0) // WM_APPに足して使用する

class TForm2 : public TForm
{
__published: // IDE で管理されるコンポーネント
TLabel *L_countDown;
TTimer *Timer1;
void __fastcall Timer1Timer(TObject *Sender);
private: // ユーザー宣言
public: // ユーザー宣言
__fastcall TForm2(TComponent* Owner);
void __fastcall ReceiveContinue(TMessage & msg);

BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_APP + WM_IDX, TMessage, ReceiveContinue);
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
#endif



UnitReceiver.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "UnitReceiver.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------

static int s_currentValue = 20;

static const int kKeyValue = 31415;

__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Timer1Timer(TObject *Sender)
{
s_currentValue--;

L_countDown->Caption = IntToStr(s_currentValue);
}
//---------------------------------------------------------------------------

void __fastcall TForm2::ReceiveContinue(TMessage & msg)
{
UINT keyval = msg.WParam;
LONG continueCount = msg.LParam;

if (keyval != kKeyValue) {
return;
}

s_currentValue = s_currentValue + continueCount;
}



親アプリ (Sender)


UnitSender.cpp

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "UnitSender.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

#define WM_IDX (0) // WM_APPに足して使用する
static const int kKeyValue = 31415;

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HWND hChild;

hChild = FindWindow(NULL, L"Form2");
if (hChild == NULL) {
return;
}

#if 1
SendMessage(hChild, WM_APP + WM_IDX, kKeyValue, 20);
#else
PostMessage(hChild, WM_APP + WM_IDX, kKeyValue, 20);
#endif

int nop = 1;
}
//---------------------------------------------------------------------------


SendMessage()する時、FindWindow()を前にしないといけないようだ。


子アプリは実行してからカウントダウンしていく。

親アプリ側でボタンを押すと、子アプリ側のカウントが20追加される。

他のアプリを自動終了させる仕組みを考えていて、これが必要になった。

ソフト起動時にカウントダウンの上限を指定しておき、0以下になった時に終了する。

何か作業をした時に、カウントを増やすか初期値に戻す。