동작이 가능하도록 약간 수정해 보았습니다.
THydro 에 parent 를 생성자에서 줄 수 있도록 코드를 추가했습니다.
실제로 메인Form에서 THydro를 만들게 되므로, parent와 owner가 같은 것이라
//---------------------------------------------------------------------------
//------- MainUnit.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MainUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Hydro = new THydro(this);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if(Hydro)
delete Hydro;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnEnableClick(TObject *Sender)
{
if(Hydro) Hydro->TimerEnable();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::btnDisableClick(TObject *Sender)
{
if(Hydro) Hydro->TimerDisable();
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// --------------------------------------------------
// THydro 의 Method
// --------------------------------------------------
__fastcall THydro::THydro(TComponent* Owner) // 생성자
:TWinControl(Owner)
{
TWinControl *cont = dynamic_cast<TWinControl *>(Owner);
if(cont)
SetParent(cont);
else
SetParent(NULL);
Timer = new TTimer(NULL);
Timer->OnTimer = OnTimer;
Timer->Enabled = false;
}
//---------------------------------------------------------------------------
THydro::~THydro()
{
if(Timer) {
TimerDisable();
Timer->OnTimer = NULL;
delete Timer;
}
}
//---------------------------------------------------------------------------
void THydro::OnMessage(TMessage &Message) // 이벤트 처리 Method
{
bool bResult = false;
EN_LOGGER_STEP enStep = (EN_LOGGER_STEP)Message.WParam;
UnicodeString MeasureDate, MeasureTime;
switch ( enStep ) {
case enIdle :
{
Form1->mo->Lines->Add("enStep Message checked");
// do sometihing..
}
break;
case enStart :
case enFinish :
break;
}
}
// ------------------------------------------------------------
void THydro::TimerEnable()
{
if(Timer) {
Timer->Interval = 1 * 1000; // every 1 second
Timer->Enabled = true;
}
}
// ------------------------------------------------------------
void THydro::TimerDisable()
{
if(Timer)
Timer->Enabled = false;
}
// ------------------------------------------------------------
// Timer Event => Timer Event에서 자신의 핸들에 이벤트를 보낸다.
void __fastcall THydro::OnTimer(TObject *Sender)
{
static int i = 0;
::PostMessage(this->Handle, UM_MESSAGE, EN_LOGGER_STEP::enIdle, 0); // 자기자신에게 이벤트를 보낸다.
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------MainUnit.h
//---------------------------------------------------------------------------
#ifndef MainUnitH
#define MainUnitH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
#define UM_MESSAGE WM_USER + 1000
enum EN_LOGGER_STEP { enIdle = 0x00,
enStart,
enFinish };
// --------------------------------------------------
// --------------------------------------------------
// THydro Class
// --------------------------------------------------
class THydro : public TWinControl // 장비 담당 전용 클래스
{
private :
TTimer *Timer; // 자체 타이머
public:
__fastcall THydro(TComponent* Owner);
virtual ~THydro();
void OnMessage(TMessage &Message); // 이벤트 처리 Method..
void TimerEnable();
void TimerDisable();
void __fastcall OnTimer(TObject *Sender); // Timer Event 처리
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(UM_MESSAGE, TMessage, OnMessage)
END_MESSAGE_MAP(TWinControl)
};
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *btnEnable;
TMemo *mo;
TButton *btnDisable;
void __fastcall btnEnableClick(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall btnDisableClick(TObject *Sender);
private: // User declarations
THydro *Hydro; // 장비 Class 생성
long iCnt;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
수달 님이 쓰신 글 :
: 개발 환경 : C++ Builder 10.3(Rio)
:
: MainForm에서 특정 장비을 처리하는 클래스(THydro)를 만들고,
: 해당 장비 클래스에서 Timer와 자체 Event를 가지려고 합니다.
:
: 제작하는 class(THydro)에서 윈도우 핸들을 가지려면,
: VCL의 상속 구조 상 TWinControl부터 Handle이 있길래,
: 이놈에서 상속을 받아서 class를 제작했는데.. -.-;;
: 원래 이런 초식이 아닌 모양입니다.
:
: 코드로는 대략 아래와 같은데.. 당근 에러 입니다.
: 에러 메세지는 Parent window가 없다는 것이고.. THydro has no parent window..
:
: THydro Class를 만들고, 자체 Timer에서 THydro 클래스 자체의 핸들에
: PostMessage()로 윈도우 메세지를 보내려고 합니다.
: SendMessage()로 보내지 않은 것은, 이벤트를 처리하는 시간이 길어질 수 있어서 이렇게 처리합니다.
: 대략 코드는 아래와 같이 구성했는데..
:
: 어떻게 해야하는 지 고수님들의 지도 편달 바랍니다.
:
:
:
: enum EN_LOGGER_STEP { enIdle = 0x00,
: enStart,
: enFinish };
: // --------------------------------------------------
: // MainForm Class
: // --------------------------------------------------
: class TForm1 : public TForm // MainForm Class
: {
: __published: // IDE-managed Components
: private: // User declarations
: //... attribute..
: public:
: THydro *Hydro; // 장비 Class 생성
: //...
: public: // User declarations
: __fastcall TForm1(TComponent* Owner);
: };
:
: // --------------------------------------------------
: // THydro Class
: // --------------------------------------------------
: class THydro : public TWinControl // 장비 담당 전용 클래스
: {
: private :
: TTimer *Timer; // 자체 타이머
: public:
: __fastcall THydro(TComponent* Owner);
:
: void OnMessage(TMessage &Message); // 이벤트 처리 Method..
: void TimerEnable();
: void TimerDisable();
: void __fastcall OnTimer(TObject *Sender); // Timer Event 처리
:
: BEGIN_MESSAGE_MAP
: MESSAGE_HANDLER(UM_MESSAGE, TMessage, OnMessage)
: END_MESSAGE_MAP(TWinControl)
: };
:
: // ...
:
: // --------------------------------------------------
: // THydro 의 Method
: // --------------------------------------------------
:
: __fastcall THydro::THydro(TComponent* Owner) // 생성자
: :TWinControl(Owner)
: {
: Timer = new TTimer(NULL);
: Timer->OnTimer = OnTimer;
: Timer->Enabled = false;
: }
:
: void THydro::OnMessage(TMessage &Message) // 이벤트 처리 Method
: {
: bool bResult = false;
:
: EN_LOGGER_STEP enStep = (EN_LOGGER_STEP)Message.WParam;
:
: UnicodeString MeasureDate, MeasureTime;
:
: switch ( enStep ) {
: case enIdle :
: {
: // do sometihing..
: }
: break;
: case enStart :
: case enFinish :
: break;
: }
: }
:
: // ------------------------------------------------------------
: void THydro::TimerEnable()
: {
: Timer->Interval = 1 * 1000; // every 2 second
: Timer->Enabled = true;
: }
:
: // ------------------------------------------------------------
: void THydro::TimerDisable()
: {
: Timer->Enabled = false;
: }
:
: // ------------------------------------------------------------
: // Timer Event => Timer Event에서 자신의 핸들에 이벤트를 보낸다.
: void __fastcall THydro::OnTimer(TObject *Sender)
: {
: static int i = 0;
: ::PostMessage(this->Handle, UM_MESSAGE, EN_LOGGER_STEP::enIdle, 0); // 자기자신에게 이벤트를 보낸다.
: }
:
:
: