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?