changeset 80:1801ddeb8f32

removed static ctors
author Frank Benoit <benoit@tionex.de>
date Wed, 06 Feb 2008 12:09:44 +0100
parents 67d24430822a
children e10cbfc977d2
files dwt/graphics/TextLayout.d dwt/internal/image/JPEGFileFormat.d dwt/internal/image/PngChunk.d dwt/internal/image/PngDeflater.d dwt/widgets/Button.d dwt/widgets/Combo.d dwt/widgets/CoolBar.d dwt/widgets/Display.d dwt/widgets/Group.d dwt/widgets/Label.d dwt/widgets/Link.d dwt/widgets/List.d dwt/widgets/MenuItem.d dwt/widgets/ProgressBar.d dwt/widgets/Scale.d dwt/widgets/Shell.d dwt/widgets/Slider.d dwt/widgets/Spinner.d dwt/widgets/TabFolder.d dwt/widgets/Table.d dwt/widgets/Text.d dwt/widgets/ToolBar.d dwt/widgets/Tree.d dwt/widgets/Widget.d
diffstat 24 files changed, 689 insertions(+), 380 deletions(-) [+]
line wrap: on
line diff
--- a/dwt/graphics/TextLayout.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/graphics/TextLayout.d	Wed Feb 06 12:09:44 2008 +0100
@@ -72,11 +72,21 @@
     static const wchar LTR_MARK = '\u200E', RTL_MARK = '\u200F';
     static const int SCRIPT_VISATTR_SIZEOF = 2;
     static const int GOFFSET_SIZEOF = 8;
