May 11, 2012
On Friday, 11 May 2012 at 15:41:02 UTC, Mehrdad wrote:
> On Friday, 11 May 2012 at 15:36:37 UTC, Mehrdad wrote:
>> It's in the same exact thread as the caller of CreateWindow in Win32
>
> Minor correction: that's under the assumption that the thread that registered the window class (with RegisterClass()) is the same thread creating the window, which is the case most of the time.
>
> But if it's one process instantiating the window of a different process (which happens sometimes), or if it's one thread instantiating the window of a different thread (which happens more rarely), that's obviously not the case...

Never mind, I actually messed up the last part; it's the same thread throughout:
http://www.oopweb.com/Assembly/Documents/Win32ASM/Volume/winmsg.htm#windowthread


I just got this confused because if you happen to use SendMessage() to send the message, THEN the rule I mentioned applies.

But here, the system calls the window procedure directly, and as the link says, only the current ever calls the window procedure.
May 11, 2012
Since I kinda failed at explaining it, here's a better link, MSDN itself:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644950.aspx

Note what it says happens when you call SendMessage():

"If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message."

So, in other words, the thread of RegisterClass() doesn't have much to do with anything so far as the window procedure is concerned -- the window procedure is always executed in the same thread that created the window. (We're not using SendMessage() here, but the rule regarding who can call the window procedure is the same.)
May 11, 2012
On 2012-05-06 21:55, Mehrdad wrote:
> Is this possible in D2?
>
> i.e. I'm wondering if there is a way to do the object
> construction yourself, which would allow you to call the object's
> "constructor" (initializer) manually, and just return a pointer
> to the new object.
>
> Something along the lines of:
>
> class Window
> {
> static Window opConstruct(void* ptr)
> {
> // Assume ptr is already correctly sized and filled
> Window result = cast(Window)ptr;
> result.__ctor();
> return return result;
> }
> }
>
> It seems like overloading new() *almost* does this, but not
> quite: It only lets you allocate the memory, not call the
> constructor yourself.
>
> This would be useful, because some objects can have external
> constructors (notably when interfacing with C/C++, such as when
> using CreateWindow() in Windows), and you *cannot* call these
> constructors inside the object's "constructor" (initializer) due
> to re-entrancy issues.

Don't know if it helps but, have a look the DWT sources:

https://github.com/d-widget-toolkit/org.eclipse.swt.win32.win32.x86/tree/master/src/org/eclipse/swt

should probably be in the internal folder, widgets/Widget or widgets/Shell.

-- 
/Jacob Carlborg
May 11, 2012
On Friday, 11 May 2012 at 22:28:55 UTC, Jacob Carlborg wrote:
> On 2012-05-06 21:55, Mehrdad wrote:
>> Is this possible in D2?
>>
>> i.e. I'm wondering if there is a way to do the object
>> construction yourself, which would allow you to call the object's
>> "constructor" (initializer) manually, and just return a pointer
>> to the new object.
>>
>> Something along the lines of:
>>
>> class Window
>> {
>> static Window opConstruct(void* ptr)
>> {
>> // Assume ptr is already correctly sized and filled
>> Window result = cast(Window)ptr;
>> result.__ctor();
>> return return result;
>> }
>> }
>>
>> It seems like overloading new() *almost* does this, but not
>> quite: It only lets you allocate the memory, not call the
>> constructor yourself.
>>
>> This would be useful, because some objects can have external
>> constructors (notably when interfacing with C/C++, such as when
>> using CreateWindow() in Windows), and you *cannot* call these
>> constructors inside the object's "constructor" (initializer) due
>> to re-entrancy issues.
>
> Don't know if it helps but, have a look the DWT sources:
>
> https://github.com/d-widget-toolkit/org.eclipse.swt.win32.win32.x86/tree/master/src/org/eclipse/swt
>
> should probably be in the internal folder, widgets/Widget or widgets/Shell.


Thanks for the link.
It seems like it's on Control.d...

Yup, they do what C# does with the constructor: they put make a *separate* function, createHandle(), used to create the control.

