Hi all
I'm currently involved in a project that is migrating some old VB6 code to C# (.Net Framework 3.5). My mandate is to just do the migration; any functional enhancements or refactoring is to be pushed to a later phase of the project. Not ideal, but there you go.
So part of the VB6 code makes a call out to the Windows API SetTimer function. I've migrated this and cannot get it to work.
The migrated project builds as a DLL; I've created a small WinForms test harness that links to the DLL and calls the code in question. Very simple, just to prove that the call can be made.
The relevant code in the migrated DLL is as follows:
[DllImport("user32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public extern static int SetTimer(int hwnd, int nIDEvent, int uElapse, AsyncObjectCallerDelegate lpTimerFunc);
public delegate void AsyncObjectCallerDelegate(int hwnd, int uMsg, int idEvent, int dwTime);
static public int StartTimer( AsyncGeoServer.GeoWrapper AsyncObj)
{
m_objGeoWrapper = AsyncObj;
int lngReturn = SetTimer(0, 0, 1, new AsyncObjectCallerDelegate(AsyncObjectCaller));
// When the line below is removed, the call functions correctly.
// MessageBox.Show("This is a temp message box!", "Temp Msg Box", MessageBoxButtons.OKCancel);
return lngReturn;
}
static private void AsyncObjectCaller(int hwnd, int uMsg, int idEvent, int dwTime)
{
// Perform processing here - details removed for clarity
}
static public void StopTimer( int TimerID)
{
try { KillTimer(0, TimerID); }
catch { }
}
The above calls are wrapped by the DLL in an outer DoProcessing() method; this creates an event using CreateEvent before calling StartTimer (both Windows Kernel calls), then calls WaitForSingleObject before continuing processing. The AsyncObjectCaller function will set the event as part of its execution to allow processing to continue.
So my issue is this: if the code is called as listed above, it fails. The AsyncObjectCaller callback method never gets triggered and the WaitForSingleObject call times out.
If, however, I uncomment the MessageBox.Show call in StartTimer, it works as expected... sort of. The AsyncObjectCaller callback method gets triggered immediately after the call to MessageBox.Show. I've tried putting MessageBox.Show in various locations in the code, and it's the same no matter where I put it (as long as it's called after the call to SetTimer) - the callback function doesn't get triggered until the messagebox is displayed.
I'm completely stumped, and none too familiar with either VB6 or Windows API coding, coming from a mainly .Net background.
Thanks for any help!