Solved

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

Posted on 2000-02-21
8
202 Views
Last Modified: 2010-04-04
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
Comment
Question by:Johnn
  • 4
  • 3
8 Comments
 
LVL 6

Expert Comment

by:DrDelphi
ID: 2544958
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
 
LVL 1

Author Comment

by:Johnn
ID: 2544985
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
 
LVL 20

Accepted Solution

by:
Madshi earned 100 total points
ID: 2545095
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:Johnn
ID: 2546231
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
 
LVL 1

Author Comment

by:Johnn
ID: 2546240
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
 
LVL 20

Expert Comment

by:Madshi
ID: 2546299
>> 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
 
LVL 1

Author Comment

by:Johnn
ID: 2547784
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
 
LVL 20

Expert Comment

by:Madshi
ID: 2549337
>> 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

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

713 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question