-    static byte[16] CLSID_CMultiLanguage;
-    static byte[16] IID_IMLangFontLink2;
-    static this() {
-        OS.IIDFromString("{275c23e2-3747-11d0-9fea-00aa003f8646}\0".toCharArray().ptr, CLSID_CMultiLanguage.ptr);
-        OS.IIDFromString("{DCCFC162-2B38-11d2-B7EC-00C04F8F5D9A}\0".toCharArray().ptr, IID_IMLangFontLink2.ptr);
+    private static byte[16] CLSID_CMultiLanguage;
+    private static byte[16] IID_IMLangFontLink2;
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        // in case of allready initialized, we can check and leave without lock
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( !static_this_completed ){
+                OS.IIDFromString("{275c23e2-3747-11d0-9fea-00aa003f8646}\0".toCharArray().ptr, CLSID_CMultiLanguage.ptr);
+                OS.IIDFromString("{DCCFC162-2B38-11d2-B7EC-00C04F8F5D9A}\0".toCharArray().ptr, IID_IMLangFontLink2.ptr);
+                static_this_completed = true;
+            }
+        }
     }
 
     class StyleItem {
@@ -180,6 +190,7 @@
  * @see #dispose()
  */
 public this (Device device) {
+    static_this();
     if (device is null) device = Device.getDevice();
     if (device is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
     this.device = device;
--- a/dwt/internal/image/JPEGFileFormat.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/internal/image/JPEGFileFormat.d	Wed Feb 06 12:09:44 2008 +0100
@@ -150,28 +150,39 @@
     public static int[] CrRTable, CbBTable, CrGTable, CbGTable;
     public static int[] RYTable, GYTable, BYTable,
         RCbTable, GCbTable, BCbTable, RCrTable, GCrTable, BCrTable, NBitsTable;
-    //public static void static_this() {
-    static this() {
-        initialize();
-        RGB16 = [
-            new RGB(0,0,0),
-            new RGB(0x80,0,0),
-            new RGB(0,0x80,0),
-            new RGB(0x80,0x80,0),
-            new RGB(0,0,0x80),
-            new RGB(0x80,0,0x80),
-            new RGB(0,0x80,0x80),
-            new RGB(0xC0,0xC0,0xC0),
-            new RGB(0x80,0x80,0x80),
-            new RGB(0xFF,0,0),
-            new RGB(0,0xFF,0),
-            new RGB(0xFF,0xFF,0),
-            new RGB(0,0,0xFF),
-            new RGB(0xFF,0,0xFF),
-            new RGB(0,0xFF,0xFF),
-            new RGB(0xFF,0xFF,0xFF)
-        ];
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            initialize();
+            RGB16 = [
+                new RGB(0,0,0),
+                new RGB(0x80,0,0),
+                new RGB(0,0x80,0),
+                new RGB(0x80,0x80,0),
+                new RGB(0,0,0x80),
+                new RGB(0x80,0,0x80),
+                new RGB(0,0x80,0x80),
+                new RGB(0xC0,0xC0,0xC0),
+                new RGB(0x80,0x80,0x80),
+                new RGB(0xFF,0,0),
+                new RGB(0,0xFF,0),
+                new RGB(0xFF,0xFF,0),
+                new RGB(0,0,0xFF),
+                new RGB(0xFF,0,0xFF),
+                new RGB(0,0xFF,0xFF),
+                new RGB(0xFF,0xFF,0xFF)
+            ];
+            static_this_completed = true;
+        }
     }
+
 void compress(ImageData image, byte[] dataYComp, byte[] dataCbComp, byte[] dataCrComp) {
     int srcWidth = image.width;
     int srcHeight = image.height;
--- a/dwt/internal/image/PngChunk.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/internal/image/PngChunk.d	Wed Feb 06 12:09:44 2008 +0100
@@ -52,19 +52,28 @@
     static const byte[] TYPE_IEND = cast(byte[])"IEND";//{(byte) 'I', (byte) 'E', (byte) 'N', (byte) 'D'};
     static const byte[] TYPE_tRNS = cast(byte[])"tRNS";//{(byte) 't', (byte) 'R', (byte) 'N', (byte) 'S'};
 
-    static const int[] CRC_TABLE;
-    //public static void static_this() {
-    static this() {
-        CRC_TABLE = new int[256];
-        for (int i = 0; i < 256; i++) {
-            CRC_TABLE[i] = i;
-            for (int j = 0; j < 8; j++) {
-                if ((CRC_TABLE[i] & 0x1) is 0) {
-                    CRC_TABLE[i] = (CRC_TABLE[i] >> 1) & 0x7FFFFFFF;
-                } else {
-                    CRC_TABLE[i] = 0xEDB88320 ^ ((CRC_TABLE[i] >> 1) & 0x7FFFFFFF);
+    private static /+const+/ int[] CRC_TABLE;
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            CRC_TABLE = new int[256];
+            for (int i = 0; i < 256; i++) {
+                CRC_TABLE[i] = i;
+                for (int j = 0; j < 8; j++) {
+                    if ((CRC_TABLE[i] & 0x1) is 0) {
+                        CRC_TABLE[i] = (CRC_TABLE[i] >> 1) & 0x7FFFFFFF;
+                    } else {
+                        CRC_TABLE[i] = 0xEDB88320 ^ ((CRC_TABLE[i] >> 1) & 0x7FFFFFFF);
+                    }
                 }
             }
+            static_this_completed = true;
         }
     }
 
@@ -75,6 +84,7 @@
  * given.
  */
 this(byte[] reference) {
+    static_this();
     setReference(reference);
     if (reference.length < LENGTH_OFFSET + LENGTH_FIELD_LENGTH) DWT.error(DWT.ERROR_INVALID_IMAGE);
     length = getInt32(LENGTH_OFFSET);
--- a/dwt/internal/image/PngDeflater.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/internal/image/PngDeflater.d	Wed Feb 06 12:09:44 2008 +0100
@@ -1,4 +1,4 @@
-/*******************************************************************************
+/*******************************************************************************
  * Copyright (c) 2000, 2006 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -36,6 +36,7 @@
     int nextWindow;
 
 public this(){
+    static_this();
     bytes = new ByteArrayOutputStream(1024);
 }
 
@@ -120,72 +121,82 @@
 
 }
 
-static const Code lengthCodes[];
-static const Code distanceCodes[];
+private static /+const+/ Code lengthCodes[];
+private static /+const+/ Code distanceCodes[];
 
-static this() {
-    lengthCodes = [
-        new Code(257, 0, 3, 3),
-        new Code(258, 0, 4, 4),
-        new Code(259, 0, 5, 5),
-        new Code(260, 0, 6, 6),
-        new Code(261, 0, 7, 7),
-        new Code(262, 0, 8, 8),
-        new Code(263, 0, 9, 9),
-        new Code(264, 0, 10, 10),
-        new Code(265, 1, 11, 12),
-        new Code(266, 1, 13, 14),
-        new Code(267, 1, 15, 16),
-        new Code(268, 1, 17, 18),
-        new Code(269, 2, 19, 22),
-        new Code(270, 2, 23, 26),
-        new Code(271, 2, 27, 30),
-        new Code(272, 2, 31, 34),
-        new Code(273, 3, 35, 42),
-        new Code(274, 3, 43, 50),
-        new Code(275, 3, 51, 58),
-        new Code(276, 3, 59, 66),
-        new Code(277, 4, 67, 82),
-        new Code(278, 4, 83, 98),
-        new Code(279, 4, 99, 114),
-        new Code(280, 4, 115, 130),
-        new Code(281, 5, 131, 162),
-        new Code(282, 5, 163, 194),
-        new Code(283, 5, 195, 226),
-        new Code(284, 5, 227, 257),
-        new Code(285, 0, 258, 258)];
+private static bool static_this_completed = false;
+private static void static_this() {
+    if( static_this_completed ){
+        return;
+    }
+    synchronized {
+        if( static_this_completed ){
+            return;
+        }
+        lengthCodes = [
+            new Code(257, 0, 3, 3),
+            new Code(258, 0, 4, 4),
+            new Code(259, 0, 5, 5),
+            new Code(260, 0, 6, 6),
+            new Code(261, 0, 7, 7),
+            new Code(262, 0, 8, 8),
+            new Code(263, 0, 9, 9),
+            new Code(264, 0, 10, 10),
+            new Code(265, 1, 11, 12),
+            new Code(266, 1, 13, 14),
+            new Code(267, 1, 15, 16),
+            new Code(268, 1, 17, 18),
+            new Code(269, 2, 19, 22),
+            new Code(270, 2, 23, 26),
+            new Code(271, 2, 27, 30),
+            new Code(272, 2, 31, 34),
+            new Code(273, 3, 35, 42),
+            new Code(274, 3, 43, 50),
+            new Code(275, 3, 51, 58),
+            new Code(276, 3, 59, 66),
+            new Code(277, 4, 67, 82),
+            new Code(278, 4, 83, 98),
+            new Code(279, 4, 99, 114),
+            new Code(280, 4, 115, 130),
+            new Code(281, 5, 131, 162),
+            new Code(282, 5, 163, 194),
+            new Code(283, 5, 195, 226),
+            new Code(284, 5, 227, 257),
+            new Code(285, 0, 258, 258)];
 
-    distanceCodes = [
-        new Code(0, 0, 1, 1),
-        new Code(1, 0, 2, 2),
-        new Code(2, 0, 3, 3),
-        new Code(3, 0, 4, 4),
-        new Code(4, 1, 5, 6),
-        new Code(5, 1, 7, 8),
-        new Code(6, 2, 9, 12),
-        new Code(7, 2, 13, 16),
-        new Code(8, 3, 17, 24),
-        new Code(9, 3, 25, 32),
-        new Code(10, 4, 33, 48),
-        new Code(11, 4, 49, 64),
-        new Code(12, 5, 65, 96),
-        new Code(13, 5, 97, 128),
-        new Code(14, 6, 129, 192),
-        new Code(15, 6, 193, 256),
-        new Code(16, 7, 257, 384),
-        new Code(17, 7, 385, 512),
-        new Code(18, 8, 513, 768),
-        new Code(19, 8, 769, 1024),
-        new Code(20, 9, 1025, 1536),
-        new Code(21, 9, 1537, 2048),
-        new Code(22, 10, 2049, 3072),
-        new Code(23, 10, 3073, 4096),
-        new Code(24, 11, 4097, 6144),
-        new Code(25, 11, 6145, 8192),
-        new Code(26, 12, 8193, 12288),
-        new Code(27, 12, 12289, 16384),
-        new Code(28, 13, 16385, 24576),
-        new Code(29, 13, 24577, 32768)];
+        distanceCodes = [
+            new Code(0, 0, 1, 1),
+            new Code(1, 0, 2, 2),
+            new Code(2, 0, 3, 3),
+            new Code(3, 0, 4, 4),
+            new Code(4, 1, 5, 6),
+            new Code(5, 1, 7, 8),
+            new Code(6, 2, 9, 12),
+            new Code(7, 2, 13, 16),
+            new Code(8, 3, 17, 24),
+            new Code(9, 3, 25, 32),
+            new Code(10, 4, 33, 48),
+            new Code(11, 4, 49, 64),
+            new Code(12, 5, 65, 96),
+            new Code(13, 5, 97, 128),
+            new Code(14, 6, 129, 192),
+            new Code(15, 6, 193, 256),
+            new Code(16, 7, 257, 384),
+            new Code(17, 7, 385, 512),
+            new Code(18, 8, 513, 768),
+            new Code(19, 8, 769, 1024),
+            new Code(20, 9, 1025, 1536),
+            new Code(21, 9, 1537, 2048),
+            new Code(22, 10, 2049, 3072),
+            new Code(23, 10, 3073, 4096),
+            new Code(24, 11, 4097, 6144),
+            new Code(25, 11, 6145, 8192),
+            new Code(26, 12, 8193, 12288),
+            new Code(27, 12, 12289, 16384),
+            new Code(28, 13, 16385, 24576),
+            new Code(29, 13, 24577, 32768)];
+        static_this_completed = true;
+    }
 }
 
 void writeShortLSB(ByteArrayOutputStream baos, int theShort) {
--- a/dwt/widgets/Button.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Button.d	Wed Feb 06 12:09:44 2008 +0100
@@ -12,8 +12,6 @@
  *******************************************************************************/
 module dwt.widgets.Button;
 
-
-
 import dwt.DWT;
 import dwt.DWTException;
 import dwt.events.SelectionEvent;
@@ -67,26 +65,37 @@
     ImageList imageList;
     bool ignoreMouse;
     static const int MARGIN = 4;
-    static const int CHECK_WIDTH, CHECK_HEIGHT;
+    private static /+const+/ int CHECK_WIDTH, CHECK_HEIGHT;
     static const int ICON_WIDTH = 128, ICON_HEIGHT = 128;
     static const bool COMMAND_LINK = false;
-    static const TWindowProc ButtonProc;
+    private static /+const+/ TWindowProc ButtonProc;
     static const TCHAR[] ButtonClass = "BUTTON\0";
-    static this() {
-        auto hBitmap = OS.LoadBitmap (null, OS.OBM_CHECKBOXES);
-        if (hBitmap is null) {
-            CHECK_WIDTH = OS.GetSystemMetrics (OS.IsWinCE ? OS.SM_CXSMICON : OS.SM_CXVSCROLL);
-            CHECK_HEIGHT = OS.GetSystemMetrics (OS.IsWinCE ? OS.SM_CYSMICON : OS.SM_CYVSCROLL);
-        } else {
-            BITMAP bitmap;
-            OS.GetObject (hBitmap, BITMAP.sizeof, &bitmap);
-            OS.DeleteObject (hBitmap);
-            CHECK_WIDTH = bitmap.bmWidth / 4;
-            CHECK_HEIGHT =  bitmap.bmHeight / 3;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
         }
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, ButtonClass.ptr, &lpWndClass);
-        ButtonProc = lpWndClass.lpfnWndProc;
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            auto hBitmap = OS.LoadBitmap (null, OS.OBM_CHECKBOXES);
+            if (hBitmap is null) {
+                CHECK_WIDTH = OS.GetSystemMetrics (OS.IsWinCE ? OS.SM_CXSMICON : OS.SM_CXVSCROLL);
+                CHECK_HEIGHT = OS.GetSystemMetrics (OS.IsWinCE ? OS.SM_CYSMICON : OS.SM_CYVSCROLL);
+            } else {
+                BITMAP bitmap;
+                OS.GetObject (hBitmap, BITMAP.sizeof, &bitmap);
+                OS.DeleteObject (hBitmap);
+                CHECK_WIDTH = bitmap.bmWidth / 4;
+                CHECK_HEIGHT =  bitmap.bmHeight / 3;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, ButtonClass.ptr, &lpWndClass);
+            ButtonProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
     }
 
 /**
@@ -126,6 +135,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/Combo.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Combo.d	Wed Feb 06 12:09:44 2008 +0100
@@ -77,7 +77,6 @@
     alias Composite.setBounds setBounds;
     alias Composite.setToolTipText setToolTipText;
 
-    alias extern(Windows) int function( HWND, uint, uint, int ) TWindowProc;
     private static Combo pThis;
     bool noSelection, ignoreDefaultSelection, ignoreCharacter, ignoreModify;
     HHOOK cbtHook;
@@ -110,15 +109,25 @@
      */
     static const int CBID_LIST = 1000;
     static const int CBID_EDIT = 1001;
-    static /*final*/ TWindowProc EditProc, ListProc;
+    static /*final*/ WNDPROC EditProc, ListProc;
 
-    static const TWindowProc ComboProc;
+    static /+const+/ WNDPROC ComboProc;
     static const TCHAR* ComboClass = "COMBOBOX\0";
 
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, ComboClass, &lpWndClass);
-        ComboProc = lpWndClass.lpfnWndProc;
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, ComboClass, &lpWndClass);
+            ComboProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
     }
 
 
@@ -153,6 +162,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
     /* This code is intentionally commented */
     //if ((style & DWT.H_SCROLL) !is 0) this.style |= DWT.H_SCROLL;
@@ -527,11 +537,11 @@
     /* Get the text and list window procs */
     auto hwndText = OS.GetDlgItem (handle, CBID_EDIT);
     if (hwndText !is null && EditProc is null) {
-        EditProc = cast(TWindowProc) OS.GetWindowLong (hwndText, OS.GWL_WNDPROC);
+        EditProc = cast(WNDPROC) OS.GetWindowLong (hwndText, OS.GWL_WNDPROC);
     }
     auto hwndList = OS.GetDlgItem (handle, CBID_LIST);
     if (hwndList !is null && ListProc is null) {
-        ListProc = cast(TWindowProc) OS.GetWindowLong (hwndList, OS.GWL_WNDPROC);
+        ListProc = cast(WNDPROC) OS.GetWindowLong (hwndList, OS.GWL_WNDPROC);
     }
 
     /*
--- a/dwt/widgets/CoolBar.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/CoolBar.d	Wed Feb 06 12:09:44 2008 +0100
@@ -61,17 +61,29 @@
     CoolItem [] originalItems;
     bool locked;
     bool ignoreResize;
-    static const WNDPROC ReBarProc;
+    private static /+const+/ WNDPROC ReBarProc;
     static const TCHAR* ReBarClass = OS.REBARCLASSNAME.ptr;
-    static this() {
-        INITCOMMONCONTROLSEX icex;
-        icex.dwSize = INITCOMMONCONTROLSEX.sizeof;
-        icex.dwICC = OS.ICC_COOL_CLASSES;
-        OS.InitCommonControlsEx (&icex);
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, ReBarClass, &lpWndClass);
-        ReBarProc = lpWndClass.lpfnWndProc;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            INITCOMMONCONTROLSEX icex;
+            icex.dwSize = INITCOMMONCONTROLSEX.sizeof;
+            icex.dwICC = OS.ICC_COOL_CLASSES;
+            OS.InitCommonControlsEx (&icex);
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, ReBarClass, &lpWndClass);
+            ReBarProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
     }
+
     static const int SEPARATOR_WIDTH = 2;
     static const int MAX_WIDTH = 0x7FFF;
     static const int DEFAULT_COOLBAR_WIDTH = 0;
@@ -106,6 +118,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
     /*
     * Ensure that either of HORIZONTAL or VERTICAL is set.
--- a/dwt/widgets/Display.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Display.d	Wed Feb 06 12:09:44 2008 +0100
@@ -165,26 +165,38 @@
     HWND lastGetHwnd;
     Control [] controlTable;
     static const int GROW_SIZE = 1024;
-    static const int SWT_OBJECT_INDEX;
+    private static /+const+/ int SWT_OBJECT_INDEX;
     static const bool USE_PROPERTY = !OS.IsWinCE;
-    static this() {
-        static if (USE_PROPERTY) {
-            SWT_OBJECT_INDEX = OS.GlobalAddAtom (StrToTCHARz( "SWT_OBJECT_INDEX")); //$NON-NLS-1$
-        } else {
-            SWT_OBJECT_INDEX = 0;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            static if (USE_PROPERTY) {
+                SWT_OBJECT_INDEX = OS.GlobalAddAtom (StrToTCHARz("SWT_OBJECT_INDEX")); //$NON-NLS-1$
+            } else {
+                SWT_OBJECT_INDEX = 0;
+            }
+            static_this_StartupInfo ();
+            static_this_DeviceFinder ();
+            static_this_completed = true;
         }
     }
 
     /* Startup info */
-    static STARTUPINFO* lpStartupInfo;
-    static this() {
+    private static STARTUPINFO* lpStartupInfo;
+    private static void static_this_StartupInfo (){
         static if (!OS.IsWinCE) {
             lpStartupInfo = new STARTUPINFO ();
             lpStartupInfo.cb = STARTUPINFO.sizeof;
             OS.GetStartupInfo (lpStartupInfo);
         }
     }
-
     /* XP Themes */
     HTHEME hButtonTheme_, hEditTheme_, hExplorerBarTheme_, hScrollBarTheme_, hTabTheme_;
     static const wchar [] BUTTON = "BUTTON\0"w;
@@ -429,7 +441,7 @@
     * gets the current display. This code will
     * be removed in the future.
     */
-    static this () {
+    private static void static_this_DeviceFinder () {
         DeviceFinder = new class() Runnable {
             public void run () {
                 Device device = getCurrent ();
@@ -445,6 +457,7 @@
 * TEMPORARY CODE.
 */
 static void setDevice (Device device) {
+    static_this();
     CurrentDevice = device;
 }
 
@@ -477,6 +490,7 @@
  * @param data the device data
  */
 public this (DeviceData data) {
+    static_this();
     super (data);
     synchronizer = new Synchronizer (this);
     cursors = new Cursor [DWT.CURSOR_HAND + 1];
@@ -794,6 +808,7 @@
 }
 
 static HBITMAP create32bitDIB (Image image) {
+    static_this();
     int transparentPixel = -1, alpha = -1;
     HBITMAP hMask;
     HBITMAP hBitmap;
@@ -926,6 +941,7 @@
 }
 
 static HBITMAP create32bitDIB (HBITMAP hBitmap, int alpha, byte [] alphaData, int transparentPixel) {
+    static_this();
     BITMAP bm;
     OS.GetObject (hBitmap, BITMAP.sizeof, &bm);
     int imgWidth = bm.bmWidth;
@@ -1015,6 +1031,7 @@
 }
 
 static Image createIcon (Image image) {
+    static_this();
     Device device = image.getDevice ();
     ImageData data = image.getImageData ();
     if (data.alpha is -1 && data.alphaData is null) {
@@ -1062,6 +1079,7 @@
 }
 
 static HBITMAP createMaskFromAlpha (ImageData data, int destWidth, int destHeight) {
+    static_this();
     int srcWidth = data.width;
     int srcHeight = data.height;
     ImageData mask = ImageData.internal_new (srcWidth, srcHeight, 1,
@@ -1093,6 +1111,7 @@
 }
 
 static synchronized void deregister (Display display) {
+    static_this();
     for (int i=0; i<Displays.length; i++) {
         if (display is Displays [i]) Displays [i] = null;
     }
@@ -1331,6 +1350,7 @@
  * @return the display for the given thread
  */
 public static synchronized Display findDisplay (Thread thread) {
+    static_this();
     for (int i=0; i<Displays.length; i++) {
         Display display = Displays [i];
         if (display !is null && display.thread is thread) {
@@ -1390,6 +1410,7 @@
  * @return the current display
  */
 public static synchronized Display getCurrent () {
+    static_this();
     return findDisplay (Thread.getThis ());
 }
 
@@ -1548,6 +1569,7 @@
  * @return the default display
  */
 public static synchronized Display getDefault () {
+    static_this();
     if (Default is null) Default = new Display ();
     return Default;
 }
@@ -3368,6 +3390,7 @@
 }
 
 static synchronized void register (Display display) {
+    static_this();
     for (int i=0; i<Displays.length; i++) {
         if (Displays [i] is null) {
             Displays [i] = display;
--- a/dwt/widgets/Group.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Group.d	Wed Feb 06 12:09:44 2008 +0100
@@ -51,47 +51,58 @@
 
     char[] text = "";
     static const int CLIENT_INSET = 3;
-    static const WNDPROC GroupProc;
+    private static /+const+/ WNDPROC GroupProc;
     static if( OS.IsWinCE ){
         static const TCHAR[] GroupClass = "BUTTON\0";
     }
     else{
         static const TCHAR[] GroupClass = "SWT_GROUP\0";
     }
-    static this() {
-        /*
-        * Feature in Windows.  The group box window class
-        * uses the CS_HREDRAW and CS_VREDRAW style bits to
-        * force a full redraw of the control and all children
-        * when resized.  This causes flashing.  The fix is to
-        * register a new window class without these bits and
-        * implement special code that damages only the control.
-        *
-        * Feature in WinCE.  On certain devices, defining
-        * a new window class which looks like BUTTON causes
-        * CreateWindowEx() to crash.  The workaround is to use
-        * the class Button directly.
-        */
-        WNDCLASS lpWndClass;
-        if (OS.IsWinCE) {
-            OS.GetClassInfo (null, GroupClass.ptr, &lpWndClass);
-            GroupProc = lpWndClass.lpfnWndProc;
-        } else {
-            TCHAR[] WC_BUTTON = "BUTTON\0";
-            OS.GetClassInfo (null, WC_BUTTON.ptr, &lpWndClass);
-            GroupProc = lpWndClass.lpfnWndProc;
-            auto hInstance = OS.GetModuleHandle (null);
-            if (!OS.GetClassInfo (hInstance, GroupClass.ptr, &lpWndClass)) {
-                auto hHeap = OS.GetProcessHeap ();
-                lpWndClass.hInstance = hInstance;
-                lpWndClass.style &= ~(OS.CS_HREDRAW | OS.CS_VREDRAW);
-                int byteCount = GroupClass.length * TCHAR.sizeof;
-                auto lpszClassName = cast(TCHAR*)OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
-                OS.MoveMemory (lpszClassName, GroupClass.ptr, byteCount);
-                lpWndClass.lpszClassName = lpszClassName;
-                OS.RegisterClass (&lpWndClass);
-                OS.HeapFree (hHeap, 0, lpszClassName);
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
             }
+            /*
+            * Feature in Windows.  The group box window class
+            * uses the CS_HREDRAW and CS_VREDRAW style bits to
+            * force a full redraw of the control and all children
+            * when resized.  This causes flashing.  The fix is to
+            * register a new window class without these bits and
+            * implement special code that damages only the control.
+            *
+            * Feature in WinCE.  On certain devices, defining
+            * a new window class which looks like BUTTON causes
+            * CreateWindowEx() to crash.  The workaround is to use
+            * the class Button directly.
+            */
+            WNDCLASS lpWndClass;
+            static if (OS.IsWinCE) {
+                OS.GetClassInfo (null, GroupClass.ptr, &lpWndClass);
+                GroupProc = lpWndClass.lpfnWndProc;
+            } else {
+                TCHAR[] WC_BUTTON = "BUTTON\0";
+                OS.GetClassInfo (null, WC_BUTTON.ptr, &lpWndClass);
+                GroupProc = lpWndClass.lpfnWndProc;
+                auto hInstance = OS.GetModuleHandle (null);
+                if (!OS.GetClassInfo (hInstance, GroupClass.ptr, &lpWndClass)) {
+                    auto hHeap = OS.GetProcessHeap ();
+                    lpWndClass.hInstance = hInstance;
+                    lpWndClass.style &= ~(OS.CS_HREDRAW | OS.CS_VREDRAW);
+                    int byteCount = GroupClass.length * TCHAR.sizeof;
+                    auto lpszClassName = cast(TCHAR*)OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
+                    OS.MoveMemory (lpszClassName, GroupClass.ptr, byteCount);
+                    lpWndClass.lpszClassName = lpszClassName;
+                    OS.RegisterClass (&lpWndClass);
+                    OS.HeapFree (hHeap, 0, lpszClassName);
+                }
+            }
+            static_this_completed = true;
         }
     }
 
@@ -128,6 +139,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/Label.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Label.d	Wed Feb 06 12:09:44 2008 +0100
@@ -60,14 +60,26 @@
     Image image;
     static const int MARGIN = 4;
     static const bool IMAGE_AND_TEXT = false;
-    static const WNDPROC LabelProc;
+    private static /+const+/ WNDPROC LabelProc;
     static const TCHAR[] LabelClass = "STATIC\0";
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, LabelClass.ptr, &lpWndClass);
-        LabelProc = lpWndClass.lpfnWndProc;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, LabelClass.ptr, &lpWndClass);
+            LabelProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
     }
 
+
 /**
  * Constructs a new instance of this class given its parent
  * and a style value describing its behavior and appearance.
@@ -106,6 +118,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/Link.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Link.d	Wed Feb 06 12:09:44 2008 +0100
@@ -74,17 +74,28 @@
     int [] mnemonics;
     int focusIndex, mouseDownIndex;
     HFONT font;
-    static const RGB LINK_FOREGROUND;
-    static const WNDPROC LinkProc;
+    static /+const+/ RGB LINK_FOREGROUND;
+    static /+const+/ WNDPROC LinkProc;
     static const TCHAR[] LinkClass = OS.WC_LINK;
-    static this() {
-        LINK_FOREGROUND = new RGB (0, 51, 153);
-        if (OS.COMCTL32_MAJOR >= 6) {
-            WNDCLASS lpWndClass;
-            OS.GetClassInfo (null, LinkClass.ptr, &lpWndClass);
-            LinkProc = lpWndClass.lpfnWndProc;
-        } else {
-            LinkProc = null;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            LINK_FOREGROUND = new RGB (0, 51, 153);
+            if (OS.COMCTL32_MAJOR >= 6) {
+                WNDCLASS lpWndClass;
+                OS.GetClassInfo (null, LinkClass.ptr, &lpWndClass);
+                LinkProc = lpWndClass.lpfnWndProc;
+            } else {
+                LinkProc = null;
+            }
+            static_this_completed = true;
         }
     }
 
@@ -116,6 +127,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, style);
 }
 
--- a/dwt/widgets/List.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/List.d	Wed Feb 06 12:09:44 2008 +0100
@@ -51,12 +51,23 @@
     alias Scrollable.windowProc windowProc;
 
     static const int INSET = 3;
-    static const WNDPROC ListProc;
+    private static /+const+/ WNDPROC ListProc;
     static const TCHAR[] ListClass = "LISTBOX";
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, ListClass.ptr, &lpWndClass);
-        ListProc = lpWndClass.lpfnWndProc;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, ListClass.ptr, &lpWndClass);
+            ListProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
     }
 
 /**
@@ -89,6 +100,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 /**
--- a/dwt/widgets/MenuItem.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/MenuItem.d	Wed Feb 06 12:09:44 2008 +0100
@@ -63,11 +63,30 @@
     * accelerator text.  The fix is to use smaller margins
     * everywhere but on Windows 98.
     */
-    const static int MARGIN_WIDTH;
-    const static int MARGIN_HEIGHT;
-    static this() {
-        MARGIN_WIDTH = OS.IsWin95 ? 2 : 1;
-        MARGIN_HEIGHT = OS.IsWin95 ? 2 : 1;
+    private static int MARGIN_WIDTH_;
+    public static int MARGIN_WIDTH(){
+        assert( static_this_completed );
+        return MARGIN_WIDTH_;
+    }
+    private static int MARGIN_HEIGHT_;
+    public static int MARGIN_HEIGHT(){
+        assert( static_this_completed );
+        return MARGIN_HEIGHT_;
+    }
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            MARGIN_WIDTH_ = OS.IsWin95 ? 2 : 1;
+            MARGIN_HEIGHT_ = OS.IsWin95 ? 2 : 1;
+            static_this_completed = true;
+        }
     }
 
 /**
@@ -105,6 +124,7 @@
  * @see Widget#getStyle
  */
 public this (Menu parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
     this.parent = parent;
     parent.createItem (this, parent.getItemCount ());
@@ -147,12 +167,14 @@
  * @see Widget#getStyle
  */
 public this (Menu parent, int style, int index) {
+    static_this();
     super (parent, checkStyle (style));
     this.parent = parent;
     parent.createItem (this, index);
 }
 
 this (Menu parent, Menu menu, int style, int index) {
+    static_this();
     super (parent, checkStyle (style));
     this.parent = parent;
     this.menu = menu;
--- a/dwt/widgets/ProgressBar.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/ProgressBar.d	Wed Feb 06 12:09:44 2008 +0100
@@ -48,40 +48,51 @@
     static const int DELAY = 100;
     static const int TIMER_ID = 100;
     static const int MINIMUM_WIDTH = 100;
-    static const WNDPROC ProgressBarProc;
+    private static /+const+/ WNDPROC ProgressBarProc;
     static const TCHAR[] ProgressBarClass = OS.PROGRESS_CLASS;
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, ProgressBarClass.ptr, &lpWndClass);
-        ProgressBarProc = lpWndClass.lpfnWndProc;
-        /*
-        * Feature in Windows.  The progress bar window class
-        * does not include CS_DBLCLKS.  This mean that these
-        * controls will not get double click messages such as
-        * WM_LBUTTONDBLCLK.  The fix is to register a new
-        * window class with CS_DBLCLKS.
-        *
-        * NOTE:  Screen readers look for the exact class name
-        * of the control in order to provide the correct kind
-        * of assistance.  Therefore, it is critical that the
-        * new window class have the same name.  It is possible
-        * to register a local window class with the same name
-        * as a global class.  Since bits that affect the class
-        * are being changed, it is possible that other native
-        * code, other than DWT, could create a control with
-        * this class name, and fail unexpectedly.
-        */
-        auto hInstance = OS.GetModuleHandle (null);
-        auto hHeap = OS.GetProcessHeap ();
-        lpWndClass.hInstance = hInstance;
-        lpWndClass.style &= ~OS.CS_GLOBALCLASS;
-        lpWndClass.style |= OS.CS_DBLCLKS;
-        int byteCount = (ProgressBarClass.length+1) * TCHAR.sizeof;
-        TCHAR* lpszClassName = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
-        OS.MoveMemory (lpszClassName, ProgressBarClass.ptr, byteCount);
-        lpWndClass.lpszClassName = lpszClassName;
-        OS.RegisterClass (&lpWndClass);
-        OS.HeapFree (hHeap, 0, lpszClassName);
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, ProgressBarClass.ptr, &lpWndClass);
+            ProgressBarProc = lpWndClass.lpfnWndProc;
+            /*
+            * Feature in Windows.  The progress bar window class
+            * does not include CS_DBLCLKS.  This mean that these
+            * controls will not get double click messages such as
+            * WM_LBUTTONDBLCLK.  The fix is to register a new
+            * window class with CS_DBLCLKS.
+            *
+            * NOTE:  Screen readers look for the exact class name
+            * of the control in order to provide the correct kind
+            * of assistance.  Therefore, it is critical that the
+            * new window class have the same name.  It is possible
+            * to register a local window class with the same name
+            * as a global class.  Since bits that affect the class
+            * are being changed, it is possible that other native
+            * code, other than DWT, could create a control with
+            * this class name, and fail unexpectedly.
+            */
+            auto hInstance = OS.GetModuleHandle (null);
+            auto hHeap = OS.GetProcessHeap ();
+            lpWndClass.hInstance = hInstance;
+            lpWndClass.style &= ~OS.CS_GLOBALCLASS;
+            lpWndClass.style |= OS.CS_DBLCLKS;
+            int byteCount = (ProgressBarClass.length+1) * TCHAR.sizeof;
+            TCHAR* lpszClassName = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
+            OS.MoveMemory (lpszClassName, ProgressBarClass.ptr, byteCount);
+            lpWndClass.lpszClassName = lpszClassName;
+            OS.RegisterClass (&lpWndClass);
+            OS.HeapFree (hHeap, 0, lpszClassName);
+            static_this_completed = true;
+        }
     }
 
 /**
@@ -115,6 +126,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/Scale.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Scale.d	Wed Feb 06 12:09:44 2008 +0100
@@ -51,40 +51,51 @@
     alias Control.windowProc windowProc;
 
     bool ignoreResize;
-    static const WNDPROC TrackBarProc;
+    private static /+const+/ WNDPROC TrackBarProc;
     static const TCHAR[] TrackBarClass = OS.TRACKBAR_CLASS;
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, TrackBarClass.ptr, &lpWndClass);
-        TrackBarProc = lpWndClass.lpfnWndProc;
-        /*
-        * Feature in Windows.  The track bar window class
-        * does not include CS_DBLCLKS.  This mean that these
-        * controls will not get double click messages such as
-        * WM_LBUTTONDBLCLK.  The fix is to register a new
-        * window class with CS_DBLCLKS.
-        *
-        * NOTE:  Screen readers look for the exact class name
-        * of the control in order to provide the correct kind
-        * of assistance.  Therefore, it is critical that the
-        * new window class have the same name.  It is possible
-        * to register a local window class with the same name
-        * as a global class.  Since bits that affect the class
-        * are being changed, it is possible that other native
-        * code, other than DWT, could create a control with
-        * this class name, and fail unexpectedly.
-        */
-        auto hInstance = OS.GetModuleHandle (null);
-        auto hHeap = OS.GetProcessHeap ();
-        lpWndClass.hInstance = hInstance;
-        lpWndClass.style &= ~OS.CS_GLOBALCLASS;
-        lpWndClass.style |= OS.CS_DBLCLKS;
-        int byteCount = (TrackBarClass.length+1) * TCHAR.sizeof;
-        auto lpszClassName = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
-        OS.MoveMemory (lpszClassName, TrackBarClass.ptr, byteCount);
-        lpWndClass.lpszClassName = lpszClassName;
-        OS.RegisterClass (&lpWndClass);
-        OS.HeapFree (hHeap, 0, lpszClassName);
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, TrackBarClass.ptr, &lpWndClass);
+            TrackBarProc = lpWndClass.lpfnWndProc;
+            /*
+            * Feature in Windows.  The track bar window class
+            * does not include CS_DBLCLKS.  This mean that these
+            * controls will not get double click messages such as
+            * WM_LBUTTONDBLCLK.  The fix is to register a new
+            * window class with CS_DBLCLKS.
+            *
+            * NOTE:  Screen readers look for the exact class name
+            * of the control in order to provide the correct kind
+            * of assistance.  Therefore, it is critical that the
+            * new window class have the same name.  It is possible
+            * to register a local window class with the same name
+            * as a global class.  Since bits that affect the class
+            * are being changed, it is possible that other native
+            * code, other than DWT, could create a control with
+            * this class name, and fail unexpectedly.
+            */
+            auto hInstance = OS.GetModuleHandle (null);
+            auto hHeap = OS.GetProcessHeap ();
+            lpWndClass.hInstance = hInstance;
+            lpWndClass.style &= ~OS.CS_GLOBALCLASS;
+            lpWndClass.style |= OS.CS_DBLCLKS;
+            int byteCount = (TrackBarClass.length+1) * TCHAR.sizeof;
+            auto lpszClassName = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
+            OS.MoveMemory (lpszClassName, TrackBarClass.ptr, byteCount);
+            lpWndClass.lpszClassName = lpszClassName;
+            OS.RegisterClass (&lpWndClass);
+            OS.HeapFree (hHeap, 0, lpszClassName);
+            static_this_completed = true;
+        }
     }
 
 /**
@@ -117,6 +128,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/Shell.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Shell.d	Wed Feb 06 12:09:44 2008 +0100
@@ -146,15 +146,14 @@
     char[] toolTitle, balloonTitle;
     HICON toolIcon;
     HICON balloonIcon;
-    alias extern(Windows) int function(HWND, uint, uint, int) TWindowProc;
-    TWindowProc windowProc_;
+    WNDPROC windowProc_;
     Control lastActive, lockToolTipControl;
     static if( OS.IsWinCE ){
         SHACTIVATEINFO psai;
     }
     Region region;
-    static /*final*/ TWindowProc ToolTipProc;
-    static const TWindowProc DialogProc;
+    static /+const+/ WNDPROC ToolTipProc;
+    static /+const+/ WNDPROC DialogProc;
     static if( OS.IsWinCE ){
         static const TCHAR[] DialogClass = "Dialog\0";
     }
@@ -170,10 +169,21 @@
         OS.COLOR_SCROLLBAR,
     ];
     final static int BRUSHES_SIZE = 32;
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, DialogClass.ptr, &lpWndClass);
-        DialogProc = lpWndClass.lpfnWndProc;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, DialogClass.ptr, &lpWndClass);
+            DialogProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
     }
 
 /**
@@ -299,6 +309,7 @@
 }
 
 this (Display display, Shell parent, int style, HWND handle, bool embedded) {
+    static_this();
     super ();
     checkSubclass ();
     if (display is null) display = Display.getCurrent ();
@@ -522,7 +533,7 @@
         null);
     if (balloonTipHandle_ is null) error (DWT.ERROR_NO_HANDLES);
     if (ToolTipProc is null) {
-        ToolTipProc = cast(TWindowProc) OS.GetWindowLong (balloonTipHandle_, OS.GWL_WNDPROC);
+        ToolTipProc = cast(WNDPROC) OS.GetWindowLong (balloonTipHandle_, OS.GWL_WNDPROC);
     }
     /*
     * Feature in Windows.  Despite the fact that the
@@ -558,7 +569,7 @@
         if ((style & (DWT.H_SCROLL | DWT.V_SCROLL)) is 0) {
             state |= THEME_BACKGROUND;
         }
-        windowProc_ = cast(TWindowProc) OS.GetWindowLong (handle, OS.GWL_WNDPROC);
+        windowProc_ = cast(WNDPROC) OS.GetWindowLong (handle, OS.GWL_WNDPROC);
     }
 
     /*
@@ -630,7 +641,7 @@
         null);
     if (toolTipHandle_ is null) error (DWT.ERROR_NO_HANDLES);
     if (ToolTipProc is null) {
-        ToolTipProc = cast(TWindowProc) OS.GetWindowLong (toolTipHandle_, OS.GWL_WNDPROC);
+        ToolTipProc = cast(WNDPROC) OS.GetWindowLong (toolTipHandle_, OS.GWL_WNDPROC);
     }
     /*
     * Feature in Windows.  Despite the fact that the
--- a/dwt/widgets/Slider.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Slider.d	Wed Feb 06 12:09:44 2008 +0100
@@ -82,12 +82,23 @@
 
     int increment, pageIncrement;
     bool ignoreFocus;
-    static const WNDPROC ScrollBarProc;
+    static /+const+/ WNDPROC ScrollBarProc;
     static const TCHAR[] ScrollBarClass = "SCROLLBAR";
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, ScrollBarClass.ptr, &lpWndClass);
-        ScrollBarProc = lpWndClass.lpfnWndProc;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, ScrollBarClass.ptr, &lpWndClass);
+            ScrollBarProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
     }
 
 /**
@@ -120,6 +131,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/Spinner.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Spinner.d	Wed Feb 06 12:09:44 2008 +0100
@@ -65,18 +65,30 @@
     HWND hwndText, hwndUpDown;
     bool ignoreModify;
     int pageIncrement, digits;
-    static const WNDPROC EditProc;
+    static /+const+/ WNDPROC EditProc;
     static const TCHAR[] EditClass = "EDIT";
-    static const WNDPROC UpDownProc;
+    static /+const+/ WNDPROC UpDownProc;
     static const TCHAR[] UpDownClass = OS.UPDOWN_CLASS;
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, EditClass.ptr, &lpWndClass);
-        EditProc = lpWndClass.lpfnWndProc;
-        OS.GetClassInfo (null, UpDownClass.ptr, &lpWndClass);
-        UpDownProc = lpWndClass.lpfnWndProc;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, EditClass.ptr, &lpWndClass);
+            EditProc = lpWndClass.lpfnWndProc;
+            OS.GetClassInfo (null, UpDownClass.ptr, &lpWndClass);
+            UpDownProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
     }
 
+
 /**
  * Constructs a new instance of this class given its parent
  * and a style value describing its behavior and appearance.
@@ -107,6 +119,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/TabFolder.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/TabFolder.d	Wed Feb 06 12:09:44 2008 +0100
@@ -64,7 +64,7 @@
 
     TabItem [] items;
     ImageList imageList;
-    static const WNDPROC TabFolderProc;
+    private static /+const+/ WNDPROC TabFolderProc;
     static const TCHAR[] TabFolderClass = OS.WC_TABCONTROL;
 
     /*
@@ -74,39 +74,49 @@
     */
     static const int ID_UPDOWN = 1;
 
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, TabFolderClass.ptr, &lpWndClass);
-        TabFolderProc = lpWndClass.lpfnWndProc;
-        /*
-        * Feature in Windows.  The tab control window class
-        * uses the CS_HREDRAW and CS_VREDRAW style bits to
-        * force a full redraw of the control and all children
-        * when resized.  This causes flashing.  The fix is to
-        * register a new window class without these bits and
-        * implement special code that damages only the exposed
-        * area.
-        *
-        * NOTE:  Screen readers look for the exact class name
-        * of the control in order to provide the correct kind
-        * of assistance.  Therefore, it is critical that the
-        * new window class have the same name.  It is possible
-        * to register a local window class with the same name
-        * as a global class.  Since bits that affect the class
-        * are being changed, it is possible that other native
-        * code, other than DWT, could create a control with
-        * this class name, and fail unexpectedly.
-        */
-        auto hInstance = OS.GetModuleHandle (null);
-        auto hHeap = OS.GetProcessHeap ();
-        lpWndClass.hInstance = hInstance;
-        lpWndClass.style &= ~(OS.CS_HREDRAW | OS.CS_VREDRAW | OS.CS_GLOBALCLASS);
-        int byteCount = (TabFolderClass.length+1) * TCHAR.sizeof;
-        auto lpszClassName = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
-        OS.MoveMemory (lpszClassName, TabFolderClass.ptr, byteCount);
-        lpWndClass.lpszClassName = lpszClassName;
-        OS.RegisterClass (&lpWndClass);
-        OS.HeapFree (hHeap, 0, lpszClassName);
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, TabFolderClass.ptr, &lpWndClass);
+            TabFolderProc = lpWndClass.lpfnWndProc;
+            /*
+            * Feature in Windows.  The tab control window class
+            * uses the CS_HREDRAW and CS_VREDRAW style bits to
+            * force a full redraw of the control and all children
+            * when resized.  This causes flashing.  The fix is to
+            * register a new window class without these bits and
+            * implement special code that damages only the exposed
+            * area.
+            *
+            * NOTE:  Screen readers look for the exact class name
+            * of the control in order to provide the correct kind
+            * of assistance.  Therefore, it is critical that the
+            * new window class have the same name.  It is possible
+            * to register a local window class with the same name
+            * as a global class.  Since bits that affect the class
+            * are being changed, it is possible that other native
+            * code, other than DWT, could create a control with
+            * this class name, and fail unexpectedly.
+            */
+            auto hInstance = OS.GetModuleHandle (null);
+            auto hHeap = OS.GetProcessHeap ();
+            lpWndClass.hInstance = hInstance;
+            lpWndClass.style &= ~(OS.CS_HREDRAW | OS.CS_VREDRAW | OS.CS_GLOBALCLASS);
+            int byteCount = (TabFolderClass.length+1) * TCHAR.sizeof;
+            auto lpszClassName = cast(TCHAR*) OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
+            OS.MoveMemory (lpszClassName, TabFolderClass.ptr, byteCount);
+            lpWndClass.lpszClassName = lpszClassName;
+            OS.RegisterClass (&lpWndClass);
+            OS.HeapFree (hHeap, 0, lpszClassName);
+            static_this_completed = true;
+        }
     }
 
 /**
@@ -138,6 +148,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/Table.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Table.d	Wed Feb 06 12:09:44 2008 +0100
@@ -110,12 +110,23 @@
     static const int VISTA_EXTRA = 2;
     static const int EXPLORER_EXTRA = 2;
     static const bool EXPLORER_THEME = true;
-    static const WNDPROC TableProc;
+    private static /+const+/ WNDPROC TableProc;
     static const TCHAR[] TableClass = OS.WC_LISTVIEW;
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, TableClass.ptr, &lpWndClass);
-        TableProc = lpWndClass.lpfnWndProc;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, TableClass.ptr, &lpWndClass);
+            TableProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
     }
 
 /**
@@ -152,6 +163,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/Text.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Text.d	Wed Feb 06 12:09:44 2008 +0100
@@ -69,14 +69,18 @@
     * the native widget implementation.
     * </p>
     */
