Index: Fl_win32.cxx
===================================================================
--- Fl_win32.cxx	(revision 12459)
+++ Fl_win32.cxx	(working copy)
@@ -1737,6 +1737,88 @@
 
 ////////////////////////////////////////////////////////////////
 
+#include "Psapi.h"
+#pragma comment( lib, "psapi.lib" )
+static HMODULE GetModuleHandleByAddress(HANDLE hProc, LPVOID lpAddress) {	// str #3350
+  HANDLE hHeap = GetProcessHeap();
+  HMODULE *hmodules = NULL;
+  DWORD cb = 0;
+  while (1) {
+    DWORD cbNeeded = 0;
+    if (!EnumProcessModules(hProc, hmodules, cb, &cbNeeded)) {
+      return NULL;
+    }
+    if (cb >= cbNeeded) {
+      cb = cbNeeded;
+      break;
+    }
+    PVOID p = HeapAlloc(hHeap, 0, cbNeeded);
+    HeapFree(hHeap, 0, hmodules);
+    if (p == NULL) return NULL;
+    hmodules = (HMODULE*)p;
+    cb = cbNeeded;
+  }
+
+  DWORD i = 0;
+  DWORD ccModules = cb / sizeof(HMODULE);
+  HMODULE hm = NULL;
+
+  for (; i < ccModules; ++i) {
+    MODULEINFO modinfo;
+    if(!GetModuleInformation(hProc, hmodules[i], &modinfo, sizeof(modinfo)))
+      continue;
+    if(lpAddress < modinfo.lpBaseOfDll)
+      continue;
+    if((ULONG_PTR)lpAddress >= ((ULONG_PTR)modinfo.lpBaseOfDll + modinfo.SizeOfImage))
+      continue;
+    hm = (HMODULE)modinfo.lpBaseOfDll;
+    break;
+  }
+  if (i == ccModules && hm == NULL)
+    SetLastError(ERROR_MOD_NOT_FOUND);
+  HeapFree(hHeap, 0, hmodules);
+  return hm;
+}
+
+static HMODULE GetCurrentModule() {	// str #3350
+  HMODULE hModule = GetModuleHandleByAddress(GetCurrentProcess(), &GetCurrentModule);
+  return hModule;
+}
+
+
+#define USER_ERROR 0x20000000
+static BOOL CALLBACK HandleWindowClosing(HWND hwnd, LPARAM lParam) {	// str #3350
+  unsigned processID = 0;
+  if (processID == GetCurrentProcessId()) {
+    const char* const classNameToClose = (const char* const)lParam;
+    char className[MAX_PATH] = "";
+    GetClassName(hwnd, className, sizeof(className));
+    className[MAX_PATH-1] = '\0';
+    if (strcmp(className, classNameToClose) == 0) {
+      BOOL ret = DestroyWindow(hwnd);
+      if (!ret) {
+	SetLastError(GetLastError() | USER_ERROR);
+	return FALSE;
+      }
+    }
+  }
+  return TRUE;
+}
+
+static void unregister_class(const char* classname) {	// str #3350
+  if (classname) {
+    HINSTANCE hInst = GetModuleHandle(NULL);
+    BOOL ret = UnregisterClassA(classname,  hInst);
+    if (!ret) {
+      unsigned err = GetLastError();
+      if (err == ERROR_CLASS_HAS_WINDOWS) {
+	EnumWindows(HandleWindowClosing, (LPARAM)(void*)classname);
+	ret = UnregisterClassA(classname,  hInst);
+      }
+    }
+  }
+}
+
 /*
  * This silly little class remembers the name of all window classes
  * we register to avoid double registration. It has the added bonus
@@ -1747,7 +1829,10 @@
   NameList() { name = (char**)malloc(sizeof(char**)); NName = 1; nName = 0; }
   ~NameList() {
     int i;
-    for (i=0; i<nName; i++) free(name[i]);
+    for (i=0; i<nName; i++) {
+      unregister_class(name[i]);		// str#3350
+      free(name[i]);
+    }
     if (name) free(name);
   }
   void add_name(const char *n) {
@@ -1769,6 +1854,8 @@
   int nName, NName;
 };
 
+static NameList class_name_list;	// str #3350
+
 void fl_fix_focus(); // in Fl.cxx
 
 // int fl_background_pixel = -1; // color to use for background
@@ -1789,25 +1876,34 @@
     return 0L;
   }
 
-  static NameList class_name_list;
+  char long_class_name[MAX_PATH];
   static const char *first_class_name = 0L;
   const char *class_name = w->xclass();
   if (!class_name) class_name = first_class_name; // reuse first class name used
   if (!class_name) class_name = "FLTK"; // default to create a "FLTK" WNDCLASS
-  if (!first_class_name) {
-    first_class_name = class_name;
-  }
 
-  wchar_t class_namew[100]; // (limited) buffer for Windows class name
+  // Create long name, e.g. "c:\somepath\yourapp.exe_FLTK"
+  //                         ----------------------- ----
+  //                                 |                 |
+  //                         GetModuleFileName()     class_name
+  //
+  char moduleName[MAX_PATH] = "";
+  GetModuleFileNameA(GetCurrentModule(), moduleName, MAX_PATH);
+  moduleName[MAX_PATH-1] = '\0';
+  snprintf(long_class_name, MAX_PATH, "%s_%s", moduleName, class_name);
+  long_class_name[MAX_PATH-1] = '\0';	    // snprintf() truncates w/out NULL if too long
 
+  if (!first_class_name) first_class_name = long_class_name;
+  
   // convert UTF-8 class_name to wchar_t for RegisterClassExW and CreateWindowExW
-
-  fl_utf8toUtf16(class_name,
-		 (unsigned)strlen(class_name),		// in
+  wchar_t class_namew[MAX_PATH]; // (limited) buffer for Windows class name
+  fl_utf8toUtf16(long_class_name,			// str #3350
+		 (unsigned)strlen(long_class_name),	// in
 		 (unsigned short*)class_namew,		// out
-		 (unsigned)sizeof(class_namew)/sizeof(wchar_t));	// max. size
+		 (unsigned)MAX_PATH);			// max. size
 
-  if (!class_name_list.has_name(class_name)) {
+  if (!class_name_list.has_name(long_class_name)) { 
+
     WNDCLASSEXW wcw;
     memset(&wcw, 0, sizeof(wcw));
     wcw.cbSize = sizeof(WNDCLASSEXW);
@@ -1830,7 +1926,7 @@
     wcw.lpszMenuName = NULL;
     wcw.lpszClassName = class_namew;
     RegisterClassExW(&wcw);
-    class_name_list.add_name(class_name);
+    class_name_list.add_name(long_class_name);	// str #3350
   }
 
   const wchar_t* message_namew = L"FLTK::ThreadWakeup";
@@ -2010,6 +2106,10 @@
   ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE :
 	     (Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
 
+  if (!class_name_list.has_name(long_class_name)) {	// str #3350
+    class_name_list.add_name(long_class_name);
+  }
+
   // Register all windows for potential drag'n'drop operations
   RegisterDragDrop(x->xid, flIDropTarget);
 
