• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 220
  • Last Modified:

How to get a method in a class that an API call can Callback?

Experts,

This is what I need to accomplish.  I'm building a class that needs to pass an address of one of it's methods to a win API and in this method I will fire an event to the users of this class. Please provide example.  I can't use a public/method unit method because I'll have no idea which class invoked it, or is there a way to tell?

Thanks,
0
Johnn
Asked:
Johnn
  • 4
  • 3
1 Solution
 
DrDelphiCommented:
John,
  I am a little fuzzy on what exacxtly you are looking to do, but I can tell you that if you are looking to find the class which invoked the event, you should be able to use the sender parameter, since all classes derive ultimately from Tobject, you'd typecast (YourClass as Tobject).whatever... Hope this helps.


Good Luck!!

0
 
JohnnAuthor Commented:
Let me try to make this clearer if I can...I have a class that needs a method address to be passed to win32 API call for a callback.  I need a means to establish which instance of the class was called back so I can fire an event in that particular class.
0
 
MadshiCommented:
Johnn, that won't work this way, because class methods have an additional hidden self parameter. E.g. TNotifyEvent in reality looks like this:

procedure ([Self: TObject;] Sender: TObject);

This is indicated by the keywords "of object".

But you can nevertheless do what you want if the enumeration function has a private value you can use.

E.g. call EnumWindows like this:

function EnumWindowsProc(window: cardinal; Self: TObject);
begin
  // now in Self you have the object which called EnumWindows...
end;

procedure TSomeObject.Test;
begin
  EnumWindows(@YourStandardFunction, integer(Self));
end;

Regards, Madshi.
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
JohnnAuthor Commented:
Madshi, that may work for EnumWindows which allow an application defined object however other callback functions don't have such a parameter.  Any more ideas?
0
 
JohnnAuthor Commented:
Also, I'va managed to get the callback to call a class function via typed procedure, procedure type property, etc.  however i'm getting strange numbers for my parameters and my handle doesn't seem to be the correct one.
0
 
MadshiCommented:
>> Madshi, that may work for EnumWindows which allow an application defined object however other callback functions don't have such a parameter.

Yes, that's exactly what I told you. There is no other good choice. I'm sorry... Well, of course you could put the "Self" object into a global variable, then in the callback function you can access the global variable, but that's very ugly - and won't work, if you work with threads.

>> Also, I'va managed to get the callback to call a class function via typed procedure, procedure type property, etc.  however i'm getting strange numbers for my parameters and my handle doesn't seem to be the correct one.

You can't make this work, because as soon as you use an "of object" function (that is a member of a class) as the callback pointer, the parameters are not correct. Forget it. That just CANNOT work...   :-(

BTW, about which callback function are we talking? About callback pointers in general? Or something specific?
0
 
JohnnAuthor Commented:
setwindowshookex, if it helps.

>>You can't make this work, because as soon as you use an "of object" function (that is a member of a class) as the callback pointer, the parameters are not correct. Forget it. That just CANNOT work...   :-(<<

The parameters contain the correct values just not the correct parameter, I suspect if I knew how to shift the data I could make it work.  So far I know that the nCode parameter contains the wParams actual value and the wParam contains lParams actual value.  I don't really need the nCode because I can jsut call CallWindowsHook as a default, it's just getting my hooks handle that is the problem :(  So I am very close to getting it to work, at least with one instance of the class during my tests.


John
0
 
MadshiCommented:
>> setwindowshookex, if it helps.

Hmm... Yes, I see, SetWindowsHookEx is really a problem. Hmm... You don't do system wide hooks, do you? Because then you would have to put the callback function in a dll.
Well, okay, let's presume, you don't want system wide hooks. Then I think your only possibility is to use a global variable like this:

var HookHandle : cardinal;
    HookSelf   : TYourObj;

function CallbackFunc(...
begin
  if ... then
    HookSelf.HookCallback(...);
end;

You have to install the hook then this way:

procedure TYourObj.InstallHook(...);
begin
  HookSelf := Self;
  HookHandle := SetWindowsHookEx(...);
end;

>> The parameters contain the correct values just not the correct parameter, I suspect if I knew how to shift the data I could make it work.  So far I know that the nCode parameter contains the wParams actual value and the wParam contains lParams actual value.  I don't really need the nCode because I can jsut call CallWindowsHook as a default, it's just getting my hooks handle that is the problem :(  So I am very close to getting it to work, at least with one instance of the class during my tests.

Yes, of course the parameters are shifted, because of the hidden self parameter. "nCode" is stored in the hidden self parameter.
So if in your handler you do something like this now:

procedure TYourObj.DirectCallbackFunc(...);
begin
  FClassVariable := ...;    
  // here you'll get problems, because Delphi now tries to resolve [Self.]FClassVariable
  // but Self is "nCode", so Delphi uses nCode as an object pointer
  // you see the problem?
  // this just can't work
end;

Regards, Madshi.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now