On 24.09.2010, at 00:07, Albrecht Schlosser wrote:

[Ian wrote]
Also, Fl_win32.cxx may call CoInitialize if it has not already called
OleInitialize - though looking briefly at this I could not see how it
could ever get to the code that calls CoInitialize without having first
executed the part that does OleInitialize, so that may be redundant
code... If so we could remove it and make things a bit simpler.

I didn't check that, but if you're right that's even better. Otherwise
we would check the flag anyway and don't call it a 2nd time.

Checked, and I agree. It can't be called. I removed it in my patch.

Now, in Fl.cxx, the Fl_Win32_At_Exit code unconditionally calls
OleUninitialize (and nobody ever calls CoUninitialize) so:

We simplify Fl_win32.cxx to only use OleInitialize (not CoInitialize)
and add a mechanism so that both Fl_win32 and Fl_Native_File_Chooser
will flag up that they have loaded OleInitialize (and not load it again)
and make sure that Fl.cxx only calls OleUninitialize if that flag is
set...

Something like that?

Exactly that ! ;-)

Please see attached patch. Andy, could you please test this and
confirm, if this fixes the problem? Ian, is there anything that
I might have missed?

Please note that this is maybe not yet complete, because it doesn't
check the gcc 2.x compatibility, but I presume that we can remove
gcc 2.x support, and then it should be okay. And beware: it's really
late here now.

Albrecht
Index: src/Fl_win32.cxx
===================================================================
--- src/Fl_win32.cxx    (Revision 7704)
+++ src/Fl_win32.cxx    (Arbeitskopie)
@@ -1554,14 +1554,10 @@
   // Drag-n-drop requires GCC 3.x or a non-GNU compiler...
 #if !defined(__GNUC__) || __GNUC__ >= 3
   // Register all windows for potential drag'n'drop operations
-  static char oleInitialized = 0;
-  if (!oleInitialized) { OleInitialize(0L); oleInitialized=1; }
-
+  fl_OleInitialize();
   RegisterDragDrop(x->xid, flIDropTarget);
+
   if (!fl_aimm) {
-    static char been_here = 0;
-    if (!been_here && !oleInitialized) CoInitialize(NULL);
-    been_here = 1;
     CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_INPROC_SERVER,
                     IID_IActiveIMMApp, (void**) &fl_aimm);
     if (fl_aimm) {
Index: src/Fl.cxx
===================================================================
--- src/Fl.cxx  (Revision 7704)
+++ src/Fl.cxx  (Arbeitskopie)
@@ -484,13 +484,35 @@
 }
 
 #ifdef WIN32
+
+// Function to initialize COM/OLE for usage. This must be done only once.
+// We define a flag to register whether we called it:
+static char oleInitialized = 0;
+
+// This calls the Windows function OleInitialize() exactly once.
+void fl_OleInitialize() {
+  if (!oleInitialized) {
+    OleInitialize(0L);
+    oleInitialized = 1;
+  }
+}
+
+// This calls the Windows function OleUninitialize() only, if
+// OleInitialize has been called before.
+void fl_OleUninitialize() {
+  if (oleInitialized) {
+    OleUninitialize();
+    oleInitialized = 0;
+  }
+}
+
 class Fl_Win32_At_Exit {
 public:
   Fl_Win32_At_Exit() { }
   ~Fl_Win32_At_Exit() {
     fl_free_fonts();        // do some WIN32 cleanup
     fl_cleanup_pens();
-    OleUninitialize();
+    fl_OleUninitialize();
     fl_brush_action(1);
     fl_cleanup_dc_list();
   }
Index: src/Fl_Native_File_Chooser_WIN32.cxx
===================================================================
--- src/Fl_Native_File_Chooser_WIN32.cxx        (Revision 7704)
+++ src/Fl_Native_File_Chooser_WIN32.cxx        (Arbeitskopie)
@@ -47,6 +47,8 @@
 #define RBRACKET_CHR   ']'
 #define MAXFILTERS     80
 
+void fl_OleInitialize();       // in Fl.cxx (Windows only)
+
 // STATIC: PRINT WINDOWS 'DOUBLE NULL' STRING (DEBUG)
 static void dnullprint(char *wp) {
   if ( ! wp ) return;
@@ -464,7 +466,8 @@
 
 // SHOW DIRECTORY BROWSER
 int Fl_Native_File_Chooser::showdir() {
-  OleInitialize(NULL);         // init needed by BIF_USENEWUI
+  // initialize OLE only once
+  fl_OleInitialize();          // init needed by BIF_USENEWUI
   ClearBINF();
   clear_pathnames();
   // PARENT WINDOW
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to