There are two problems with your code:
1) 123456 (0x1E240) is not a valid user-level message ID. Values above 0xFFFF are reserved by the OS. Custom messages MUST be in the WM_USER
(0x0400 - 0x7FFF), WM_APP
(0x8000 - 0xBFFF), or RegisterWindowMessage()
(0xC000 - 0xFFFF) ranges.
2) you are passing a bad string pointer to FindWindow()
. You are type-casting a char[]
to a wchar_t*
, which is an invalid type-cast. To specify that the string literal should use wchar_t
instead of char
, you have to prefix the literal with the L
specifier instead. Or more generically, when using any TCHAR
-senstive API (like FindWindow()
), use the TEXT()
macro instead.
In addition, although not strictly an error, you should ue VCL_MESSAGE_HANDLER()
instead of MESSAGE_HANDLER()
, only because MESSAGE_HANDLER()
is defined differently by ATL. If you are not using ATL in your project, you won't run into a problem, but it is better to use VCL_MESSAGE_HANDLER()
just to make absolutely sure, and to document that the code is using the VCL's version of MESSAGE_HANDLER()
and not some other version.
Try this:
Unit1.h:
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
//---------------------------------------------------------------------------
#define WM_BAR_STEP_IT (WM_USER+1)
//---------------------------------------------------------------------------
class TRECIEVER : public TForm
{
__published: // IDE-managed Components
TButton *SENDER;
TProgressBar *BAR;
void __fastcall SENDERClick(TObject *Sender);
private: // User declarations
void __fastcall barUPD(TMessage&);
public: // User declarations
__fastcall TRECIEVER(TComponent* Owner);
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_BAR_STEP_IT, TMessage, barUPD);
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TRECIEVER *RECIEVER;
//---------------------------------------------------------------------------
#endif
Unit1.cpp:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TRECIEVER *RECIEVER;
//---------------------------------------------------------------------------
__fastcall TRECIEVER::TRECIEVER(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TRECIEVER::barUPD(TMessage&)
{
BAR->StepIt();
}
//---------------------------------------------------------------------------
void __fastcall TRECIEVER::SENDERClick(TObject *Sender)
{
// this assumes the Form's Caption is set to "RECEIVER"
// also specifying the class type for good measure...
PostMessage(FindWindow(TEXT("TRECEIVER"), TEXT("RECIEVER")), WM_BAR_STEP_IT, 0, 0);
//Alternatively:
//PostMessage(FindWindowW(ClassName().c_str(), Caption.c_str()), WM_BAR_STEP_IT, 0, 0);
}
//---------------------------------------------------------------------------
With that said, since the message is private to the app, there is no need to use FindWindow()
at all, use the TForm::Handle
property instead. And I would even go a step further by getting rid of the MESSAGE_HANDLER()
altogether. The message is private to the internals of TRECEIVER
, so that is where it should stay:
Unit1.h:
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
//---------------------------------------------------------------------------
class TRECIEVER : public TForm
{
__published: // IDE-managed Components
TButton *SENDER;
TProgressBar *BAR;
void __fastcall SENDERClick(TObject *Sender);
private: // User declarations
protected:
void __fastcall WndProc(TMessage& Message);
public: // User declarations
__fastcall TRECIEVER(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TRECIEVER *RECIEVER;
//---------------------------------------------------------------------------
#endif
Unit1.cpp:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TRECIEVER *RECIEVER;
#define WM_BAR_STEP_IT (WM_USER+1)
//---------------------------------------------------------------------------
__fastcall TRECIEVER::TRECIEVER(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TRECIEVER::WndProc(TMessage& Message)
{
if (Message.Msg == WM_BAR_STEP_IT)
BAR->StepIt();
else
TForm::WndProc(Message);
}
//---------------------------------------------------------------------------
void __fastcall TRECIEVER::SENDERClick(TObject *Sender)
{
PostMessage(Handle, WM_BAR_STEP_IT, 0, 0);
}
//---------------------------------------------------------------------------
If you want other pieces of your app to post messages to the Revceiver, you could expose a public method for that:
Unit1.h:
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
//---------------------------------------------------------------------------
class TRECIEVER : public TForm
{
__published: // IDE-managed Components
TButton *SENDER;
TProgressBar *BAR;
void __fastcall SENDERClick(TObject *Sender);
private: // User declarations
protected:
void __fastcall WndProc(TMessage& Message);
public: // User declarations
__fastcall TRECIEVER(TComponent* Owner);
void __fastcall PostBarStepIt();
};
//---------------------------------------------------------------------------
extern PACKAGE TRECIEVER *RECIEVER;
//---------------------------------------------------------------------------
#endif
Unit1.cpp:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TRECIEVER *RECIEVER;
#define WM_BAR_STEP_IT (WM_USER+1)
//---------------------------------------------------------------------------
__fastcall TRECIEVER::TRECIEVER(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TRECIEVER::WndProc(TMessage& Message)
{
if (Message.Msg == WM_BAR_STEP_IT)
BAR->StepIt();
else
TForm::WndProc(Message);
}
//---------------------------------------------------------------------------
void __fastcall TRECIEVER::SENDERClick(TObject *Sender)
{
PostBarStepIt();
}
//---------------------------------------------------------------------------
void __fastcall TRECIEVER::PostBarStepIt()
{
PostMessage(Handle, WM_BAR_STEP_IT, 0, 0);
}
//---------------------------------------------------------------------------
SomeOtherFile.cpp:
#include "Unit1.h"
void __fastcall TSomeOtherClass::SomeMethod()
{
RECIEVER->PostBarStepIt();
}