Create TNotifyEvent in C++ for use at Application level

Deadly 提交于 2019-12-11 05:21:53

问题


I need to hook on to the Application's OnDeactivate event in C++ Builder. So I need to write my own function to run when the OnDeactivate event fires for the application, but I don't know where or how to define that function.

Ideally I would like my code to look something like this:

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

later:

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

When I write it like this in my .cpp file, it complains

cannot convert 'void(*)(TObject *)' to 'TNotifyEvent'

If I change my function to return a TNotifyEvent (which shouldn't work anyway), it gives me the hilarious error of

Cannot convert 'TNotifyEvent' to 'TNotifyEvent'

So, how should I go about writing a function to hook to my Application property?


回答1:


You are trying to assign a standalone function where a non-static class method is expected instead. You have two choices:

1) move your event handler into a helper class:

class Helper
{
public:
    void __fasycall myFunction(TObject *Sender)
    {
        ...
    }
};

WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    try
    {
        Application->Initialize();

        Helper helper;
        Application->OnDeactivate = &helper.myFunction;
        ...
    }
    ...
}

2) leave the function as a non-class function, but give it an extra parameter to receive the compiler's this pointer, and then use a TMethod struct to help you pass it to the event as a suitable TNotifyEvent:

void __fasycall 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);
        ...
    }
    ...
}

With that said, TApplication::Run() will exit immediately if a MainForm is not assigned, so the simpliest solution is to just drop a TApplicationEvents component onto your MainForm and then you can assign an OnDeactivate event handler to it at design-time.

Update: alternatively, if your project has any TForm or TDataModule objects, you can simply drop a TApplicationEvents component on one of them, and assign an OnDeactivate event handler to it at design time. It will then hook into the Application's OnDeactivate event for you.




回答2:


You pretty much have it like that.

What I did was create a TActionList that contains various actions. I created an action that would be called on the forms OnCreate event with this code:

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

and then added a little test function to my Form:

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

and that was it.



来源:https://stackoverflow.com/questions/7193174/create-tnotifyevent-in-c-for-use-at-application-level

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!