-    public static const int LIMIT;
+    private static int LIMIT_;
+    public static int LIMIT(){
+        assert( static_this_completed );
+        return LIMIT_;
+    }
 
     /**
     * The delimiter used by multi-line text widgets.  When text
     * is queried and from the widget, it will be delimited using
     * this delimiter.
     */
-    public static const char[] DELIMITER;
+    public static const char[] DELIMITER = "\r\n";
 
     /*
     * This code is intentionally commented.
@@ -89,29 +93,39 @@
     * to stop the compiler from inlining.
     */
 
-    static const WNDPROC EditProc;
+    private static /+const+/ WNDPROC EditProc;
     static const TCHAR[] EditClass = "EDIT\0";
-    static this() {
-        LIMIT = OS.IsWinNT ? 0x7FFFFFFF : 0x7FFF;
-        DELIMITER = "\r\n";
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, EditClass.ptr, &lpWndClass);
-        EditProc = lpWndClass.lpfnWndProc;
-        /*
-        * This code is intentionally commented.
-        */
-//      int hwndText = OS.CreateWindowEx (0,
-//          EditClass,
-//          null,
-//          OS.WS_OVERLAPPED | OS.ES_PASSWORD,
-//          0, 0, 0, 0,
-//          0,
-//          0,
-//          OS.GetModuleHandle (null),
-//          null);
-//      char echo = (char) OS.SendMessage (hwndText, OS.EM_GETPASSWORDCHAR, 0, 0);
-//      OS.DestroyWindow (hwndText);
-//      PASSWORD = echo !is 0 ? echo : '*';
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            LIMIT_ = OS.IsWinNT ? 0x7FFFFFFF : 0x7FFF;
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, EditClass.ptr, &lpWndClass);
+            EditProc = lpWndClass.lpfnWndProc;
+            /*
+            * This code is intentionally commented.
+            */
+    //      int hwndText = OS.CreateWindowEx (0,
+    //          EditClass,
+    //          null,
+    //          OS.WS_OVERLAPPED | OS.ES_PASSWORD,
+    //          0, 0, 0, 0,
+    //          0,
+    //          0,
+    //          OS.GetModuleHandle (null),
+    //          null);
+    //      char echo = (char) OS.SendMessage (hwndText, OS.EM_GETPASSWORDCHAR, 0, 0);
+    //      OS.DestroyWindow (hwndText);
+    //      PASSWORD = echo !is 0 ? echo : '*';
+            static_this_completed = true;
+        }
     }
 
 /**
@@ -146,6 +160,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/ToolBar.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/ToolBar.d	Wed Feb 06 12:09:44 2008 +0100
@@ -63,14 +63,28 @@
     ToolItem [] items;
     bool ignoreResize, ignoreMouse;
     ImageList imageList, disabledImageList, hotImageList;
-    static const WNDPROC ToolBarProc;
+    private static /+const+/ WNDPROC ToolBarProc;
     static const TCHAR[] ToolBarClass = OS.TOOLBARCLASSNAME;
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, ToolBarClass.ptr, &lpWndClass);
-        ToolBarProc = lpWndClass.lpfnWndProc;
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, ToolBarClass.ptr, &lpWndClass);
+            ToolBarProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
     }
 
+
+
+
     /*
     * From the Windows SDK for TB_SETBUTTONSIZE:
     *
@@ -115,6 +129,7 @@
  * @see Widget#getStyle()
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
     /*
     * Ensure that either of HORIZONTAL or VERTICAL is set.
--- a/dwt/widgets/Tree.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Tree.d	Wed Feb 06 12:09:44 2008 +0100
@@ -126,17 +126,29 @@
     static const int INCREMENT = 5;
     static const int EXPLORER_EXTRA = 2;
     static const bool EXPLORER_THEME = true;
-    static const WNDPROC TreeProc;
+    private static /+const+/ WNDPROC TreeProc;
     static const TCHAR[] TreeClass = OS.WC_TREEVIEW;
-    static const WNDPROC HeaderProc;
+    private static /+const+/ WNDPROC HeaderProc;
     static const TCHAR[] HeaderClass = OS.WC_HEADER;
-    static this() {
-        WNDCLASS lpWndClass;
-        OS.GetClassInfo (null, TreeClass.ptr, &lpWndClass);
-        TreeProc = lpWndClass.lpfnWndProc;
-        OS.GetClassInfo (null, HeaderClass.ptr, &lpWndClass);
-        HeaderProc = lpWndClass.lpfnWndProc;
-    }
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
+            }
+            WNDCLASS lpWndClass;
+            OS.GetClassInfo (null, TreeClass.ptr, &lpWndClass);
+            TreeProc = lpWndClass.lpfnWndProc;
+            OS.GetClassInfo (null, HeaderClass.ptr, &lpWndClass);
+            HeaderProc = lpWndClass.lpfnWndProc;
+            static_this_completed = true;
+        }
+    }
+
     private static Tree sThis;
 /**
  * Constructs a new instance of this class given its parent
@@ -169,6 +181,7 @@
  * @see Widget#getStyle
  */
 public this (Composite parent, int style) {
+    static_this();
     super (parent, checkStyle (style));
 }
 
