On Thursday, 27 July 2017 at 14:09:37 UTC, Mike Parker wrote:
1. You can't expect exceptions thrown in a callback called from C to be propagated through the C side back into the D side. That includes errors. It happens on some platforms, but not all. On Windows, it does not (at least, not with DMD -- I can't speak for LDC).

Figures that the different calling conventions inside the depths of windows wouldn't be unwound properly. I'll just make sure to do blanket try catches for all throwables in each of these extern windows functions so that the buffer flushes for debug output and then explicitly exit the program.

You could try to catch the error and stash it for later, but better to do change the way you access the map:

```
if(auto pwin = hwnd in winMap) window = *pwin;
```

Knew about this but didn't think you could do this in one line. This is fantastic.

3. As I mentioned in another post in this thread, you are doing the wrong thing with your window reference. In your call to CreateWindowEx, you are correctly casting the reference to void*. Everywhere else, you're treating it as a pointer. That's wrong! To prove it, you can to this. Declare an instance of WinThing at the top of the file.

In CreateWindowEx, you've treated it as such. But then when you fetch it out of lpCreateParams, you cast it to a WinThing*. For that to be correct, you would have to change CreateWindowEx to pass a pointer to the reference (i.e. cast(void*)&window). But actually, that's still not correct because you're taking the address of a local variable. So the correct thing to do is to leave CreateWindowEx as is, and change all every WinThing* to WinThing.

So in the language, references to class objects are treated the same syntactically as pointers? So if we were in C++, me declaraing a WinThing** (reference to a reference to an object) is the same as WinThing* in D? Tried out your changes, that definately cleaned up the mess. Why can I not also do the same with the create struct like:

CREATESTRUCT createStruct = cast(CREATESTRUCT) lparam;

I take it this is because CREATESTRUCT is not a D class, but a struct somewhere?

Note that you don't have to dereference the createStruct pointer to access its fields.

Nice tip, didn't realize D implicitly dereferenced pointers when you apply the dot operator. Very nice.

There's no reason to make this static member or to call toUTFz when you use it. You can use a manifest constant with a wchar literal. Unlike char -> char*, whcar does not implicitly convert to wchar*, but you can use the .ptr property.

enum baseClass = "BaseClass"w;
wc.lpszClassName = baseClass.ptr;

Is the only difference between this and private static immutable values that the enum could not be an lvalue and has no reference at runtime?


Reply via email to