Re: Use nested functions as callbacks with Windows API functions?

2018-10-02 Thread John Chapman via Digitalmars-d-learn

On Monday, 1 October 2018 at 20:27:43 UTC, spikespaz wrote:
Of course there is nothing wrong with defining each callback as 
a separate function, but then comes the issue of naming them. I 
also don't like the way it makes my code look.


I think the best you can do is something like this:

---
auto callback(T, string file = __FILE__, size_t line = 
__LINE__)(T handler) {

  import std.traits;

  __gshared T handler_;
  handler_ = handler;

  extern(Windows)
  ReturnType!T fn(Parameters!T args) {
synchronized return handler_(args);
  }

  return 
}

void main() {
  HWND[] list;
  EnumWindows((HWND hwnd, LPARAM lparam) {
list ~= hwnd;
return TRUE;
  }.callback(), 0);
  writeln(list);
}
---



Re: Use nested functions as callbacks with Windows API functions?

2018-10-02 Thread Boris-Barboris via Digitalmars-d-learn

On Monday, 1 October 2018 at 23:07:29 UTC, spikespaz wrote:
The problem with the code you have is that the callback needs 
to be extern (Windows). I don't know how to do that with a 
"lambda".


Neither do I actually. Apparently it is impossible.
Best I could squeeze out was this:
https://run.dlang.io/is/CpyfW3


Re: Use nested functions as callbacks with Windows API functions?

2018-10-01 Thread spikespaz via Digitalmars-d-learn

On Monday, 1 October 2018 at 21:03:24 UTC, Boris-Barboris wrote:

On Monday, 1 October 2018 at 20:27:43 UTC, spikespaz wrote:
I was hoping I could use something more akin to JavaScript's 
syntax: (void* hWnd, long) => {}.


I tried this but I'm getting errors with the signature, it 
says the function is a delegate and apparently Windows API 
can't accept a delegate.


You can make it a non-delegate by passing a pointer to hWndList 
in lParams as it was supposed to by WinApi devs, instead of 
zero, and not implicitly capturing stack pointer by referencing 
hWndList directly from the body.


https://run.dlang.io/is/t4k4Nc


The problem with the code you have is that the callback needs to 
be extern (Windows). I don't know how to do that with a "lambda".


===

import core.sys.windows.windows: EnumWindows;
import std.stdio: writeln;

void main() {
void*[] hWndList;

EnumWindows((void* hWnd, void* lParam) nothrow {
*(cast(void*[] *) lParam) ~= hWnd;
return true;
}, );

writeln(hWndList);
}

===

source\cb.d(7): Error: function 
core.sys.windows.winuser.EnumWindows(extern (Windows) int 
function(void*, long) nothrow, long) is not callable using 
argument types (bool function(void* hWnd, void* lParam) pure 
nothrow @system, void*[]*)
source\cb.d(7):cannot pass argument __lambda1 of type 
bool function(void* hWnd, void* lParam) pure
nothrow @system to parameter extern (Windows) int function(void*, 
long) nothrow


Re: Use nested functions as callbacks with Windows API functions?

2018-10-01 Thread spikespaz via Digitalmars-d-learn

On Monday, 1 October 2018 at 21:03:24 UTC, Boris-Barboris wrote:

On Monday, 1 October 2018 at 20:27:43 UTC, spikespaz wrote:
I was hoping I could use something more akin to JavaScript's 
syntax: (void* hWnd, long) => {}.


I tried this but I'm getting errors with the signature, it 
says the function is a delegate and apparently Windows API 
can't accept a delegate.


You can make it a non-delegate by passing a pointer to hWndList 
in lParams as it was supposed to by WinApi devs, instead of 
zero, and not implicitly capturing stack pointer by referencing 
hWndList directly from the body.


https://run.dlang.io/is/t4k4Nc


I don't know how to do this. I'm not the best with pointers, I'm 
still learning D and I'm unfamiliar with functional programming.


==

import core.sys.windows.windows: EnumWindows;
import std.stdio: writeln;

extern (Windows) int callback(void* hWnd, long hWndList) nothrow {
hWndList ~= hWnd;

return true;
}

void main() {
void*[] hWndList;

EnumWindows(, );

writeln(hWndList);
}

==

Clearly I can't use  to pass the reference, how would I 
access the variable by the memory address inside the callback?




Re: Use nested functions as callbacks with Windows API functions?

2018-10-01 Thread Boris-Barboris via Digitalmars-d-learn

On Monday, 1 October 2018 at 20:27:43 UTC, spikespaz wrote:
I was hoping I could use something more akin to JavaScript's 
syntax: (void* hWnd, long) => {}.


I tried this but I'm getting errors with the signature, it says 
the function is a delegate and apparently Windows API can't 
accept a delegate.


You can make it a non-delegate by passing a pointer to hWndList 
in lParams as it was supposed to by WinApi devs, instead of zero, 
and not implicitly capturing stack pointer by referencing 
hWndList directly from the body.


https://run.dlang.io/is/t4k4Nc


Use nested functions as callbacks with Windows API functions?

2018-10-01 Thread spikespaz via Digitalmars-d-learn

I have the following code, this works.



import core.sys.windows.windows: EnumWindows;
import std.stdio: writeln;

void*[] hWndList;

extern (Windows) int callback(void* hWnd, long /* lParams */ ) 
nothrow {

hWndList ~= hWnd;

return true;
}

void main() {
EnumWindows(, 0);

writeln(hWndList);
}



I was hoping I could use something more akin to JavaScript's 
syntax: (void* hWnd, long) => {}.


I tried this but I'm getting errors with the signature, it says 
the function is a delegate and apparently Windows API can't 
accept a delegate.




import core.sys.windows.windows: EnumWindows;
import std.stdio: writeln;

void main() {
void*[] hWndList;

EnumWindows((void* hWnd, long /* lParams */ ) nothrow {
hWndList ~= hWnd; return true;
}, 0);

writeln(hWndList);
}



I'm not going to even paste the compiler error because I am very 
clearly going about this the wrong way.


Of course there is nothing wrong with defining each callback as a 
separate function, but then comes the issue of naming them. I 
also don't like the way it makes my code look.


Thanks.