--- a/dwt/widgets/Widget.d	Wed Feb 06 11:08:01 2008 +0100
+++ b/dwt/widgets/Widget.d	Wed Feb 06 12:09:44 2008 +0100
@@ -108,20 +108,32 @@
 
     /* Check and initialize the Common Controls DLL */
     static const int MAJOR = 5, MINOR = 80;
-    static this() {
-        static if (!OS.IsWinCE) {
-            if (OS.COMCTL32_VERSION < OS.VERSION (MAJOR, MINOR)) {
-                Stdout.formatln ("***WARNING: DWT requires comctl32.dll version {}.{} or greater", MAJOR, MINOR); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-                Stdout.formatln ("***WARNING: Detected: {}.{}", OS.COMCTL32_MAJOR, OS.COMCTL32_MINOR); //$NON-NLS-1$ //$NON-NLS-2$
+
+    private static bool static_this_completed = false;
+    private static void static_this() {
+        if( static_this_completed ){
+            return;
+        }
+        synchronized {
+            if( static_this_completed ){
+                return;
             }
+            static if (!OS.IsWinCE) {
+                if (OS.COMCTL32_VERSION < OS.VERSION (MAJOR, MINOR)) {
+                    Stdout.formatln ("***WARNING: DWT requires comctl32.dll version {}.{} or greater", MAJOR, MINOR); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                    Stdout.formatln ("***WARNING: Detected: {}.{}", OS.COMCTL32_MAJOR, OS.COMCTL32_MINOR); //$NON-NLS-1$ //$NON-NLS-2$
+                }
+            }
+            OS.InitCommonControls ();
+            static_this_completed = true;
         }
-        OS.InitCommonControls ();
     }
 
 /**
  * Prevents uninitialized instances from being created outside the package.
  */
 this () {
+    static_this();
 }
 
 /**
@@ -154,6 +166,7 @@
  * @see #getStyle
  */
 public this (Widget parent, int style) {
+    static_this();
     checkSubclass ();
     checkParent (parent);
     this.style = style;