Solved

multithreaded OCX

Posted on 2000-04-07
3
623 Views
Last Modified: 2012-06-21
Hi,

I wrote a multithreaded OCX (Visual C++, with the ocx wizzard).

In a second thread (buffer processing) I fire an event to tell the application that someting has to be processed. The application then call's a property, set by the OCX before firing the event.

A Visual C++ application test programm gets the correct values and runs perfect. However, a VB programm crashes when asking the property in the eventhandling. (It does not crash when it asks the property value outside the event-handling!!)

Here's some OCX code :

- creation of the second thread

      AfxBeginThread((AFX_THREADPROC)BufferThread, this);

- the second thread

UINT BufferThread (LPVOID pParam)
{
      CPosKeyboardCtrl* pObject = (CPosKeyboardCtrl*)pParam;    

      if (pObject == NULL ||
      !pObject->IsKindOf(RUNTIME_CLASS(CPosKeyboardCtrl)))
            return 1;   // if pObject is not valid    // do something with 'pObject'

      while (pObject->m_bOpened)
      {
        ResetEvent(hEventReceive);
            // wait until character is received
        WaitForSingleObject(hEventReceive, INFINITE);
            
            while (pVerwerkBuffer < pCurrentBuffer)
                  // we have characters to process
            {
                  pObject->m_pOSKeyData = TheKey;
                  pVerwerkBuffer ++;
      pObject->FireDataEvent(1);
            }
            pVerwerkBuffer = pBeginGlobalBuffer;
            pCurrentBuffer = pBeginGlobalBuffer;
      }
      return TRUE;
}

I am desperate. Why does the C++ testprogramm work, but not a VB programm?

A correct and usable answer please.

JOHan
0
Comment
Question by:johanhz
3 Comments
 
LVL 14

Expert Comment

by:AlexVirochovsky
ID: 2692996
0
 
LVL 4

Accepted Solution

by:
pellep earned 600 total points
ID: 2693252
I've had precisely your problem. The problem lies in the fact that vb doesn't support multithreading to the full extent. This will result in a GPF when you try to fire an event in a second thread of your component. Solve this by only firing events from the main thread of your OCX. It's all described in the article below. Go to microsoft.com and search for 'Q196026'. Their proposed sollution involves sending windows messages to your main thread (and it worked fine for me).
In the second thread, do:
(the arg list is arbitrary
WM_EVENT_ERROR must be defined to for instance (WM_USER+101)
void SecondThreadClass::FireEvent(int iNum, int iSeverity, LPCTSTR lpszDesc, LPCTSTR lpszSource)
{
      void **pArgs = new LPVOID[4];
      pArgs[0] = new char[strlen(lpszDesc) + 1];
      strcpy((char*)pArgs[0], lpszDesc);
      pArgs[1] = new char[strlen(lpszSource) + 1];
      strcpy((char*)pArgs[1], lpszSource);
      pArgs[2] = new int(iNum);
      pArgs[3] = new int(iSeverity);
      PostMessage(WM_EVENT_ERROR, (long)pArgs);
}
In the main thread, add a msg map and bind the WM_EVENT_ERROR to a handler function like:

LRESULT MyMainThreadClass::OnFireError(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
            //ARGS
      //0 = Description (LPCTSTR)
      //1 = Source (LPCTSTR)
      //2 = Number (int*)
      //3 = Severity (int*)

      void **pArgs = (void**)wParam;


        BSTR sDesc;
      BSTR sSource;
      WCHAR   wszBuff[512];            

      //DESCRIPTION
      if (MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)pArgs[0], -1, wszBuff, 512)==0)
            return 0;
      sDesc = SysAllocString(wszBuff);

      //SOURCE
      if (MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)pArgs[1], -1, wszBuff, 512)==0)
            return 0;
      sSource = SysAllocString(wszBuff);
      if ((sDesc == NULL) || (sSource == NULL))
            return 0;
//This would be your ordinary event
//firing function
      Fire_Error(*(int*)pArgs[2],*(int*)pArgs[3], sDesc, sSource);
      delete[] pArgs[0];
      delete[] pArgs[1];
      delete pArgs[2];
      delete pArgs[3];
      delete[] pArgs;
      SysFreeString(sDesc);
      SysFreeString(sSource);
      return 0;
}

Good luck

See MSDN article 'PRB: Firing Event in Second Thread Causes IPF or GPF'
ID: Q196026

0
 

Author Comment

by:johanhz
ID: 2693480
pellep,

Your suggestion led me to the sollution (article ID Q157437), so i'm giving you the points.

Thanks and enjoy!
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question