Solved

multithreaded OCX

Posted on 2000-04-07
3
628 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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

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…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
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.

685 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