March 25, 2005
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
"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
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
"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
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
1 2
Next ›   Last »