1

VCLフォームアプリでメッセージを渡して処理する方法を学ぼうとしています。私はしばらくの間インターネットを掘っていて、これを見つけまし

メッセージを使用して更新したいプログレスバーがあるとします(他にもっと良い方法がある場合は、それを聞きたがっています)それで、私はものをテストするための簡単なプロジェクトを作成しました、そしてこれが私が持っているものです(RECEIVERはの名前ですプログレスバー付きのフォーム、SENDERはメッセージの送信に使用されるボタン、updBarはプログレスバーを更新する機能、123456は使用したいメッセージID):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& msg){
    BAR->StepIt();
}
//---------------------------------------------------------------------------
void __fastcall TRECIEVER::SENDERClick(TObject *Sender)
{
//BAR->StepIt();
PostMessage(FindWindow(0,(wchar_t*)"RECIEVER"),123456,0,0);
}

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
public:     // User declarations
    void __fastcall barUPD(TMessage& msg);
    __fastcall TRECIEVER(TComponent* Owner);
    BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(123456,TMessage,barUPD);
    END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TRECIEVER *RECIEVER;
//---------------------------------------------------------------------------
#endif

ご覧のとおり、メッセージの処理関数と適切なメッセージハンドラーの両方を定義しました。しかし、デバッガーを介して(ボタンを使用してメッセージを送信した後)それを調べると、実行ポイントが関数にもハンドラー行にも移動していないように見えます。前もって感謝します

4

1 に答える 1

3

コードには2つの問題があります。

1)123456(0x1E240)は有効なユーザーレベルのメッセージIDではありません。0xFFFFを超える値は、OSによって予約されています。カスタムメッセージは、WM_USER( 0x0400-0x7FFF)、( WM_APP0x8000-0xBFFF)、またはRegisterWindowMessage()(0xC000-0xFFFF)の範囲内にある必要があります。

2)不正な文字列ポインタをに渡していますFindWindow()。を型キャストしchar[]ていwchar_t*ますが、これは無効な型キャストです。の代わりに文字列リテラルを使用するように指定するには、wchar_t代わりにcharリテラルの前に指定子を付ける必要がありLます。または、より一般的には、 (のような)TCHARセンシティブなAPIを使用する場合は、代わりにマクロを使用します。FindWindow()TEXT()

さらに、厳密にはエラーではありませんが、ATLによって定義が異なるという理由だけで、VCL_MESSAGE_HANDLER()の代わりにueを使用する必要があります。プロジェクトでATLを使用していない場合、問題は発生しませんが、絶対に確認し、コードがVCLのバージョンを使用しており、他のバージョンを使用していないことを文書化することをお勧めします。MESSAGE_HANDLER()MESSAGE_HANDLER()VCL_MESSAGE_HANDLER()MESSAGE_HANDLER()

これを試して:

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); 
} 
//--------------------------------------------------------------------------- 

とはいえ、メッセージはアプリ専用であるため、使用する必要はまったくなく、代わりにプロパティをFindWindow()使用してください。そして、私は完全TForm::Handleに取り除くことによってさらに一歩進むでしょう。MESSAGE_HANDLER()メッセージはの内部にプライベートであるTRECEIVERため、そこにとどまる必要があります。

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); 
} 
//--------------------------------------------------------------------------- 

アプリの他の部分でメッセージをRevceiverに投稿する場合は、そのためのパブリックメソッドを公開できます。

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(); 
}
于 2012-06-21T22:18:57.327 に答える