View mode: basic / threaded / horizontal-split · Log in · Help
March 25, 2005
Re: How to introduce a callback function (class member) to win api ?
John C wrote:

> Ah, I'm afraid it was me who posted that code. The problem is that each time 
> you create a Callback instance, the static method_ field gets replaced, 
> making it unsuitable for reuse.
> 
> I haven't tries this yet, but it might work if each instance of Control had 
> a unique ID which is assigned in registerClass() and associated with the 
> window handle when it's created with GWL_ID.
> 
>       this(Method method, int id) {
>           methods_[id] ~= method;
>       }
> 
>       static extern (Windows) R callback(T1 arg1, T2 arg2, T3 arg3, T4 arg4) 
> {
>           return methods_[GetWindowLong(cast(Handle)arg1, GWL_ID)](arg1, 
> arg2, arg3, arg4);
>       }
> 
>       static Method[int] methods_;
> 
> John. 
> 
> 

Hmmm... good catch.  I never thought of that problem!  The solution 
above, though a little busier, might just work.  It really would be nice 
if there were a more straightforward solution.  I think this problem is 
fairly common to bump into.

Thanks for the ideas.

- JJR
March 25, 2005
Re: How to introduce a callback function (class member) to win api ?
"John Reimer" <brk_6502@yahoo.com> wrote in message 
news:d20lmo$2akm$1@digitaldaemon.com...
> John C wrote:
>
>> Ah, I'm afraid it was me who posted that code. The problem is that each 
>> time you create a Callback instance, the static method_ field gets 
>> replaced, making it unsuitable for reuse.
>>
>> I haven't tries this yet, but it might work if each instance of Control 
>> had a unique ID which is assigned in registerClass() and associated with 
>> the window handle when it's created with GWL_ID.
>>
>>       this(Method method, int id) {
>>           methods_[id] ~= method;

Of course, the above line should read:

   methods_[id] = method;

>>       }
>>
>>       static extern (Windows) R callback(T1 arg1, T2 arg2, T3 arg3, T4 
>> arg4) {
>>           return methods_[GetWindowLong(cast(Handle)arg1, GWL_ID)](arg1, 
>> arg2, arg3, arg4);
>>       }
>>
>>       static Method[int] methods_;
>>
>> John.
>
> Hmmm... good catch.  I never thought of that problem!  The solution above, 
> though a little busier, might just work.  It really would be nice if there 
> were a more straightforward solution.  I think this problem is fairly 
> common to bump into.
>
> Thanks for the ideas.
>
> - JJR

Note that some callbacks provide an extra parameter you can use to pass a 
pointer to your class instance, but WNDPROC doesn't.

I think a built-in unified delegate/function is the answer. But until we get 
that in D, I hope someone smarter than me can work out an interim solution. 
Callbacks are such an integral part of Windows programming and it's a shame 
object-oriented languages generally don't provide a way to deal with them in 
an OO way. In C++ I could use thunks (at least in VC++), but I've not been 
able to translate them to D.

C# does a lot of work behind the scenes to allow delegates to be used where 
C-style function pointers are expected. Delphi has a similar closure 
concept. Anyone know how Java copes with callbacks?
March 25, 2005
Re: How to introduce a callback function (class member) to win api ?
John C wrote:
> "John Reimer" <brk_6502@yahoo.com> wrote in message 
> news:d20lmo$2akm$1@digitaldaemon.com...

> concept. Anyone know how Java copes with callbacks? 
> 

Assuming you mean callbacks into the system API, such as Win32, it 
doesn't. All of that is hidden from you by the standard Java APIs. The 
only cases where you may encounter C-style callbacks is when using 
native code via JNI, but in that case you are using C or C++ anyway.
March 25, 2005
Re: How to introduce a callback function (class member) to win api ?
"John Reimer" <brk_6502@yahoo.com> wrote :d20ceg$2067$1@digitaldaemon.com...
> Shawn Liu wrote:
>> import std.c.windows.windows;
>> class Test{
>> HANDLE hInstance;
>> int windowProc (HANDLE hwnd, uint msg, WPARAM wParam, LPARAM lParam) 
>> {return
>> 0;}
>> void init(){
>> WNDCLASS wc;
>> wc.hInstance = hInstance;
>> wc.lpfnWndProc = &windowProc; // error !
>> // ... more
>> }
>> }
>>

I post this because I am reading the DWT and SWT source codes. SWT group 
implements this via a Callback class, but mostly depends on the JNI motheds 
in native dll file. I didn't read the c code yet.

DWT has a way to map the delegates and extern(Windows). Delegates are stored 
in global arrays. This is not oo way. And I wonder if every instance of a 
window registers one or more callbacks, the global array may exhaust.
March 25, 2005
Re: How to introduce a callback function (class member) to win api ?
Shawn Liu wrote:
> "John Reimer" <brk_6502@yahoo.com> wrote :d20ceg$2067$1@digitaldaemon.com...
> 
>>Shawn Liu wrote:
>>
>>>import std.c.windows.windows;
>>>class Test{
>>>HANDLE hInstance;
>>>int windowProc (HANDLE hwnd, uint msg, WPARAM wParam, LPARAM lParam) 
>>>{return
>>>0;}
>>>void init(){
>>>WNDCLASS wc;
>>>wc.hInstance = hInstance;
>>>wc.lpfnWndProc = &windowProc; // error !
>>>// ... more
>>>}
>>>}
>>>
> 
> 
> I post this because I am reading the DWT and SWT source codes. SWT group 
> implements this via a Callback class, but mostly depends on the JNI motheds 
> in native dll file. I didn't read the c code yet.
> 
> DWT has a way to map the delegates and extern(Windows). Delegates are stored 
> in global arrays. This is not oo way. And I wonder if every instance of a 
> window registers one or more callbacks, the global array may exhaust.
> 
> 
> 
> 

Yes, DWT uses a technique of mapping delegates to function pointers  by 
using arrays of each and a mapping function to route the calls.  It 
works but is laborious and a real eyesore (especially working with 
differing argument numbers).  It's appropriate for the project.  I just 
wish there were a simpler way to do this.

-JJR
Next ›   Last »
1 2
Top | Discussion index | About this forum | D home