Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Thread and ActiveX component

Thread and ActiveX component

Scheduled Pinned Locked Moved C / C++ / MFC
questionhelpcom
9 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    Farah Mansor
    wrote on last edited by
    #1

    I have 3 classes: class A - dialog class class B - thread class class C - ActiveX class (included in dialog) (the activeX component is a socket component and I create one variable for it in dialog class) The scenario is like this: The dialog will be initialized. The application will winsock other application. After it receive a data from socket component, it will initiate the thread. The thread then will call one method in dialog class which is using socket component. What the method (inside dialog class) should do here is, it will check the connection status. But it failed (it gives me runtime error - access violation error) The question is: 1) How can I call method in class C(activeX component) straight from class B?? 2) If cannot call directly from class B, where can I call the method? I try to call from class A but it failed. so can anybody help me to resolve on this. I want to use the thread for checking the status connection. Thanks in advance.:) FM

    G 1 Reply Last reply
    0
    • F Farah Mansor

      I have 3 classes: class A - dialog class class B - thread class class C - ActiveX class (included in dialog) (the activeX component is a socket component and I create one variable for it in dialog class) The scenario is like this: The dialog will be initialized. The application will winsock other application. After it receive a data from socket component, it will initiate the thread. The thread then will call one method in dialog class which is using socket component. What the method (inside dialog class) should do here is, it will check the connection status. But it failed (it gives me runtime error - access violation error) The question is: 1) How can I call method in class C(activeX component) straight from class B?? 2) If cannot call directly from class B, where can I call the method? I try to call from class A but it failed. so can anybody help me to resolve on this. I want to use the thread for checking the status connection. Thanks in advance.:) FM

      G Offline
      G Offline
      Ghazi H Wadi
      wrote on last edited by
      #2

      Hello Farah, Make sure you synchronizing the data access. what I think is happening is that have not locked the data befoe changing it, in the mean time another thread is using it or modifying it. Imagine making a withdraw from a bank account while there is a deposit operation in progress. Here is anexample of using CCriticalSection to avoid such problem. (it is from an article by Dianne M. Marsh on VisualC++ magazine)

      class AccountInfo
      {
      private:
      float balance;
      string accountName;
      CCriticalSection balanceCode;
      CSingleLock *balanceLock;

      public:
      AccountInfo(const string &name) :
      balance(0.0), accountName(name)
      {
      balanceLock = new
      CSingleLock(&balanceCode,
      false);
      }

      ~AccountInfo() {
      delete balanceLock;
      }

      void deposit(float amount) {

        balanceLock->Lock();
        balance +=   amount;
        balanceLock->Unlock();
      

      }

      void withdraw(float
      amount) {
      balanceLock->Lock();
      balance -= amount;
      balanceLock->Unlock();
      }
      float getBalance() const {
      balanceLock->Lock();
      float val = balance;
      balanceLock->Unlock();
      return val;
      }
      };

      On the other hand it could be that you are calling endthread() before you are returning from the thread function, hile one of the vaiables declared in the thread function is declared on the stack and it does some cleaning in the destructor. To solve this problem, Use new and delete. Otherwise, if this did not help, I suggest you post some code samples. Cheers Alfadhly It is Illogical to define an inventor by his invention

      F 1 Reply Last reply
      0
      • G Ghazi H Wadi

        Hello Farah, Make sure you synchronizing the data access. what I think is happening is that have not locked the data befoe changing it, in the mean time another thread is using it or modifying it. Imagine making a withdraw from a bank account while there is a deposit operation in progress. Here is anexample of using CCriticalSection to avoid such problem. (it is from an article by Dianne M. Marsh on VisualC++ magazine)

        class AccountInfo
        {
        private:
        float balance;
        string accountName;
        CCriticalSection balanceCode;
        CSingleLock *balanceLock;

        public:
        AccountInfo(const string &name) :
        balance(0.0), accountName(name)
        {
        balanceLock = new
        CSingleLock(&balanceCode,
        false);
        }

        ~AccountInfo() {
        delete balanceLock;
        }

        void deposit(float amount) {

          balanceLock->Lock();
          balance +=   amount;
          balanceLock->Unlock();
        

        }

        void withdraw(float
        amount) {
        balanceLock->Lock();
        balance -= amount;
        balanceLock->Unlock();
        }
        float getBalance() const {
        balanceLock->Lock();
        float val = balance;
        balanceLock->Unlock();
        return val;
        }
        };

        On the other hand it could be that you are calling endthread() before you are returning from the thread function, hile one of the vaiables declared in the thread function is declared on the stack and it does some cleaning in the destructor. To solve this problem, Use new and delete. Otherwise, if this did not help, I suggest you post some code samples. Cheers Alfadhly It is Illogical to define an inventor by his invention

        F Offline
        F Offline
        Farah Mansor
        wrote on last edited by
        #3

        Here I post some sample codes: // myDlg class (class A) CSocketSvr mySocket; // my socket variable // ActiveX event handler void myDlg::OnReceivedData(LPCTSTR ReceivedData) { ... // I start my thread - it will execute for the first time I receive any data if (TRUE) { pThread = (CWzdThread*)AfxBeginThread(RUNTIME_CLASS(CWzdThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); } ... } // my method void myDlg::Check() { if (mySocket.GetConnectedStatus()) <--- THIS IS WHERE IT GIVES ME THE RUNTIME ERROR { ... } } ///////////////////////////////////////// // CWzdThread class (class B) myDlg* pDlg; int CWzdThread::Run() { while(TRUE) { ... pDlg->Check(); } } /////////////////////////////////////////////// // CSocketSvr class (the activeX control class) // to get the connection status bool CSocketSvr::GetConnectedStatus() { .... return result; } I think this will give you enough information about what I am trying to do here. mmm I still don't get it where should I add the Lock function. :confused: Can you please explain more on that. :) Thank you so much for your help. :rose: FM

        G 1 Reply Last reply
        0
        • F Farah Mansor

          Here I post some sample codes: // myDlg class (class A) CSocketSvr mySocket; // my socket variable // ActiveX event handler void myDlg::OnReceivedData(LPCTSTR ReceivedData) { ... // I start my thread - it will execute for the first time I receive any data if (TRUE) { pThread = (CWzdThread*)AfxBeginThread(RUNTIME_CLASS(CWzdThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); } ... } // my method void myDlg::Check() { if (mySocket.GetConnectedStatus()) <--- THIS IS WHERE IT GIVES ME THE RUNTIME ERROR { ... } } ///////////////////////////////////////// // CWzdThread class (class B) myDlg* pDlg; int CWzdThread::Run() { while(TRUE) { ... pDlg->Check(); } } /////////////////////////////////////////////// // CSocketSvr class (the activeX control class) // to get the connection status bool CSocketSvr::GetConnectedStatus() { .... return result; } I think this will give you enough information about what I am trying to do here. mmm I still don't get it where should I add the Lock function. :confused: Can you please explain more on that. :) Thank you so much for your help. :rose: FM

          G Offline
          G Offline
          Ghazi H Wadi
          wrote on last edited by
          #4

          Hi, this is assuming that the variable *pDlg has been initilized to be equal to the this pointer of myDlg when it is created , in the oninitdialog or so If the mySocket variable exist the error should happen somewhere here bool CSocketSvr::GetConnectedStatus() { .... return result; } if it does not exist, then it should not have been called at all unless you have multiple threads accessing the same instance. on the other hand it could be that you are accessing the same variable while it is being used. (the case each time new data is being received) so you must call the lock before you call any operation on the variable. Here is a simple way without using MFC 1) Declare critical section CRITICAL_SECTION g_CriticalSection; ... .. .. 2) When Program Starts, initilize the critical section ::InitializeCriticalSection (&g_CriticalSection); 3) When the program terminate, delete the critical section ::DeleteCriticalSection (&g_CriticalSection); 4) Whenever you are accessing mySocket ::EnterCriticalSection (&g_CriticalSection); if (mySocket.GetConnectedStatus()) <--- THIS IS WHERE IT GIVES ME THE RUNTIME ERROR { .. } ::LeaveCriticalSection(&g_CriticalSection); It is Illogical to define an inventor by his invention Cheers Alfadhly

          F 1 Reply Last reply
          0
          • G Ghazi H Wadi

            Hi, this is assuming that the variable *pDlg has been initilized to be equal to the this pointer of myDlg when it is created , in the oninitdialog or so If the mySocket variable exist the error should happen somewhere here bool CSocketSvr::GetConnectedStatus() { .... return result; } if it does not exist, then it should not have been called at all unless you have multiple threads accessing the same instance. on the other hand it could be that you are accessing the same variable while it is being used. (the case each time new data is being received) so you must call the lock before you call any operation on the variable. Here is a simple way without using MFC 1) Declare critical section CRITICAL_SECTION g_CriticalSection; ... .. .. 2) When Program Starts, initilize the critical section ::InitializeCriticalSection (&g_CriticalSection); 3) When the program terminate, delete the critical section ::DeleteCriticalSection (&g_CriticalSection); 4) Whenever you are accessing mySocket ::EnterCriticalSection (&g_CriticalSection); if (mySocket.GetConnectedStatus()) <--- THIS IS WHERE IT GIVES ME THE RUNTIME ERROR { .. } ::LeaveCriticalSection(&g_CriticalSection); It is Illogical to define an inventor by his invention Cheers Alfadhly

            F Offline
            F Offline
            Farah Mansor
            wrote on last edited by
            #5

            mmm.. it seem it doesn't work with the critical section. Still give me the same error. :( Don't know why thread still cannot call the activeX control methods? :(( :(( FM

            G 1 Reply Last reply
            0
            • F Farah Mansor

              mmm.. it seem it doesn't work with the critical section. Still give me the same error. :( Don't know why thread still cannot call the activeX control methods? :(( :(( FM

              G Offline
              G Offline
              Ghazi H Wadi
              wrote on last edited by
              #6

              Hi Farah, Does that mean you have already initilized the *pDlg to point to an instance of MyDlg? Cheers It is Illogical to define an inventor by his invention

              F 1 Reply Last reply
              0
              • G Ghazi H Wadi

                Hi Farah, Does that mean you have already initilized the *pDlg to point to an instance of MyDlg? Cheers It is Illogical to define an inventor by his invention

                F Offline
                F Offline
                Farah Mansor
                wrote on last edited by
                #7

                Yupp. I already assign *pDlg to point to an instance of myDlg. FMansor

                G 1 Reply Last reply
                0
                • F Farah Mansor

                  Yupp. I already assign *pDlg to point to an instance of myDlg. FMansor

                  G Offline
                  G Offline
                  Ghazi H Wadi
                  wrote on last edited by
                  #8

                  I hope you don't mean this line

                  // CWzdThread class (class B)
                  myDlg* pDlg;

                  Cheers It is Illogical to define an inventor by his invention

                  L 1 Reply Last reply
                  0
                  • G Ghazi H Wadi

                    I hope you don't mean this line

                    // CWzdThread class (class B)
                    myDlg* pDlg;

                    Cheers It is Illogical to define an inventor by his invention

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #9

                    Yupp. That's what I did. But before I resume the thread, I assign this (which belongs to dialog class) to pDlg. This is my code: in dialog class: void CMyDlg::OnDataArrival() { .... pThread = (CWzdThread*)AfxBeginThread(RUNTIME_CLASS(CWzdThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); pThread->MainDlg(this); pThread->ResumeThread(); ... } in thread class: void CWzdThread::MainDlg(CMyDlg* spDlg) { pDlg = spDlg; } int CWzdThread::Run() { ... pDlg->Check(); ... } Hope I do not confuse you. TIA :) FM - I can't remember my username :|

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups