Thread overview
How I can pass the WndProc as a parameter?
Sep 10, 2022
Injeckt
Sep 10, 2022
Injeckt
Sep 10, 2022
Andrey Zherikov
Sep 10, 2022
Mike Parker
Sep 10, 2022
Mike Parker
September 10, 2022

I define this function:

extern(Windows)
static LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nothrow {
    return 0;
}

Then I define in another .d file:

void KK_CreateWindowClass(WNDPROC WndProc) {
    WNDCLASSEX wndclass;
    wndclass.lpfnWndProc = WndProc;
}

And after all, I call it:

KK_CreateWindowClass(WndProc);

But I get these bugs:
server.d(29): Error: function server.WndProc(void* hwnd, uint message, uint wParam, int lParam) is not callable using argument types ()
server.d(29): too few arguments, expected 4, got 0
server.d(29): Error: function utils.KK_CreateWindowClass(extern (Windows) int function(void*, uint, uint, int) nothrow @system WndProc) is not callable using argument types (_error_)
server.d(29): cannot pass argument __error of type _error_ to parameter extern (Windows) int function(void*, uint, uint, int) nothrow @system WndProc

September 10, 2022

On Saturday, 10 September 2022 at 10:39:12 UTC, Injeckt wrote:

>

utils.d(52): Error: cannot implicitly convert expression *WndProc of type nothrow @system extern (Windows) int(void*, uint, uint, int) to extern (Windows) int function(void*, uint, uint, int) nothrow @system

September 10, 2022

On Saturday, 10 September 2022 at 10:39:12 UTC, Injeckt wrote:

>

server.d(29): Error: function server.WndProc(void* hwnd, uint message, uint wParam, int lParam) is not callable using argument types ()

I think you need to get address of a function:

wndclass.lpfnWndProc = &WndProc;
September 10, 2022

On Saturday, 10 September 2022 at 10:39:12 UTC, Injeckt wrote:

>

And after all, I call it:

KK_CreateWindowClass(WndProc);

KK_CreateWindowClass(&WndProc);

September 10, 2022

On Saturday, 10 September 2022 at 10:39:12 UTC, Injeckt wrote:

To elaborate on why you need the above...

>

But I get these bugs:

WndProc is a function, and you can't pass a function as a runtime function parameter, only pointers to functions. The first two errors tell you exactly what the problem is.

>

server.d(29): Error: function server.WndProc(void* hwnd, uint message, uint wParam, int lParam) is not callable using argument types ()

Note the bit that says "not callable using argument types ()". In D, functions that have an empty parameter list can be called without an argument list, i.e., void foo() can be called as foo, the compiler rewrites it to foo().

This error by itself tells you what's wrong. The compiler knows WndProc is a function, so it's trying to call WndProc() when it sees the WndProc in your argument list in the function call to KK.CreateWindowClass at line 29 of server.d.

>

server.d(29): too few arguments, expected 4, got 0

And this reinforces that: the WndProc function takes 4 arguments, but none were provided.

When doing Win32 programming in D, it sometimes helps to search online for problematic types. Microsoft's Win32 API documentation is really good. For functions, that's the only reference you need. But for other types and aliases, it sometimes helps to go one step further: use the MS docs to find out which header the type is defined in, then go the DRuntime source to find the corresponding binding.

In this case, searching for WNDPROC would turn up this page:

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wndproc

At the bottom of which we see that it's defined in winuser.h. So then you can go to the DRuntime sorce directory (it's installed with the compiler) and open core/sys/winuser.d, in which a search for WNDPROC eventually leads to this:

alias LRESULT function(HWND, UINT, WPARAM, LPARAM) WNDPROC;

That tells you it's a function pointer, meaning your function call needs &WndProc, since that's how we get function pointers in D.