And they simply *don't* tie the destructor to DestroyWindow(); instead, they just assume the user will call dispose().

So in other words, they just ignored the entire problem with the lifetimes, and hoped ("required"?) that the user will call dispose().

Not something I'd want to do, since (even according to .NET's philosophy) a handle leak must NEVER occur, as long as the program has control, even if the user doesn't dispose the object.

The closing of the handle can of course be nondeterministic due to the GC, but it must be eventually cleaned up when the object is GC'd.


Any ideas if this would be easy/hard to add to DMD/Phobos?
May 12, 2012
> Yup, they do what C# does with the constructor: they put make a *separate* function, createHandle(), used to create the control.
>
> And they simply *don't* tie the destructor to DestroyWindow(); instead, they just assume the user will call dispose().>
> So in other words, they just ignored the entire problem with the lifetimes, and hoped ("required"?) that the user will call dispose().

Actually, in WinForms, closing the application's main Form
triggers its Dispose method, which disposes of child Controls too.
May 12, 2012
On Saturday, 12 May 2012 at 15:57:37 UTC, John Chapman wrote:
>> Yup, they do what C# does with the constructor: they put make a *separate* function, createHandle(), used to create the control.
>>
>> And they simply *don't* tie the destructor to DestroyWindow(); instead, they just assume the user will call dispose().>
>> So in other words, they just ignored the entire problem with the lifetimes, and hoped ("required"?) that the user will call dispose().
>
> Actually, in WinForms, closing the application's main Form
> triggers its Dispose method, which disposes of child Controls too.

Yes, that's not a WinForms thing -- when you close a window, it's trivial to have  DestroyWindow() get called too.

The trouble is that you can't rely on this to avoid handle leaks -- for example, message-only windows are invisible, so their handles can get leaked and they can never be closed.
May 14, 2012
On 2012-05-12 20:30, Mehrdad wrote:

> Yes, that's not a WinForms thing -- when you close a window, it's
> trivial to have DestroyWindow() get called too.
>
> The trouble is that you can't rely on this to avoid handle leaks -- for
> example, message-only windows are invisible, so their handles can get
> leaked and they can never be closed.

A DWT Hello World application looks like this:

void main ()
{
    auto display = new Display;
    auto shell = new Shell(display);
    shell.open();

    while (!shell.isDisposed)
        if (!display.readAndDispatch())
            display.sleep();

    display.dispose();
}

You always call "display.dispose" at the end of the main function. Since "dispose" will dispose all of the receiver's children and "display" is the top level widget, everything will be disposed when the application exits.

-- 
/Jacob Carlborg
May 14, 2012
On Monday, 14 May 2012 at 07:26:27 UTC, Jacob Carlborg wrote:
> You always call "display.dispose" at the end of the main function. Since "dispose" will dispose all of the receiver's children and "display" is the top level widget, everything will be disposed when the application exits.

*sigh* I just spent a few posts explaining why you need to clean
things up in the destructor, and then I get a reply telling me to
just manage resources manually, screw automatic garbage
collection. >_<
May 14, 2012
On 2012-05-14 10:10, Mehrdad wrote:
> On Monday, 14 May 2012 at 07:26:27 UTC, Jacob Carlborg wrote:
>> You always call "display.dispose" at the end of the main function.
>> Since "dispose" will dispose all of the receiver's children and
>> "display" is the top level widget, everything will be disposed when
>> the application exits.
>
> *sigh* I just spent a few posts explaining why you need to clean
> things up in the destructor, and then I get a reply telling me to
> just manage resources manually, screw automatic garbage
> collection. >_<

No, I'm telling you how SWT/DWT works. How "dispose" works in DWT is _not_ the same as doing managing memory manually.

-- 
/Jacob Carlborg
May 14, 2012
On Monday, 14 May 2012 at 13:25:11 UTC, Jacob Carlborg wrote:
> No, I'm telling you how SWT/DWT works. How "dispose" works in DWT is _not_ the same as doing managing memory manually.


Memory? The entire issue is about a handle leak, not a memory leak...