?
Solved

multithreaded OCX

Posted on 2000-04-07
3
Medium Priority
?
642 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 1800 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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

807 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