diff --git a/dlangui.visualdproj b/dlangui.visualdproj
index ced817a2..7dd16d7a 100644
--- a/dlangui.visualdproj
+++ b/dlangui.visualdproj
@@ -84,7 +84,7 @@
   <objfiles />
   <linkswitches />
   <libfiles>ole32.lib kernel32.lib user32.lib comctl32.lib comdlg32.lib</libfiles>
-  <libpaths />
+  <libpaths>3rdparty/libpng/lib</libpaths>
   <deffile />
   <resfile />
   <exefile>$(OutDir)\$(ProjectName).exe</exefile>
@@ -191,6 +191,9 @@
  <Folder name="dlangui">
   <Folder name="3rdparty">
    <Folder name="libpng">
+    <Folder name="libs">
+     <File path="3rdparty\libpng\lib\libpng15.lib" />
+    </Folder>
     <File path="3rdparty\libpng\source\libpng\png.d" />
     <File path="3rdparty\libpng\source\libpng\pngconf.d" />
     <File path="3rdparty\libpng\source\libpng\pnglibconf.d" />
diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d
index 730404db..15ce9795 100644
--- a/src/dlangui/platforms/windows/winapp.d
+++ b/src/dlangui/platforms/windows/winapp.d
@@ -1,76 +1,77 @@
-module dlangui.platforms.windows.winapp;
-
-version (Windows) {
-
-import core.runtime;
-import win32.windows;
-import std.string;
-import std.utf;
-import std.stdio;
-import std.algorithm;
-import dlangui.platforms.common.platform;
-import dlangui.graphics.drawbuf;
-import dlangui.graphics.fonts;
-import dlangui.core.logger;
-
-pragma(lib, "gdi32.lib");
-pragma(lib, "user32.lib");
-
-struct FontDef {
-    immutable FontFamily _family;
-    immutable string _face;
-	immutable ubyte _pitchAndFamily;
-	@property FontFamily family() { return _family; }
-	@property string face() { return _face; }
-	@property ubyte pitchAndFamily() { return _pitchAndFamily; }
-	this(FontFamily family, string face, ubyte putchAndFamily) {
-		_family = family;
-		_face = face;
-		_pitchAndFamily = pitchAndFamily;
-	}
-}
-
-/**
-* Font implementation based on Win32 API system fonts.
-*/
-class Win32Font : Font {
-    HFONT _hfont;
-    int _size;
-    int _height;
-    int _weight;
-    int _baseline;
-    bool _italic;
-    string _face;
-    FontFamily _family;
-    LOGFONTA _logfont;
-    Win32ColorDrawBuf _drawbuf;
-	GlyphCache _glyphCache;
-
-	/// need to call create() after construction to initialize font
-    this() {
-    }
-
-	/// do cleanup
-	~this() {
-		clear();
-	}
-
-	/// cleanup resources
-    override void clear() {
-        if (_hfont !is null)
-        {
-            DeleteObject(_hfont);
-            _hfont = NULL;
-            _height = 0;
-            _baseline = 0;
-            _size = 0;
-        }
-		if (_drawbuf !is null) {
-			destroy(_drawbuf);
-			_drawbuf = null;
-		}
-    }
-
+module dlangui.platforms.windows.winapp;
+
+version (Windows) {
+
+import core.runtime;
+import win32.windows;
+import std.string;
+import std.utf;
+import std.stdio;
+import std.algorithm;
+import dlangui.platforms.common.platform;
+import dlangui.graphics.drawbuf;
+import dlangui.graphics.fonts;
+import dlangui.core.logger;
+
+pragma(lib, "gdi32.lib");
+pragma(lib, "user32.lib");
+pragma(lib, "libpng15.lib");
+
+struct FontDef {
+    immutable FontFamily _family;
+    immutable string _face;
+	immutable ubyte _pitchAndFamily;
+	@property FontFamily family() { return _family; }
+	@property string face() { return _face; }
+	@property ubyte pitchAndFamily() { return _pitchAndFamily; }
+	this(FontFamily family, string face, ubyte putchAndFamily) {
+		_family = family;
+		_face = face;
+		_pitchAndFamily = pitchAndFamily;
+	}
+}
+
+/**
+* Font implementation based on Win32 API system fonts.
+*/
+class Win32Font : Font {
+    HFONT _hfont;
+    int _size;
+    int _height;
+    int _weight;
+    int _baseline;
+    bool _italic;
+    string _face;
+    FontFamily _family;
+    LOGFONTA _logfont;
+    Win32ColorDrawBuf _drawbuf;
+	GlyphCache _glyphCache;
+
+	/// need to call create() after construction to initialize font
+    this() {
+    }
+
+	/// do cleanup
+	~this() {
+		clear();
+	}
+
+	/// cleanup resources
+    override void clear() {
+        if (_hfont !is null)
+        {
+            DeleteObject(_hfont);
+            _hfont = NULL;
+            _height = 0;
+            _baseline = 0;
+            _size = 0;
+        }
+		if (_drawbuf !is null) {
+			destroy(_drawbuf);
+			_drawbuf = null;
+		}
+    }
+
 	uint getGlyphIndex(dchar code)
 	{
 		if (_drawbuf is null)
@@ -102,15 +103,15 @@ class Win32Font : Font {
 		return g[0];
 	}
 
-	override Glyph * getCharGlyph(dchar ch) {
-		uint glyphIndex = getGlyphIndex(ch);
-		if (!glyphIndex)
-			return null;
-		if (glyphIndex >= 0xFFFF)
-			return null;
-		Glyph * found = _glyphCache.find(cast(ushort)glyphIndex);
-		if (found !is null)
-			return found;
+	override Glyph * getCharGlyph(dchar ch) {
+		uint glyphIndex = getGlyphIndex(ch);
+		if (!glyphIndex)
+			return null;
+		if (glyphIndex >= 0xFFFF)
+			return null;
+		Glyph * found = _glyphCache.find(cast(ushort)glyphIndex);
+		if (found !is null)
+			return found;
 		GLYPHMETRICS metrics;
 
 		MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
@@ -182,17 +183,17 @@ class Win32Font : Font {
 		}
 		// found!
 		return _glyphCache.put(cast(ushort)glyphIndex, &g);
-	}
-
-	// draw text string to buffer
-	override void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color) {
-		int[] widths;
-		int charsMeasured = measureText(text, widths, 3000);
-		for (int i = 0; i < charsMeasured; i++) {
-			int xx = (i > 0) ? widths[i - 1] : 0;
-			Glyph * glyph = getCharGlyph(text[i]);
-			if (glyph is null)
-				continue;
+	}
+
+	// draw text string to buffer
+	override void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color) {
+		int[] widths;
+		int charsMeasured = measureText(text, widths, 3000);
+		for (int i = 0; i < charsMeasured; i++) {
+			int xx = (i > 0) ? widths[i - 1] : 0;
+			Glyph * glyph = getCharGlyph(text[i]);
+			if (glyph is null)
+				continue;
 			if ( glyph.blackBoxX && glyph.blackBoxY ) {
 				buf.drawGlyph( x + xx + glyph.originX,
 						   y + _baseline - glyph.originY,
@@ -201,15 +202,15 @@ class Win32Font : Font {
 						  glyph.blackBoxY,
 						  color);
 			}
-		}
-	}
-
-	override int measureText(const dchar[] text, ref int[] widths, int maxWidth) {
-		if (_hfont is null || _drawbuf is null || text.length == 0)
-			return 0;
-		wstring utf16text = toUTF16(text);
-		const wchar * pstr = utf16text.ptr;
-		uint len = cast(uint)utf16text.length;
+		}
+	}
+
+	override int measureText(const dchar[] text, ref int[] widths, int maxWidth) {
+		if (_hfont is null || _drawbuf is null || text.length == 0)
+			return 0;
+		wstring utf16text = toUTF16(text);
+		const wchar * pstr = utf16text.ptr;
+		uint len = cast(uint)utf16text.length;
 		GCP_RESULTSW gcpres;
 		gcpres.lStructSize = gcpres.sizeof;
 		if (widths.length < len + 1)
@@ -236,39 +237,39 @@ class Win32Font : Font {
 			widths[i] = total;
 		}
 		return measured;
-	}
-
-	bool create(FontDef * def, int size, int weight, bool italic) {
-        if (!isNull())
-            clear();
-		LOGFONTA lf;
-        lf.lfCharSet = ANSI_CHARSET; //DEFAULT_CHARSET;
-		lf.lfFaceName[0..def.face.length] = def.face;
-		lf.lfFaceName[def.face.length] = 0;
-		lf.lfHeight = -size;
-		lf.lfItalic = italic;
-		lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
-		lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
-		lf.lfQuality = ANTIALIASED_QUALITY;
-		lf.lfPitchAndFamily = def.pitchAndFamily;
-        _hfont = CreateFontIndirectA(&lf);
-        _drawbuf = new Win32ColorDrawBuf(1, 1);
-        SelectObject(_drawbuf.dc, _hfont);
-
-        TEXTMETRICW tm;
-        GetTextMetricsW(_drawbuf.dc, &tm);
-
-		_size = size;
-        _height = tm.tmHeight;
-        _baseline = _height - tm.tmDescent;
-        _weight = weight;
-        _italic = italic;
-        _face = def.face;
-        _family = def.family;
-		Log.d("Created font ", _face, " ", _size);
-		return true;
-	}
-
+	}
+
+	bool create(FontDef * def, int size, int weight, bool italic) {
+        if (!isNull())
+            clear();
+		LOGFONTA lf;
+        lf.lfCharSet = ANSI_CHARSET; //DEFAULT_CHARSET;
+		lf.lfFaceName[0..def.face.length] = def.face;
+		lf.lfFaceName[def.face.length] = 0;
+		lf.lfHeight = -size;
+		lf.lfItalic = italic;
+		lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
+		lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+		lf.lfQuality = ANTIALIASED_QUALITY;
+		lf.lfPitchAndFamily = def.pitchAndFamily;
+        _hfont = CreateFontIndirectA(&lf);
+        _drawbuf = new Win32ColorDrawBuf(1, 1);
+        SelectObject(_drawbuf.dc, _hfont);
+
+        TEXTMETRICW tm;
+        GetTextMetricsW(_drawbuf.dc, &tm);
+
+		_size = size;
+        _height = tm.tmHeight;
+        _baseline = _height - tm.tmDescent;
+        _weight = weight;
+        _italic = italic;
+        _face = def.face;
+        _family = def.family;
+		Log.d("Created font ", _face, " ", _size);
+		return true;
+	}
+
 	// clear usage flags for all entries
 	override void checkpoint() {
 		_glyphCache.checkpoint();
@@ -278,146 +279,146 @@ class Win32Font : Font {
 	override void cleanup() {
 		_glyphCache.cleanup();
 	}
-
-    @property override int size() { return _size; }
-    @property override int height() { return _height; }
-    @property override int weight() { return _weight; }
-    @property override int baseline() { return _baseline; }
-    @property override bool italic() { return _italic; }
-    @property override string face() { return _face; }
-    @property override FontFamily family() { return _family; }
-    @property override bool isNull() { return _hfont is null; }
-}
-
-
-/**
- * Font manager implementation based on Win32 API system fonts.
- */
-class Win32FontManager : FontManager {
-	FontList _activeFonts;
-	FontDef[] _fontFaces;
-	FontDef*[string] _faceByName;
-
-	/// initialize in constructor
-    this() {
-        instance = this;
-        init();
-    }
-
-	/// initialize font manager by enumerating of system fonts
-    bool init() {
-		Log.i("Win32FontManager.init()");
-        Win32ColorDrawBuf drawbuf = new Win32ColorDrawBuf(1,1);
-        LOGFONTA lf;
-        lf.lfCharSet = ANSI_CHARSET; //DEFAULT_CHARSET;
-		lf.lfFaceName[0] = 0;
-		HDC dc = drawbuf.dc;
-        int res = 
-            EnumFontFamiliesExA(
-                                dc,                  // handle to DC
-                                &lf,                              // font information
-                                &LVWin32FontEnumFontFamExProc, // callback function (FONTENUMPROC)
-                                cast(LPARAM)(cast(void*)this),                    // additional data
-                                0U                     // not used; must be 0
-                                    );
-		destroy(drawbuf);
-		Log.i("Found ", _fontFaces.length, " font faces");
-        return res!=0;
-    }
-
-	/// for returning of not found font
-	FontRef _emptyFontRef;
-
-	/// get font by properties
-    override ref FontRef getFont(int size, int weight, bool italic, FontFamily family, string face) {
-		Log.i("getFont()");
-		FontDef * def = findFace(family, face);
-		if (def !is null) {
-			int index = _activeFonts.find(size, weight, italic, def.family, def.face);
-			if (index >= 0)
-				return _activeFonts.get(index);
-			Log.d("Creating new font");
-			Win32Font item = new Win32Font();
-			if (!item.create(def, size, weight, italic))
-				return _emptyFontRef;
-			Log.d("Adding to list of active fonts");
-			return _activeFonts.add(item);
-		} else {
-			return _emptyFontRef;
-		}
-    }
-
-	/// find font face definition by family only (try to get one of defaults for family if possible)
-	FontDef * findFace(FontFamily family) {
-		FontDef * res = null;
-		switch(family) {
-		case FontFamily.SansSerif:
-			res = findFace("Arial"); if (res !is null) return res;
-			res = findFace("Tahoma"); if (res !is null) return res;
-			res = findFace("Calibri"); if (res !is null) return res;
-			res = findFace("Verdana"); if (res !is null) return res;
-			res = findFace("Lucida Sans"); if (res !is null) return res;
-			break;
-		case FontFamily.Serif:
-			res = findFace("Times New Roman"); if (res !is null) return res;
-			res = findFace("Georgia"); if (res !is null) return res;
-			res = findFace("Century Schoolbook"); if (res !is null) return res;
-			res = findFace("Bookman Old Style"); if (res !is null) return res;
-			break;
-		case FontFamily.MonoSpace:
-			res = findFace("Courier New"); if (res !is null) return res;
-			res = findFace("Lucida Console"); if (res !is null) return res;
-			res = findFace("Century Schoolbook"); if (res !is null) return res;
-			res = findFace("Bookman Old Style"); if (res !is null) return res;
-			break;
-		case FontFamily.Cursive:
-			res = findFace("Comic Sans MS"); if (res !is null) return res;
-			res = findFace("Lucida Handwriting"); if (res !is null) return res;
-			res = findFace("Monotype Corsiva"); if (res !is null) return res;
-			break;
-		default:
-			break;
-		}
-		return null;
-	}
-
-	/// find font face definition by face only
-	FontDef * findFace(string face) {
-		if (face.length == 0)
-			return null;
-		if (face in _faceByName)
-			return _faceByName[face];
-		return null;
-	}
-
-	/// find font face definition by family and face
-	FontDef * findFace(FontFamily family, string face) {
-		// by face only
-		FontDef * res = findFace(face);
-		if (res !is null)
-			return res;
-		// best for family
-		res = findFace(family);
-		if (res !is null)
-			return res;
-		for (int i = 0; i < _fontFaces.length; i++) {
-			res = &_fontFaces[i];
-			if (res.family == family)
-				return res;
-		}
-		res = findFace(FontFamily.SansSerif);
-		if (res !is null)
-			return res;
-		return &_fontFaces[0];
-	}
-
-	/// register enumerated font
-    bool registerFont(FontFamily family, string fontFace, ubyte pitchAndFamily) {
-		Log.d("registerFont(", family, ",", fontFace, ")");
-		_fontFaces ~= FontDef(family, fontFace, pitchAndFamily);
-		_faceByName[fontFace] = &_fontFaces[$ - 1];
-        return true;
-    }
+
+    @property override int size() { return _size; }
+    @property override int height() { return _height; }
+    @property override int weight() { return _weight; }
+    @property override int baseline() { return _baseline; }
+    @property override bool italic() { return _italic; }
+    @property override string face() { return _face; }
+    @property override FontFamily family() { return _family; }
+    @property override bool isNull() { return _hfont is null; }
+}
+
+
+/**
+ * Font manager implementation based on Win32 API system fonts.
+ */
+class Win32FontManager : FontManager {
+	FontList _activeFonts;
+	FontDef[] _fontFaces;
+	FontDef*[string] _faceByName;
+
+	/// initialize in constructor
+    this() {
+        instance = this;
+        init();
+    }
+
+	/// initialize font manager by enumerating of system fonts
+    bool init() {
+		Log.i("Win32FontManager.init()");
+        Win32ColorDrawBuf drawbuf = new Win32ColorDrawBuf(1,1);
+        LOGFONTA lf;
+        lf.lfCharSet = ANSI_CHARSET; //DEFAULT_CHARSET;
+		lf.lfFaceName[0] = 0;
+		HDC dc = drawbuf.dc;
+        int res = 
+            EnumFontFamiliesExA(
+                                dc,                  // handle to DC
+                                &lf,                              // font information
+                                &LVWin32FontEnumFontFamExProc, // callback function (FONTENUMPROC)
+                                cast(LPARAM)(cast(void*)this),                    // additional data
+                                0U                     // not used; must be 0
+                                    );
+		destroy(drawbuf);
+		Log.i("Found ", _fontFaces.length, " font faces");
+        return res!=0;
+    }
+
+	/// for returning of not found font
+	FontRef _emptyFontRef;
+
+	/// get font by properties
+    override ref FontRef getFont(int size, int weight, bool italic, FontFamily family, string face) {
+		Log.i("getFont()");
+		FontDef * def = findFace(family, face);
+		if (def !is null) {
+			int index = _activeFonts.find(size, weight, italic, def.family, def.face);
+			if (index >= 0)
+				return _activeFonts.get(index);
+			Log.d("Creating new font");
+			Win32Font item = new Win32Font();
+			if (!item.create(def, size, weight, italic))
+				return _emptyFontRef;
+			Log.d("Adding to list of active fonts");
+			return _activeFonts.add(item);
+		} else {
+			return _emptyFontRef;
+		}
+    }
+
+	/// find font face definition by family only (try to get one of defaults for family if possible)
+	FontDef * findFace(FontFamily family) {
+		FontDef * res = null;
+		switch(family) {
+		case FontFamily.SansSerif:
+			res = findFace("Arial"); if (res !is null) return res;
+			res = findFace("Tahoma"); if (res !is null) return res;
+			res = findFace("Calibri"); if (res !is null) return res;
+			res = findFace("Verdana"); if (res !is null) return res;
+			res = findFace("Lucida Sans"); if (res !is null) return res;
+			break;
+		case FontFamily.Serif:
+			res = findFace("Times New Roman"); if (res !is null) return res;
+			res = findFace("Georgia"); if (res !is null) return res;
+			res = findFace("Century Schoolbook"); if (res !is null) return res;
+			res = findFace("Bookman Old Style"); if (res !is null) return res;
+			break;
+		case FontFamily.MonoSpace:
+			res = findFace("Courier New"); if (res !is null) return res;
+			res = findFace("Lucida Console"); if (res !is null) return res;
+			res = findFace("Century Schoolbook"); if (res !is null) return res;
+			res = findFace("Bookman Old Style"); if (res !is null) return res;
+			break;
+		case FontFamily.Cursive:
+			res = findFace("Comic Sans MS"); if (res !is null) return res;
+			res = findFace("Lucida Handwriting"); if (res !is null) return res;
+			res = findFace("Monotype Corsiva"); if (res !is null) return res;
+			break;
+		default:
+			break;
+		}
+		return null;
+	}
+
+	/// find font face definition by face only
+	FontDef * findFace(string face) {
+		if (face.length == 0)
+			return null;
+		if (face in _faceByName)
+			return _faceByName[face];
+		return null;
+	}
+
+	/// find font face definition by family and face
+	FontDef * findFace(FontFamily family, string face) {
+		// by face only
+		FontDef * res = findFace(face);
+		if (res !is null)
+			return res;
+		// best for family
+		res = findFace(family);
+		if (res !is null)
+			return res;
+		for (int i = 0; i < _fontFaces.length; i++) {
+			res = &_fontFaces[i];
+			if (res.family == family)
+				return res;
+		}
+		res = findFace(FontFamily.SansSerif);
+		if (res !is null)
+			return res;
+		return &_fontFaces[0];
+	}
+
+	/// register enumerated font
+    bool registerFont(FontFamily family, string fontFace, ubyte pitchAndFamily) {
+		Log.d("registerFont(", family, ",", fontFace, ")");
+		_fontFaces ~= FontDef(family, fontFace, pitchAndFamily);
+		_faceByName[fontFace] = &_fontFaces[$ - 1];
+        return true;
+    }
 
 	/// clear usage flags for all entries
 	override void checkpoint() {
@@ -429,351 +430,351 @@ class Win32FontManager : FontManager {
 		_activeFonts.cleanup();
 		//_list.cleanup();
 	}
-}
-
-string fromStringz(const(char[]) s) {
-	int i = 0;
-	while(s[i])
-		i++;
-	return cast(string)(s[0..i].dup);
-}
-
-FontFamily pitchAndFamilyToFontFamily(ubyte flags) {
-	if ((flags & FF_DECORATIVE) == FF_DECORATIVE)
-		return FontFamily.Fantasy;
-	else if ((flags & (FIXED_PITCH)) != 0) // | | MONO_FONT
-		return FontFamily.MonoSpace;
-	else if ((flags & (FF_ROMAN)) != 0)
-		return FontFamily.Serif;
-	else if ((flags & (FF_SCRIPT)) != 0)
-		return FontFamily.Cursive;
-	return FontFamily.SansSerif;
-}
-
-// definition
-extern(Windows) {
-    int LVWin32FontEnumFontFamExProc(
-            const (LOGFONTA) *lf,    // logical-font data
-            const (TEXTMETRICA) *lpntme,  // physical-font data
-            //ENUMLOGFONTEX *lpelfe,    // logical-font data
-            //NEWTEXTMETRICEX *lpntme,  // physical-font data
-            DWORD fontType,           // type of font
-            LPARAM lParam             // application-defined data
-                )
-    {
-        //
-		//Log.d("LVWin32FontEnumFontFamExProc fontType=", fontType);
-        if (fontType == TRUETYPE_FONTTYPE)
-        {
-            void * p = cast(void*)lParam;
-            Win32FontManager fontman = cast(Win32FontManager)p;
-			string face = fromStringz(lf.lfFaceName);
-			FontFamily family = pitchAndFamilyToFontFamily(lf.lfPitchAndFamily);
-			if (face.length < 2 || face[0] == '@')
-				return 1;
-			//Log.d("face:", face);
-			fontman.registerFont(family, face, lf.lfPitchAndFamily);
-        }
-        return 1;
-    }
-}
-
-extern (C) int UIAppMain();
-
-immutable WIN_CLASS_NAME = "DLANGUI_APP";
-
-__gshared HINSTANCE _hInstance;
-__gshared int _cmdShow;
-
-class Win32Window : Window {
-    private HWND _hwnd;
-    string _caption;
-    Win32ColorDrawBuf _drawbuf;
-    this(string windowCaption, Window parent) {
-        _caption = windowCaption;
-        _hwnd = CreateWindow(toUTF16z(WIN_CLASS_NAME),      // window class name
-                            toUTF16z(windowCaption),  // window caption
-                            WS_OVERLAPPEDWINDOW,  // window style
-                            CW_USEDEFAULT,        // initial x position
-                            CW_USEDEFAULT,        // initial y position
-                            CW_USEDEFAULT,        // initial x size
-                            CW_USEDEFAULT,        // initial y size
-                            null,                 // parent window handle
-                            null,                 // window menu handle
-                            _hInstance,           // program instance handle
-                            cast(void*)this);                // creation parameters
-    }
-    Win32ColorDrawBuf getDrawBuf() {
-        RECT rect;
-        GetClientRect(_hwnd, &rect);
-        int dx = rect.right - rect.left;
-        int dy = rect.bottom - rect.top;
-        if (_drawbuf is null)
-            _drawbuf = new Win32ColorDrawBuf(dx, dy);
-        else 
-            _drawbuf.resize(dx, dy);
-        return _drawbuf;
-    }
-    override void show() {
-        ShowWindow(_hwnd, _cmdShow);
-        UpdateWindow(_hwnd);
-    }
-    override @property string windowCaption() {
-        return _caption;
-    }
-    override @property void windowCaption(string caption) {
-        _caption = caption;
-        SetWindowTextW(_hwnd, toUTF16z(_caption));
-    }
-    void onCreate() {
-        writeln("Window onCreate");
-    }
-    void onDestroy() {
-        writeln("Window onDestroy");
-    }
-}
-
-class Win32Platform : Platform {
-    this() {
-    }
-    bool registerWndClass() {
-        //MSG  msg;
-        WNDCLASS wndclass;
-
-        wndclass.style         = CS_HREDRAW | CS_VREDRAW;
-        wndclass.lpfnWndProc   = &WndProc;
-        wndclass.cbClsExtra    = 0;
-        wndclass.cbWndExtra    = 0;
-        wndclass.hInstance     = _hInstance;
-        wndclass.hIcon         = LoadIcon(null, IDI_APPLICATION);
-        wndclass.hCursor       = LoadCursor(null, IDC_ARROW);
-        wndclass.hbrBackground = cast(HBRUSH)GetStockObject(WHITE_BRUSH);
-        wndclass.lpszMenuName  = null;
-        wndclass.lpszClassName = toUTF16z(WIN_CLASS_NAME);
-
-        if(!RegisterClass(&wndclass))
-        {
-            return false;
-        }
-        return true;
-    }
-    override int enterMessageLoop() {
-        MSG  msg;
-        while (GetMessage(&msg, null, 0, 0))
-        {
-            TranslateMessage(&msg);
-            DispatchMessage(&msg);
-        }
-        return msg.wParam;
-    }
-    override Window createWindow(string windowCaption, Window parent) {
-        return new Win32Window(windowCaption, parent);
-    }
-}
-
-auto toUTF16z(S)(S s)
-{
-    return toUTFz!(const(wchar)*)(s);
-}
-
-extern (Windows)
-int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
-            LPSTR lpCmdLine, int nCmdShow)
-{
-    int result;
-
-    void exceptionHandler(Throwable e) {
-        throw e;
-    }
-
-    try
-    {
-        Runtime.initialize(&exceptionHandler);
-        result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
-        Runtime.terminate(&exceptionHandler);
-    }
-    catch (Throwable e) // catch any uncaught exceptions
-    {
-        MessageBox(null, toUTF16z(e.toString()), "Error",
-                   MB_OK | MB_ICONEXCLAMATION);
-        result = 0;     // failed
-    }
-
-    return result;
-}
-
-int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
-{
-	setFileLogger(std.stdio.File("ui.log", "w"));
-	setLogLevel(LogLevel.Trace);
-
-    _cmdShow = iCmdShow;
-    _hInstance = hInstance;
-    Log.d("Inside myWinMain");
-    string appName = "HelloWin";
-
-
-    Win32Platform platform = new Win32Platform();
-    if (!platform.registerWndClass()) {
-        MessageBoxA(null, "This program requires Windows NT!", appName.toStringz, MB_ICONERROR);
-        return 0;
-    }
-    Platform.setInstance(platform);
-	Win32FontManager fontMan = new Win32FontManager();
-	FontManager.instance = fontMan;
-    return UIAppMain();
-}
-
-class Win32ColorDrawBuf : ColorDrawBufBase {
-    uint * _pixels;
-    HDC _drawdc;
-    HBITMAP _drawbmp;
-    @property HDC dc() { return _drawdc; }
-    this(int width, int height) {
-        resize(width, height);
-    }
-    override uint * scanLine(int y) {
-        if (y >= 0 && y < _dy)
-            return _pixels + _dx * (_dy - 1 - y);
-        return null;
-    }
-    override void clear() {
-        if (_drawbmp !is null) {
-            DeleteObject( _drawbmp );
-            DeleteObject( _drawdc );
-            _pixels = null;
-            _dx = 0;
-            _dy = 0;
-        }
-    }
-    override void resize(int width, int height) {
-        if (width< 0)
-            width = 0;
-        if (height < 0)
-            height = 0;
-        if (_dx == width && _dy == height)
-            return;
-        clear();
-        _dx = width;
-        _dy = height;
-        if (_dx > 0 && _dy > 0) {
-            BITMAPINFO bmi;
-            //memset( &bmi, 0, sizeof(bmi) );
-            bmi.bmiHeader.biSize = (bmi.bmiHeader.sizeof);
-            bmi.bmiHeader.biWidth = _dx;
-            bmi.bmiHeader.biHeight = _dy;
-            bmi.bmiHeader.biPlanes = 1;
-            bmi.bmiHeader.biBitCount = 32;
-            bmi.bmiHeader.biCompression = BI_RGB;
-            bmi.bmiHeader.biSizeImage = 0;
-            bmi.bmiHeader.biXPelsPerMeter = 1024;
-            bmi.bmiHeader.biYPelsPerMeter = 1024;
-            bmi.bmiHeader.biClrUsed = 0;
-            bmi.bmiHeader.biClrImportant = 0;
-            _drawbmp = CreateDIBSection( NULL, &bmi, DIB_RGB_COLORS, cast(void**)(&_pixels), NULL, 0 );
-            _drawdc = CreateCompatibleDC(NULL);
-            SelectObject(_drawdc, _drawbmp);
-        }
-    }
-    override void fill(uint color) {
-        int len = _dx * _dy;
-        for (int i = 0; i < len; i++)
-            _pixels[i] = color;
-    }
-    void drawTo(HDC dc, int x, int y) {
-        BitBlt(dc, x, y, _dx, _dx, _drawdc, 0, 0, SRCCOPY);
-    }
-}
-
-//void drawBuf2DC(HDC dc, int x, int y, DrawBuf buf)
-//{
-//    uint * drawpixels;
-//    HDC drawdc;
-//    HBITMAP drawbmp;
-//
-//    int buf_width = buf.width();
-//    int bytesPerRow = buf_width * 4;
-//    BITMAPINFO bmi;
-//    //memset( &bmi, 0, sizeof(bmi) );
-//    bmi.bmiHeader.biSize = (bmi.bmiHeader.sizeof);
-//    bmi.bmiHeader.biWidth = buf_width;
-//    bmi.bmiHeader.biHeight = buf.height;
-//    bmi.bmiHeader.biPlanes = 1;
-//    bmi.bmiHeader.biBitCount = 32;
-//    bmi.bmiHeader.biCompression = BI_RGB;
-//    bmi.bmiHeader.biSizeImage = 0;
-//    bmi.bmiHeader.biXPelsPerMeter = 1024;
-//    bmi.bmiHeader.biYPelsPerMeter = 1024;
-//    bmi.bmiHeader.biClrUsed = 0;
-//    bmi.bmiHeader.biClrImportant = 0;
-//    drawbmp = CreateDIBSection( NULL, &bmi, DIB_RGB_COLORS, cast(void**)(&drawpixels), NULL, 0 );
-//    drawdc = CreateCompatibleDC(NULL);
-//    SelectObject(drawdc, drawbmp);
-//    for (int yy=0; yy < buf.height; yy++)
-//    {
-//        uint * src = buf.scanLine(yy);
-//        uint * dst = drawpixels + (buf.height - 1 - yy) * buf.width;
-//        for (int xx = 0; xx < buf_width; xx++)
-//            dst[xx] = src[xx];
-//    }
-//    BitBlt( dc, x, y, buf_width, buf.height, drawdc, 0, 0, SRCCOPY);
-//    DeleteObject( drawbmp );
-//    DeleteObject( drawdc );
-//}
-
-
-extern(Windows)
-LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
-    HDC hdc;
-    PAINTSTRUCT ps;
-    RECT rect;
-    void * p = cast(void*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
-    Win32Window window = p is null ? null : cast(Win32Window)(p);
-    switch (message)
-    {
-        case WM_CREATE:
-            {
-                CREATESTRUCT * pcreateStruct = cast(CREATESTRUCT*)lParam;
-                window = cast(Win32Window)pcreateStruct.lpCreateParams;
-                void * ptr = cast(void*) window;
-                SetWindowLongPtr(hwnd, GWLP_USERDATA, cast(LONG_PTR)ptr);
-                window.onCreate();
-            }
-            //PlaySoundA("hellowin.wav", NULL, SND_FILENAME | SND_ASYNC);
-            return 0;
-        case WM_WINDOWPOSCHANGED:
-            {
-                WINDOWPOS * pos = cast(WINDOWPOS*)lParam;
-                window.onResize(pos.cx, pos.cy);
-            }
-            return 0;
-
-        case WM_PAINT:
-            {
-                hdc = BeginPaint(hwnd, &ps);
-                Win32ColorDrawBuf buf = window.getDrawBuf();
-                buf.fill(0x808080);
-                window.onDraw(buf);
-                buf.drawTo(hdc, 0, 0);
-                //drawBuf2DC(hdc, 0, 0, buf);
-                scope(exit) EndPaint(hwnd, &ps);
-            }
-            //DrawTextA(hdc, "Hello, Windows!", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
-            return 0;
-
-        case WM_DESTROY:
-            window.onDestroy();
-            PostQuitMessage(0);
-            return 0;
-
-        default:
-    }
-
-    return DefWindowProc(hwnd, message, wParam, lParam);
-}
-
-//===========================================
-// end of version(Windows)
-//===========================================
-} 
+}
+
+string fromStringz(const(char[]) s) {
+	int i = 0;
+	while(s[i])
+		i++;
+	return cast(string)(s[0..i].dup);
+}
+
+FontFamily pitchAndFamilyToFontFamily(ubyte flags) {
+	if ((flags & FF_DECORATIVE) == FF_DECORATIVE)
+		return FontFamily.Fantasy;
+	else if ((flags & (FIXED_PITCH)) != 0) // | | MONO_FONT
+		return FontFamily.MonoSpace;
+	else if ((flags & (FF_ROMAN)) != 0)
+		return FontFamily.Serif;
+	else if ((flags & (FF_SCRIPT)) != 0)
+		return FontFamily.Cursive;
+	return FontFamily.SansSerif;
+}
+
+// definition
+extern(Windows) {
+    int LVWin32FontEnumFontFamExProc(
+            const (LOGFONTA) *lf,    // logical-font data
+            const (TEXTMETRICA) *lpntme,  // physical-font data
+            //ENUMLOGFONTEX *lpelfe,    // logical-font data
+            //NEWTEXTMETRICEX *lpntme,  // physical-font data
+            DWORD fontType,           // type of font
+            LPARAM lParam             // application-defined data
+                )
+    {
+        //
+		//Log.d("LVWin32FontEnumFontFamExProc fontType=", fontType);
+        if (fontType == TRUETYPE_FONTTYPE)
+        {
+            void * p = cast(void*)lParam;
+            Win32FontManager fontman = cast(Win32FontManager)p;
+			string face = fromStringz(lf.lfFaceName);
+			FontFamily family = pitchAndFamilyToFontFamily(lf.lfPitchAndFamily);
+			if (face.length < 2 || face[0] == '@')
+				return 1;
+			//Log.d("face:", face);
+			fontman.registerFont(family, face, lf.lfPitchAndFamily);
+        }
+        return 1;
+    }
+}
+
+extern (C) int UIAppMain();
+
+immutable WIN_CLASS_NAME = "DLANGUI_APP";
+
+__gshared HINSTANCE _hInstance;
+__gshared int _cmdShow;
+
+class Win32Window : Window {
+    private HWND _hwnd;
+    string _caption;
+    Win32ColorDrawBuf _drawbuf;
+    this(string windowCaption, Window parent) {
+        _caption = windowCaption;
+        _hwnd = CreateWindow(toUTF16z(WIN_CLASS_NAME),      // window class name
+                            toUTF16z(windowCaption),  // window caption
+                            WS_OVERLAPPEDWINDOW,  // window style
+                            CW_USEDEFAULT,        // initial x position
+                            CW_USEDEFAULT,        // initial y position
+                            CW_USEDEFAULT,        // initial x size
+                            CW_USEDEFAULT,        // initial y size
+                            null,                 // parent window handle
+                            null,                 // window menu handle
+                            _hInstance,           // program instance handle
+                            cast(void*)this);                // creation parameters
+    }
+    Win32ColorDrawBuf getDrawBuf() {
+        RECT rect;
+        GetClientRect(_hwnd, &rect);
+        int dx = rect.right - rect.left;
+        int dy = rect.bottom - rect.top;
+        if (_drawbuf is null)
+            _drawbuf = new Win32ColorDrawBuf(dx, dy);
+        else 
+            _drawbuf.resize(dx, dy);
+        return _drawbuf;
+    }
+    override void show() {
+        ShowWindow(_hwnd, _cmdShow);
+        UpdateWindow(_hwnd);
+    }
+    override @property string windowCaption() {
+        return _caption;
+    }
+    override @property void windowCaption(string caption) {
+        _caption = caption;
+        SetWindowTextW(_hwnd, toUTF16z(_caption));
+    }
+    void onCreate() {
+        writeln("Window onCreate");
+    }
+    void onDestroy() {
+        writeln("Window onDestroy");
+    }
+}
+
+class Win32Platform : Platform {
+    this() {
+    }
+    bool registerWndClass() {
+        //MSG  msg;
+        WNDCLASS wndclass;
+
+        wndclass.style         = CS_HREDRAW | CS_VREDRAW;
+        wndclass.lpfnWndProc   = &WndProc;
+        wndclass.cbClsExtra    = 0;
+        wndclass.cbWndExtra    = 0;
+        wndclass.hInstance     = _hInstance;
+        wndclass.hIcon         = LoadIcon(null, IDI_APPLICATION);
+        wndclass.hCursor       = LoadCursor(null, IDC_ARROW);
+        wndclass.hbrBackground = cast(HBRUSH)GetStockObject(WHITE_BRUSH);
+        wndclass.lpszMenuName  = null;
+        wndclass.lpszClassName = toUTF16z(WIN_CLASS_NAME);
+
+        if(!RegisterClass(&wndclass))
+        {
+            return false;
+        }
+        return true;
+    }
+    override int enterMessageLoop() {
+        MSG  msg;
+        while (GetMessage(&msg, null, 0, 0))
+        {
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        }
+        return msg.wParam;
+    }
+    override Window createWindow(string windowCaption, Window parent) {
+        return new Win32Window(windowCaption, parent);
+    }
+}
+
+auto toUTF16z(S)(S s)
+{
+    return toUTFz!(const(wchar)*)(s);
+}
+
+extern (Windows)
+int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+            LPSTR lpCmdLine, int nCmdShow)
+{
+    int result;
+
+    void exceptionHandler(Throwable e) {
+        throw e;
+    }
+
+    try
+    {
+        Runtime.initialize(&exceptionHandler);
+        result = myWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
+        Runtime.terminate(&exceptionHandler);
+    }
+    catch (Throwable e) // catch any uncaught exceptions
+    {
+        MessageBox(null, toUTF16z(e.toString()), "Error",
+                   MB_OK | MB_ICONEXCLAMATION);
+        result = 0;     // failed
+    }
+
+    return result;
+}
+
+int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
+{
+	setFileLogger(std.stdio.File("ui.log", "w"));
+	setLogLevel(LogLevel.Trace);
+
+    _cmdShow = iCmdShow;
+    _hInstance = hInstance;
+    Log.d("Inside myWinMain");
+    string appName = "HelloWin";
+
+
+    Win32Platform platform = new Win32Platform();
+    if (!platform.registerWndClass()) {
+        MessageBoxA(null, "This program requires Windows NT!", appName.toStringz, MB_ICONERROR);
+        return 0;
+    }
+    Platform.setInstance(platform);
+	Win32FontManager fontMan = new Win32FontManager();
+	FontManager.instance = fontMan;
+    return UIAppMain();
+}
+
+class Win32ColorDrawBuf : ColorDrawBufBase {
+    uint * _pixels;
+    HDC _drawdc;
+    HBITMAP _drawbmp;
+    @property HDC dc() { return _drawdc; }
+    this(int width, int height) {
+        resize(width, height);
+    }
+    override uint * scanLine(int y) {
+        if (y >= 0 && y < _dy)
+            return _pixels + _dx * (_dy - 1 - y);
+        return null;
+    }
+    override void clear() {
+        if (_drawbmp !is null) {
+            DeleteObject( _drawbmp );
+            DeleteObject( _drawdc );
+            _pixels = null;
+            _dx = 0;
+            _dy = 0;
+        }
+    }
+    override void resize(int width, int height) {
+        if (width< 0)
+            width = 0;
+        if (height < 0)
+            height = 0;
+        if (_dx == width && _dy == height)
+            return;
+        clear();
+        _dx = width;
+        _dy = height;
+        if (_dx > 0 && _dy > 0) {
+            BITMAPINFO bmi;
+            //memset( &bmi, 0, sizeof(bmi) );
+            bmi.bmiHeader.biSize = (bmi.bmiHeader.sizeof);
+            bmi.bmiHeader.biWidth = _dx;
+            bmi.bmiHeader.biHeight = _dy;
+            bmi.bmiHeader.biPlanes = 1;
+            bmi.bmiHeader.biBitCount = 32;
+            bmi.bmiHeader.biCompression = BI_RGB;
+            bmi.bmiHeader.biSizeImage = 0;
+            bmi.bmiHeader.biXPelsPerMeter = 1024;
+            bmi.bmiHeader.biYPelsPerMeter = 1024;
+            bmi.bmiHeader.biClrUsed = 0;
+            bmi.bmiHeader.biClrImportant = 0;
+            _drawbmp = CreateDIBSection( NULL, &bmi, DIB_RGB_COLORS, cast(void**)(&_pixels), NULL, 0 );
+            _drawdc = CreateCompatibleDC(NULL);
+            SelectObject(_drawdc, _drawbmp);
+        }
+    }
+    override void fill(uint color) {
+        int len = _dx * _dy;
+        for (int i = 0; i < len; i++)
+            _pixels[i] = color;
+    }
+    void drawTo(HDC dc, int x, int y) {
+        BitBlt(dc, x, y, _dx, _dx, _drawdc, 0, 0, SRCCOPY);
+    }
+}
+
+//void drawBuf2DC(HDC dc, int x, int y, DrawBuf buf)
+//{
+//    uint * drawpixels;
+//    HDC drawdc;
+//    HBITMAP drawbmp;
+//
+//    int buf_width = buf.width();
+//    int bytesPerRow = buf_width * 4;
+//    BITMAPINFO bmi;
+//    //memset( &bmi, 0, sizeof(bmi) );
+//    bmi.bmiHeader.biSize = (bmi.bmiHeader.sizeof);
+//    bmi.bmiHeader.biWidth = buf_width;
+//    bmi.bmiHeader.biHeight = buf.height;
+//    bmi.bmiHeader.biPlanes = 1;
+//    bmi.bmiHeader.biBitCount = 32;
+//    bmi.bmiHeader.biCompression = BI_RGB;
+//    bmi.bmiHeader.biSizeImage = 0;
+//    bmi.bmiHeader.biXPelsPerMeter = 1024;
+//    bmi.bmiHeader.biYPelsPerMeter = 1024;
+//    bmi.bmiHeader.biClrUsed = 0;
+//    bmi.bmiHeader.biClrImportant = 0;
+//    drawbmp = CreateDIBSection( NULL, &bmi, DIB_RGB_COLORS, cast(void**)(&drawpixels), NULL, 0 );
+//    drawdc = CreateCompatibleDC(NULL);
+//    SelectObject(drawdc, drawbmp);
+//    for (int yy=0; yy < buf.height; yy++)
+//    {
+//        uint * src = buf.scanLine(yy);
+//        uint * dst = drawpixels + (buf.height - 1 - yy) * buf.width;
+//        for (int xx = 0; xx < buf_width; xx++)
+//            dst[xx] = src[xx];
+//    }
+//    BitBlt( dc, x, y, buf_width, buf.height, drawdc, 0, 0, SRCCOPY);
+//    DeleteObject( drawbmp );
+//    DeleteObject( drawdc );
+//}
+
+
+extern(Windows)
+LRESULT WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    HDC hdc;
+    PAINTSTRUCT ps;
+    RECT rect;
+    void * p = cast(void*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+    Win32Window window = p is null ? null : cast(Win32Window)(p);
+    switch (message)
+    {
+        case WM_CREATE:
+            {
+                CREATESTRUCT * pcreateStruct = cast(CREATESTRUCT*)lParam;
+                window = cast(Win32Window)pcreateStruct.lpCreateParams;
+                void * ptr = cast(void*) window;
+                SetWindowLongPtr(hwnd, GWLP_USERDATA, cast(LONG_PTR)ptr);
+                window.onCreate();
+            }
+            //PlaySoundA("hellowin.wav", NULL, SND_FILENAME | SND_ASYNC);
+            return 0;
+        case WM_WINDOWPOSCHANGED:
+            {
+                WINDOWPOS * pos = cast(WINDOWPOS*)lParam;
+                window.onResize(pos.cx, pos.cy);
+            }
+            return 0;
+
+        case WM_PAINT:
+            {
+                hdc = BeginPaint(hwnd, &ps);
+                Win32ColorDrawBuf buf = window.getDrawBuf();
+                buf.fill(0x808080);
+                window.onDraw(buf);
+                buf.drawTo(hdc, 0, 0);
+                //drawBuf2DC(hdc, 0, 0, buf);
+                scope(exit) EndPaint(hwnd, &ps);
+            }
+            //DrawTextA(hdc, "Hello, Windows!", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+            return 0;
+
+        case WM_DESTROY:
+            window.onDestroy();
+            PostQuitMessage(0);
+            return 0;
+
+        default:
+    }
+
+    return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+//===========================================
+// end of version(Windows)
+//===========================================
+}