Defining a custom *constructor* (not initializer!)

Steven Schveighoffer schveiguy at yahoo.com
Fri May 11 06:58:15 PDT 2012


On Fri, 11 May 2012 09:33:54 -0400, Mehrdad <wfunction at hotmail.com> wrote:

>> OK, I understand what you are saying now.
>>
>> What about using NVI?
>>
>> class Window
>> {
>>   protected void processMessage_impl(int message) // virtual call
>>   {}
>>   final public void processMessage(int message)
>>   {
>>     if(message == WM_CREATE)
>>     {
>>        // handle specially
>>     }
>>     else if(message == WM_DELETE)
>>     {
>>        // handle specially
>>     }
>>     else
>>     {
>>         processMessage_impl(int message);
>>     }
>>   }
>>   private HWND window;
>>   this()
>>   {
>>     window = CreateWindow(&processMessage); // or whatever mechanism,  
>> you get the idea
>>   }
>>   ~this()
>>   {
>>     DestroyWindow(window);
>>   }
>> }
>>
>> -Steve
>
> The trouble is that if you "handle these specially", then your  
> subclasses won't....
> But your subclasses MUST still be able to handle these messages, because  
> they might need to do something special when the messages are sent. (For  
> example, you might need to calculate the size of the window when  
> WM_CREATE or WM_NCCREATE is sent.

I'm probably not getting the entire picture here, but I assume from your  
description that CreateWindow directly calls your WndProc.  If that is the  
case, isn't it guaranteed that after the base ctor runs the class has  
received the WM_CREATE message?  I mean, the only issue happens when you  
are not quite through the ctor chain, no?

> Or something else... there are a ton of situations that can happen --  
> such as MDI window creation, etc. -- that don't happen too often, but  
> happen often enough that you simply can't assume you can get by without  
> allowing them to handle the messages.)

You can use another mechanism to decide.  for instance:

class Window
    private bool inCreateWindow = false;
    ...
    final public void processMessage(int message)
    {
        if(inCreateWindow && message == WM_CREATE)
        {
            // handle specially
        }
        ...
    }
    this()
    {
       inCreateWindow = true;
       window = CreateWindow(&processMessage);
       inCreateWindow = false; // all WM_CREATE messages will now go  
through normal mechanism.
    }
}

-Steve


More information about the Digitalmars-d mailing list