動作環境
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以下になった時に終了する。
何か作業をした時に、カウントを増やすか初期値に戻す。