Report after porting a windows app to WINE

Mike Engelhardt pmte at concentric.net
Fri Feb 28 14:00:57 CST 2003


Alexandre,

> > I've noticed a few things about WINE that might help you
> > improve it.  WINE can confuse SendMessage() with PostMessage().
> > LTspice uses SendMessage to handshake between threads
> > sometimes.  Wine usually obeys the difference, but treated
> > some SendMessage calls like a PostMessage.  My workaround
> > was to poll volatile global variables.
>
> I'd be interested to hear more details; SendMessage is
> definitely supposed to behave properly.

Here's the situation:  The app has two threads.  One is the
whole MDI/user interface/CAD and text editor.  The worker
thread does a simulation of the circuit you draw in the
CAD editor.  The messages are all registered messages for a
historical reason in a footnote(1).

The first message back from the worker thread says it's got
some partial data to plot and sends a message to the view
window that launched the thread.  The view knows the name of
the file containing the data and launches a doc/view to
read it.  That doc/view throws up a dialog asking which
data to plot.  The schematic doc/view and plotting doc/view
handshake here by calling each other's functions and setting
each other's data members.  After the data is read, the
original view to get the message from the working thread
returns the number of data points that were found in the
file.  All this time the worker thread, having done a
SendMessage() and not a PostMessage(), is frozen waiting
for the return value of the number of points so it can
decide where to try again or continue.  The scheme that
I'm using has been extensively debugged and used under
95,98,Me,NT,2K, and XP.  But under wine, the worker thread
doesn't freeze when it calls SendMessage() but keeps
executing.  It's imperative that it does because on
subsequent calls from the worker to the UI thread, it
sends little compressed packets of data.  The UI must
process these before the worker thread continues.

//Here's the code that worked under Windows:

   int nPnts = SendMessage(TheChartWindow, WM_MARCH_INIT, 0, 0);
   if(nPnts != run->pointCount) // try again if it failed
      SendMessage(TheChartWindow, WM_MARCH_INIT, 0, 0);

// And here's the code hacked to work under Wine:
volatile BOOL LinuxProcessed = FALSE;
volatile int NumberPoints    = 0;

unsigned MarchInit()
{
   NumberPoints   = 0;
   LinuxProcessed = FALSE;
   SendMessage(TheChartWindow, WM_MARCH_INIT, 0, 0); // the function that
receives this will
                                                     // assign the return
value to NumberPoints
                                                     // and assign a value
to LinuxProcessed
   while(!LinuxProcessed) // Will Wine every simply ever lose the message?
Do I need to time-out?
      Sleep(100);
   return(NumberPoints);
}

   int nPnts = MarchInit();
   if(nPnts != run->pointCount)
      MarchInit();

I did find one other problem in Wine that may or may not
be related to messaging, that being with the FindReplace
common dialog.  When you press "Find Next" which is IDOK,
under Wine nothings happened in my app.  My app uses one
FindReplace dialog for all document types and relates the
command to the active document.  The workaround was to
add an OnOK() handler:

// Wine is a global BOOL the TRUE if running under Wine
void CFindDlg::OnOK()
// for WINE
{
// for WINE
   if(Wine)
// for WINE

{                                                                         //
for WINE
      WineFindReplaceHack = TRUE;
// for WINE
      LPARAM lParam = (unsigned ) this + offsetof(CFindReplaceDialog, m_fr);
// for WINE
      ::SendMessage(theApp.m_pMainWnd->m_hWnd, WM_FINDREPLACE, 0, lParam);
// for WINE
      WineFindReplaceHack = FALSE;
// for WINE
   }
// for WINE
   else
// for WINE
      Default();
// for WINE
}
// for WINE

LRESULT CMainFrame::OnFindString(WPARAM wParam, LPARAM lParam)
{
   CFindDlg *dlg = (CFindDlg *) CFindReplaceDialog::GetNotifier(lParam);
   .
   .
   .
   if(WineFindReplaceHack || dlg->FindNext())
   {
      // search active document for dlg->m_findWindowText and highlight.
   }
   .
   .
   .
   return(0);
}

Let me know if you have any other questions.  I'd like to be
as helpful as I can in this and immensely appreciate the
help that, e.g., Uwe has been.  I officially feel guilty
that I'm not subscribed to the e-mail list, but I get
too many e-mails and phone calls as it is.

--Mike

(1)  Normally the graphical schematic drives the worker thread.
but a text netlist can also be used.  I used to use a CEditView
for this netlist and under Win95, the original message scheme
didn't work until I used registered messages.  I no longer use
a CEditView but an more general purpose syntax colonizing editor
with unlimited undo/redo, so i don't know if the messages still
have to be registered.






More information about the wine-devel mailing list