www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to register class member function as lpfnWndProc? Cannot convert

reply "deed" <none none.none> writes:
Hi

I am trying to register a class member function as 
wc.lpfnWndProc, but get the error message "cannot implicitly 
convert expression (&this.WndProc) of type extern (Windows) int 
delegate(...) to extern (Windows) int function(...).

I have:

extern (Windows)
class App
{
     HRESULT initialize(HINSTANCE hInstance, int iCmdShow)
     {
         WNDCLASS wc;
         ...
         wc.lpfnWndProc = &wndProc;
         ...
     }

     HRESULT wndProc(HWND hwnd, UINT message, WPARAM wParam, 
LPARAM lParam)
     {
         switch (message)
         {
             ...
         }
     }
     ...
}


(Defining wndProc as a global function works, but is not what I 
want to do...)
What is the issue here and how do I make it work?
Sep 28 2012
next sibling parent "Jesse Phillips" <Jessekphillips+D gmail.com> writes:
On Friday, 28 September 2012 at 17:53:59 UTC, deed wrote:

 (Defining wndProc as a global function works, but is not what I 
 want to do...)
 What is the issue here and how do I make it work?

You are interfacing with C, which does not support functions with state (delegate). You must pass it a function, and while you can get at the function pointer of a delegate this is unsafe. You make it work by providing a function and not a delegate. I do not know how to wrap a delegate to make that work.
Sep 28 2012
prev sibling next sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Friday, 28 September 2012 at 17:53:59 UTC, deed wrote:
 Hi

 I am trying to register a class member function as 
 wc.lpfnWndProc, but get the error message "cannot implicitly 
 convert expression (&this.WndProc) of type extern (Windows) int 
 delegate(...) to extern (Windows) int function(...).

 I have:

 extern (Windows)
 class App
 {
     HRESULT initialize(HINSTANCE hInstance, int iCmdShow)
     {
         WNDCLASS wc;
         ...
         wc.lpfnWndProc = &wndProc;
         ...
     }

     HRESULT wndProc(HWND hwnd, UINT message, WPARAM wParam, 
 LPARAM lParam)
     {
         switch (message)
         {
             ...
         }
     }
     ...
 }


 (Defining wndProc as a global function works, but is not what I 
 want to do...)
 What is the issue here and how do I make it work?

Because wndProc in your case cannot be converted to a delegate. You can make it a module-level function (there is no globals in D) or try to make it static function - I currently cannot check whether it works. In any way, what gives you making wndProc a class member function?
Sep 28 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 9/28/12, Maxim Fomin <maxim maxim-fomin.ru> wrote:
 try to make it static function

If only one app is ever supposed to be instantiated you can use a static function and a static reference to the class instance: http://dpaste.dzfl.pl/b1497fa1 Otherwise you could use a hashmap to redirect wndProc's to class instances by using a HWND as the key and App as the value, something like: App[HWND] apps; extern (Windows) LRESULT winDispatch(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { auto app = hwnd in apps; if (app !is null) { return app.wndProc(hwnd, message, wParam, lParam); } return DefWindowProc(hwnd, message, wParam, lParam); } apps would be written to any time a new App instance is created. Anyway there are multiple ways of doing this, it depends on what you need.
Sep 28 2012
prev sibling parent "deed" <none none.none> writes:
Thanks to all of you for your informative replies. I was testing 
different code structures and wondered whether this was possible.
Sep 30 2012