0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

2017-10-31 C++ Builder XE4, 10.2 Tokyo > Form2からForm1の関数を実行する > Form2はUnit1.hをincludeしない > __closureの利用

Last updated at Posted at 2017-10-31
動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2018/01/05)

概要

  • Form1とForm2がある
  • Form2にてとある処理をすると、Form1に反映されるようにしたい
  • Form2においてUnit1.hをincludeしない
    • includeするとUnit1に依存して、Unit2の再利用性が低減する
      • 例: Unit3からUnit2の利用

前回

C++ Builder > Form2からForm1のボタンを押す > Form2はUnit1.hをincludeしない > TButtonのポインタを渡す
においてはTButtonのポインタを渡した。

Form1の関数を渡して、Form2からその関数をコールしたい。

__closureを使ってみた。

参考: https://stackoverflow.com/questions/19050077/why-is-this-function-pointer-failing

code

Unit1.h
//---------------------------------------------------------------------------

# ifndef Unit1H
# define Unit1H
//---------------------------------------------------------------------------
# include <System.Classes.hpp>
# include <Vcl.Controls.hpp>
# include <Vcl.StdCtrls.hpp>
# include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *Button1;
	TMemo *Memo1;
	void __fastcall FormShow(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
	void __fastcall SetXXX(void);
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
# endif
Unit1.cpp
//---------------------------------------------------------------------------

# include <vcl.h>
# pragma hdrstop

# include "Unit1.h"
# include "Unit2.h"
//---------------------------------------------------------------------------
# pragma package(smart_init)
# pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SetXXX(void)
{
	Memo1->Lines->Add(L"SetXXX");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
	Form2->SetFunction(SetXXX);

	Form2->Show();
}
//---------------------------------------------------------------------------
Unti2.h
//---------------------------------------------------------------------------

# ifndef Unit2H
# define Unit2H
//---------------------------------------------------------------------------
# include <System.Classes.hpp>
# include <Vcl.Controls.hpp>
# include <Vcl.StdCtrls.hpp>
# include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
class TForm2 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TButton *Button1;
	void __fastcall Button1Click(TObject *Sender);
private:	// ユーザー宣言
	TButton *m_buttonPtr;
	typedef void __fastcall (__closure *TMethod)(void);
	TMethod m_funcPtr;
public:		// ユーザー宣言
	void __fastcall SetFunction(TMethod ptr);

	__fastcall TForm2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm2 *Form2;
//---------------------------------------------------------------------------
# endif
Unit2.cpp
//---------------------------------------------------------------------------

# include <vcl.h>
# pragma hdrstop

# include "Unit2.h"
//---------------------------------------------------------------------------
# pragma package(smart_init)
# pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
	: TForm(Owner)
{
	m_buttonPtr = NULL;
	m_funcPtr = NULL;
}

void __fastcall TForm2::Button1Click(TObject *Sender)
{
	if (m_funcPtr == NULL) {
		return;
	}

	m_funcPtr();
}

void __fastcall TForm2::SetFunction(TMethod ptr)
{
	m_funcPtr = ptr;
}

実行

Form2上のボタンを押すとForm1の関数が実行されSetXXXが追記される。

qiita.png

はまった点

void __fastcallの関数を渡す場合は、__closureの定義もvoid __fastcallにしないといけない。

typedef void __fastcall (__closure *TMethod)(void);

__closureは使いこなしていないので、まだ間違っているかもしれない。

検索用キーワード

(2019-10-03追加)

  • 関数ポインタ
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?