diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
 A Haskell wrapper around the C library
 [tiny file dialogs](https://sourceforge.net/projects/tinyfiledialogs/).
 
-Currently bundles v3.0.8, with minor edits (all labeled with `// MT:`).
+Currently bundles v3.0.9. Any edits in `.c`/`.h` are labeled with `// MT:`.
diff --git a/cbits/tinyfiledialogs.c b/cbits/tinyfiledialogs.c
--- a/cbits/tinyfiledialogs.c
+++ b/cbits/tinyfiledialogs.c
@@ -1,5 +1,5 @@
 /*_________
- /         \ tinyfiledialogs.c v3.0.8 [Sep 28, 2017] zlib licence
+ /         \ tinyfiledialogs.c v3.0.9 [Sep 29, 2017] zlib licence
  |tiny file| Unique code file created [November 9, 2014]
  | dialogs | Copyright (c) 2014 - 2017 Guillaume Vareille http://ysengrin.com
  \____  ___/ http://tinyfiledialogs.sourceforge.net
@@ -17,8 +17,9 @@
 A big thank you to Don Heyse http://ldglite.sf.net for
                    his code contributions, bug corrections & thorough testing!
 		
-Please 1) let me know If you are using it on different hardware / OS / compiler
-       2) leave a very short review on Sourceforge. It helps the ranking in google.
+Please 1) Let me know If you are using it on exotic hardware / OS / compiler
+       2) If yo have a sourceforge account, leave a 3-word review on Sourceforge.
+          It helps the ranking on google.
 
 tiny file dialogs (cross-platform C C++)
 InputBox PasswordBox MessageBox ColorPicker
@@ -65,8 +66,8 @@
 using Gnome Kde Enlightenment Mate Cinnamon Unity
 Lxde Lxqt Xfce WindowMaker IceWm Cde Jds OpenBox Awesome Jwm
 
-bindings for LUA and C# dll
-included in LWJGL(java), rust, Allegrobasic
+bindings for LUA and C# dll, Haskell
+included in LWJGL(java), Rust, Allegrobasic
 
 - License -
 
@@ -124,7 +125,7 @@
 #define MAX_PATH_OR_CMD 1024 /* _MAX_PATH or MAX_PATH */
 #define MAX_MULTIPLE_FILES 32
 
-char tinyfd_version [8] = "3.0.8";
+char tinyfd_version [8] = "3.0.9";
 
 static int tinyfd_verbose = 0 ; /* print on unix the command line calls */
 
@@ -146,7 +147,7 @@
 tinyfd_response is then filled with the retain solution.
 possible values for tinyfd_response are (all lowercase)
 for the graphic mode:
-  windows applescript zenity zenity3 matedialog qarma kdialog
+  windows_wchar windows applescript zenity zenity3 matedialog qarma kdialog
   tkinter gxmessage gmessage xmessage xdialog gdialog
 for the console mode:
   dialog whiptail basicinput */
@@ -366,6 +367,7 @@
 	return 1 ;
 }
 
+#ifndef _WIN32
 
 static int fileExists( char const * const aFilePathAndName )
 {
@@ -383,54 +385,31 @@
 	return 1 ;
 }
 
+#elif defined(TINYFD_NOLIB)
 
-/* source and destination can be the same or ovelap*/
-static char const * ensureFilesExist( char * const aDestination ,
-							 		  char const * const aSourcePathsAndNames)
+static int fileExists( char const * const aFilePathAndName )
 {
-	char * lDestination = aDestination ;
-	char const * p ;
-	char const * p2 ;
-	int lLen ;
-
-	if ( ! aSourcePathsAndNames )
-	{
-		return NULL ;
-	}
-	lLen = strlen( aSourcePathsAndNames ) ;
-	if ( ! lLen )
-	{
-		return NULL ;
-	}
-	
-	p = aSourcePathsAndNames ;
-	while ( (p2 = strchr(p, '|')) != NULL )
-	{
-		lLen = p2-p ;		
-		memmove(lDestination,p,lLen);
-		lDestination[lLen] = '\0';
-		if ( fileExists( lDestination ) )
-		{
-			lDestination += lLen ;
-			* lDestination = '|';
-			lDestination ++ ;
-		}
-		p = p2 + 1 ;
-	}
-	if ( fileExists( p ) )
+	FILE * lIn ;
+	if ( ! aFilePathAndName || ! strlen(aFilePathAndName) )
 	{
-		lLen = strlen(p) ;		
-		memmove(lDestination,p,lLen);
-		lDestination[lLen] = '\0';
+		return 0 ;
 	}
-	else
+
+	if ( tinyfd_winUtf8 )
+		return 1; /* we cannot test */
+
+	lIn = fopen( aFilePathAndName , "r" ) ;
+	if ( ! lIn )
 	{
-		* (lDestination-1) = '\0';
+		return 0 ;
 	}
-	return aDestination ;
+	fclose( lIn ) ;
+	return 1 ;
 }
 
+#endif
 
+
 static void wipefile(char const * const aFilename)
 {
 	int i;
@@ -754,6 +733,94 @@
 }
 
 
+static int fileExists(char const * const aFilePathAndName)
+{
+	struct _stat lInfo;
+	wchar_t * lTmpWChar;
+	int lStatRet;
+	FILE * lIn;
+
+	if (!aFilePathAndName || !strlen(aFilePathAndName))
+	{
+		return 0;
+	}
+
+	if (tinyfd_winUtf8)
+	{
+		lTmpWChar = utf8to16(aFilePathAndName);
+		lStatRet = _wstat(lTmpWChar, &lInfo);
+		free(lTmpWChar);
+		if (lStatRet != 0)
+			return 0;
+		else if (lInfo.st_mode & _S_IFREG)
+			return 1;
+		else
+			return 0;
+	}
+	else
+	{
+		lIn = fopen(aFilePathAndName, "r");
+		if (!lIn)
+		{
+			return 0;
+		}
+		fclose(lIn);
+		return 1;
+	}
+}
+
+#endif /* TINYFD_NOLIB */
+#endif /* _WIN32 */
+
+/* source and destination can be the same or ovelap*/
+static char const * ensureFilesExist(char * const aDestination,
+	char const * const aSourcePathsAndNames)
+{
+	char * lDestination = aDestination;
+	char const * p;
+	char const * p2;
+	int lLen;
+
+	if (!aSourcePathsAndNames)
+	{
+		return NULL;
+	}
+	lLen = strlen(aSourcePathsAndNames);
+	if (!lLen)
+	{
+		return NULL;
+	}
+
+	p = aSourcePathsAndNames;
+	while ((p2 = strchr(p, '|')) != NULL)
+	{
+		lLen = p2 - p;
+		memmove(lDestination, p, lLen);
+		lDestination[lLen] = '\0';
+		if (fileExists(lDestination))
+		{
+			lDestination += lLen;
+			*lDestination = '|';
+			lDestination++;
+		}
+		p = p2 + 1;
+	}
+	if (fileExists(p))
+	{
+		lLen = strlen(p);
+		memmove(lDestination, p, lLen);
+		lDestination[lLen] = '\0';
+	}
+	else
+	{
+		*(lDestination - 1) = '\0';
+	}
+	return aDestination;
+}
+
+#ifdef _WIN32
+#ifndef TINYFD_NOLIB
+
 static int __stdcall EnumThreadWndProc(HWND hwnd, LPARAM lParam)
 { 
 	wchar_t lTitleName[MAX_PATH];
@@ -842,7 +909,7 @@
 	int lBoxReturnValue;
 	UINT aCode;
 
-	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return 1; }
+	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return 1; }
 
 	if (aIconType && !wcscmp(L"warning", aIconType))
 	{
@@ -943,7 +1010,7 @@
 	int lMessageLen;
 	int lDialogStringLen;
 
-	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return (wchar_t const *)1; }
+	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; }
 
 	lTitleLen =  aTitle ? wcslen(aTitle) : 0 ;
 	lMessageLen =  aMessage ? wcslen(aMessage) : 0 ;
@@ -1279,7 +1346,7 @@
 	HRESULT lHResult;
 	OPENFILENAMEW ofn = {0};
 
-	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return (wchar_t const *)1; }
+	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; }
 
 	lHResult = CoInitializeEx(NULL, 0);
 
@@ -1430,7 +1497,7 @@
 	HRESULT lHResult;
 	OPENFILENAMEW ofn = { 0 };
 
-	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return (wchar_t const *)1; }
+	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; }
 
 	lHResult = CoInitializeEx(NULL, 0);
 
@@ -1625,7 +1692,7 @@
 	LPITEMIDLIST lpItem;
 	HRESULT lHResult;
 
-	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return (wchar_t const *)1; }
+	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; }
 
 	lHResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
 
@@ -1702,7 +1769,7 @@
 
 	HRESULT lHResult;
 
-	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windowsW"); return (wchar_t const *)1; }
+	if (aTitle&&!wcscmp(aTitle, L"tinyfd_query")){ strcpy(tinyfd_response, "windows_wchar"); return (wchar_t const *)1; }
 
 	lHResult = CoInitializeEx(NULL, 0);
 
@@ -2909,8 +2976,7 @@
 	}
 	if ( aAllowMultipleSelects && strchr(p, '|') )
 	{
-		// MT: removing this because it doesn't work for non-ascii filenames on Windows
-		// p = ensureFilesExist( lBuff , p ) ;
+		p = ensureFilesExist( lBuff , p ) ;
 	}
 	else if ( ! fileExists(p) )
 	{
diff --git a/cbits/tinyfiledialogs.h b/cbits/tinyfiledialogs.h
--- a/cbits/tinyfiledialogs.h
+++ b/cbits/tinyfiledialogs.h
@@ -1,5 +1,5 @@
 /*_________
- /         \ tinyfiledialogs.h v3.0.8 [Sep 28, 2017] zlib licence
+ /         \ tinyfiledialogs.h v3.0.9 [Sep 29, 2017] zlib licence
  |tiny file| Unique header file created [November 9, 2014]
  | dialogs | Copyright (c) 2014 - 2017 Guillaume Vareille http://ysengrin.com
  \____  ___/ http://tinyfiledialogs.sourceforge.net
@@ -17,8 +17,9 @@
 A big thank you to Don Heyse http://ldglite.sf.net for
                    his code contributions, bug corrections & thorough testing!
 
-Please 1) let me know If you are using it on different hardware / OS / compiler
-       2) leave a very short review on Sourceforge. It helps the ranking in google.
+Please 1) Let me know If you are using it on exotic hardware / OS / compiler
+       2) If yo have a sourceforge account, leave a 3-word review on Sourceforge.
+          It helps the ranking on google.
 
 tiny file dialogs (cross-platform C C++)
 InputBox PasswordBox MessageBox ColorPicker
@@ -65,8 +66,8 @@
 using Gnome Kde Enlightenment Mate Cinnamon Unity
 Lxde Lxqt Xfce WindowMaker IceWm Cde Jds OpenBox Awesome Jwm
 
-bindings for LUA and C# dll
-included in LWJGL(java), rust, Allegrobasic
+bindings for LUA and C# dll, Haskell
+included in LWJGL(java), Rust, Allegrobasic
 
 - License -
 
@@ -129,7 +130,7 @@
 tinyfd_response is then filled with the retain solution.
 possible values for tinyfd_response are (all lowercase)
 for the graphic mode:
-  windows applescript zenity zenity3 matedialog qarma kdialog
+  windows_wchar windows applescript zenity zenity3 matedialog qarma kdialog
   xdialog tkinter gdialog gxmessage xmessage
 for the console mode:
   dialog whiptail basicinput */
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,10 @@
+## 0.2.0.0
+
+  * Support yesnocancel message box
+  * Reworked message box dialog types into a typeclass
+
+## 0.1.0.0
+
+  * Initial release
+  * Comes with TFD 3.0.8
+  * Supports all features except yesnocancel message box
diff --git a/src/Graphics/UI/TinyFileDialogs.chs b/src/Graphics/UI/TinyFileDialogs.chs
--- a/src/Graphics/UI/TinyFileDialogs.chs
+++ b/src/Graphics/UI/TinyFileDialogs.chs
@@ -1,12 +1,18 @@
 module Graphics.UI.TinyFileDialogs
-( messageBox
+( -- * The functions
+  messageBox
 , inputBox
 , saveFileDialog
 , openFileDialog
 , selectFolderDialog
 , colorChooser
-, DialogType(..)
+  -- * Message box options
 , IconType(..)
+, MessageBox
+, OK(..)
+, OKCancel(..)
+, YesNo(..)
+, YesNoCancel(..)
 ) where
 
 import           Data.Char          (toLower)
@@ -57,20 +63,66 @@
 withCTexts ts f = withMany withCText ts $ \ptrs ->
   withArrayLen ptrs $ \len ptr -> f (fromIntegral len, ptr)
 
-data DialogType = OK | OKCancel | YesNo
-  deriving (Eq, Ord, Show, Read, Enum, Bounded)
+class (Enum a, Bounded a) => MessageBox a where
+  messageBoxType :: a -> T.Text
+  messageBoxValue :: a -> Int
 
 data IconType = Info | Warning | Error | Question
   deriving (Eq, Ord, Show, Read, Enum, Bounded)
 
-{#fun messageBox
+data OK = OK
+  deriving (Eq, Ord, Show, Read, Enum, Bounded)
+
+instance MessageBox OK where
+  messageBoxType _ = T.pack "ok"
+  messageBoxValue OK = 1
+
+data OKCancel = OC_OK | OC_Cancel
+  deriving (Eq, Ord, Show, Read, Enum, Bounded)
+
+instance MessageBox OKCancel where
+  messageBoxType _ = T.pack "okcancel"
+  messageBoxValue OC_Cancel = 0
+  messageBoxValue OC_OK     = 1
+
+data YesNo = YN_Yes | YN_No
+  deriving (Eq, Ord, Show, Read, Enum, Bounded)
+
+instance MessageBox YesNo where
+  messageBoxType _ = T.pack "yesno"
+  messageBoxValue YN_No  = 0
+  messageBoxValue YN_Yes = 1
+
+data YesNoCancel = YNC_Yes | YNC_No | YNC_Cancel
+  deriving (Eq, Ord, Show, Read, Enum, Bounded)
+
+instance MessageBox YesNoCancel where
+  messageBoxType _ = T.pack "yesnocancel"
+  messageBoxValue YNC_Cancel = 0
+  messageBoxValue YNC_Yes    = 1
+  messageBoxValue YNC_No     = 2
+
+{#fun messageBox as c_messageBox
   { withCText*      `T.Text'     -- ^ title
   , withCText*      `T.Text'     -- ^ message, may contain @\\n@ and @\\t@
-  , withCShowLower* `DialogType'
+  , withCText*      `T.Text'     -- ^ "ok" "okcancel" "yesno" "yesnocancel"
   , withCShowLower* `IconType'
-  ,                 `Bool'       -- ^ default button: 'False' for cancel\/no, 'True' for ok\/yes
-  } -> `Bool' -- ^ 'False' for cancel\/no, 'True' for ok/yes
+  ,                 `Int'        -- ^ default button: 0 for cancel/no, 1 for ok/yes, 2 for no in yesnocancel
+  } -> `Int' -- ^ 0 for cancel/no, 1 for ok/yes, 2 for no in yesnocancel
 #}
+
+messageBox
+  :: (MessageBox a)
+  => T.Text -- ^ title
+  -> T.Text -- ^ message, may contain @\\n@ and @\\t@
+  -> IconType
+  -> a -- ^ default button
+  -> IO a
+messageBox ttl msg icon dflt = do
+  n <- c_messageBox ttl msg (messageBoxType dflt) icon (messageBoxValue dflt)
+  case lookup n [ (messageBoxValue x, x) | x <- [minBound .. maxBound] ] of
+    Just x  -> return x
+    Nothing -> error $ "Graphics.UI.TinyFileDialogs.messageBox: internal error; unrecognized return value " ++ show n
 
 {#fun inputBox
   { withCText*      `T.Text'       -- ^ title
diff --git a/tinyfiledialogs.cabal b/tinyfiledialogs.cabal
--- a/tinyfiledialogs.cabal
+++ b/tinyfiledialogs.cabal
@@ -1,5 +1,5 @@
 name:                 tinyfiledialogs
-version:              0.1.0.0
+version:              0.2.0.0
 homepage:             https://github.com/mtolly/tinyfiledialogs
 license:              BSD3
 license-file:         LICENSE
@@ -10,6 +10,7 @@
 build-type:           Simple
 extra-source-files:
   README.md
+  changelog.md
   cbits/tinyfiledialogs.h
 cabal-version:        >= 1.10
 synopsis:             Wrapper around the 'tiny file dialogs' C library
@@ -30,7 +31,7 @@
   .
   * color picker
   .
-  This package bundles the C library (currently v3.0.8)
+  This package bundles the C library (currently v3.0.9)
   and provides a complete Haskell interface.
   Proper Unicode support has been tested on Windows, Mac and Linux.
 
