在c++中创建TNotifyEvent用于应用程序级别

Create TNotifyEvent in C++ for use at Application level

本文关键字:应用程序 用于 TNotifyEvent c++ 创建      更新时间:2023-10-16

我需要在c++ Builder中挂钩到应用程序的OnDeactivate事件。因此,我需要编写自己的函数,以便在OnDeactivate事件为应用程序触发时运行,但我不知道在哪里或如何定义该函数。

理想情况下我希望我的代码看起来像这样:

WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
  try
  {
     Application->Initialize();
     Application->OnDeactivate = myFunction;
     Application->Run();
   }

后:

 void myFunction(TObject *Sender)
 {
 //Do Stuff
 }

当我在我的.cpp文件中这样写时,它会报错

无法将'void(*)(TObject *)'转换为'TNotifyEvent'

如果我更改函数以返回TNotifyEvent(无论如何都不应该工作),它会给我

的搞笑错误

无法将'TNotifyEvent'转换为'TNotifyEvent'

那么,我应该如何去写一个函数挂钩到我的应用程序属性?

您正在尝试分配一个独立的函数,而期望使用非静态类方法。您有两个选择:

1)将事件处理程序移动到helper类中:

class Helper
{
public:
    void __fastcall myFunction(TObject *Sender)
    {
        // ... do stuff
    }
};
WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    try
    {
        Application->Initialize();
        Helper helper;
        Application->OnDeactivate = &helper.myFunction;
        ...
    }
    ...
}

2)将函数保留为非类函数,但给它一个额外的参数来接收编译器的this指针,然后使用TMethod结构体来帮助您将其作为合适的TNotifyEvent传递给事件:

void __fastcall myFunction(void *pThis, TObject *Sender)
{
    ...
}
WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    try
    {
        Application->Initialize();
        TMethod m;
        m.Data = NULL; // passed to the pThis parameter, can be whatever you want
        m.Code = &myFunction;
        Application->OnDeactivate = reinterpret_cast<TNotifyEvent&>(m);
        ...
    }
    ...
}

话是这么说的,如果MainForm没有被分配,TApplication::Run()会立即退出,所以最简单的解决方案就是把TApplicationEvents组件放到MainForm上,然后你可以在设计时为它分配一个OnDeactivate事件处理程序。

Update:或者,如果您的项目有任何TFormTDataModule对象,您可以简单地在其中一个上放置TApplicationEvents组件,并在设计时为其分配OnDeactivate事件处理程序。然后,它将为您钩入应用程序的OnDeactivate事件。

你差不多就是这样了。

我所做的是创建一个包含各种动作的TActionList。我用下面的代码创建了一个将在表单OnCreate事件上调用的动作:

void __fastcall TForm1::onCreateActionExecute(TObject *Sender)
{
 Application->OnDeactivate = MyAppDeactivate;
}

,然后添加一个小测试函数到我的表单:

void __fastcall MyAppDeactivate(TObject *Sender) { ShowMessage("Deactivate"); };