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
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. CObject (CView - CDoument) callbacks

CObject (CView - CDoument) callbacks

Scheduled Pinned Locked Moved C / C++ / MFC
c++questionannouncementlounge
11 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.
  • T Tony Teveris

    callback (p1, p2, p3, ....) { CView *pView = (CView *)p1 pView->whatever() causes ASSERT as defined in wincore.cpp - void CWnd::AssertValid() } MainApp{ CDocument::OnCommand - selected some operation from menu CView *pView = get active view call DLL (pView, p2, p3, ...) } DLL { put up dialog move slider, now need to update pView in main app callback(pView, p2, p3 ...) } No matter if I pass a ptr to CDocument or CView the callback will fail (ASSERT) someplace If I pass in the HWND and in the callback use CWnd::FromHandle() and then call InvalidateRect() I can get thinks to redraw but I want to access items in the Doc or View. The ASSERT code states // Note: if either of the above asserts fire and you are // writing a multithreaded application, it is likely that // you have passed a C++ object from one thread to another // and have used that object in a way that was not intended. // (only simple inline wrapper functions should be used) // // In general, CWnd objects should be passed by HWND from // one thread to another. The receiving thread can wrap // the HWND with a CWnd object by using CWnd::FromHandle. // // It is dangerous to pass C++ objects from one thread to // another, unless the objects are designed to be used in // such a manner. So does anyone have a way around this? Thanks in advance

    Tony Teveris Gerber Scientific Products Senior Software Engineer Phone: 860 648 8151 Fax: 860 648 8214 83 Gerber Road West South Windsor, CT 06074

    L Offline
    L Offline
    led mike
    wrote on last edited by
    #2

    Tony Teveris wrote:

    So does anyone have a way around this?

    Does anyone include Microsoft[^] ? :rolleyes:

    1 Reply Last reply
    0
    • T Tony Teveris

      callback (p1, p2, p3, ....) { CView *pView = (CView *)p1 pView->whatever() causes ASSERT as defined in wincore.cpp - void CWnd::AssertValid() } MainApp{ CDocument::OnCommand - selected some operation from menu CView *pView = get active view call DLL (pView, p2, p3, ...) } DLL { put up dialog move slider, now need to update pView in main app callback(pView, p2, p3 ...) } No matter if I pass a ptr to CDocument or CView the callback will fail (ASSERT) someplace If I pass in the HWND and in the callback use CWnd::FromHandle() and then call InvalidateRect() I can get thinks to redraw but I want to access items in the Doc or View. The ASSERT code states // Note: if either of the above asserts fire and you are // writing a multithreaded application, it is likely that // you have passed a C++ object from one thread to another // and have used that object in a way that was not intended. // (only simple inline wrapper functions should be used) // // In general, CWnd objects should be passed by HWND from // one thread to another. The receiving thread can wrap // the HWND with a CWnd object by using CWnd::FromHandle. // // It is dangerous to pass C++ objects from one thread to // another, unless the objects are designed to be used in // such a manner. So does anyone have a way around this? Thanks in advance

      Tony Teveris Gerber Scientific Products Senior Software Engineer Phone: 860 648 8151 Fax: 860 648 8214 83 Gerber Road West South Windsor, CT 06074

      M Offline
      M Offline
      Mark Salsbery
      wrote on last edited by
      #3

      I don't see anything in your sample code that shows different threads. Am I missing something? Calls across the EXE/DLL boundary should be safe, unless the DLL is linked to a separate MFC library, in which case all bets are off. The only way this will work is to use a true MFC extension DLL[^]. Mark

      Mark Salsbery Microsoft MVP - Visual C++ :java:

      T 1 Reply Last reply
      0
      • M Mark Salsbery

        I don't see anything in your sample code that shows different threads. Am I missing something? Calls across the EXE/DLL boundary should be safe, unless the DLL is linked to a separate MFC library, in which case all bets are off. The only way this will work is to use a true MFC extension DLL[^]. Mark

        Mark Salsbery Microsoft MVP - Visual C++ :java:

        T Offline
        T Offline
        Tony Teveris
        wrote on last edited by
        #4

        If the DLL is displaying a dialog and the dialog code through it's messageing calls the callback is there a problem. Do dialogs operate in the same thread or different ? When I first did this I thought that same as you but it does fail. In the DLL I am using some 3rd part imaging software (LEAD) but it all links with the same liraries.

        Tony Teveris Gerber Scientific Products Senior Software Engineer Phone: 860 648 8151 Fax: 860 648 8214 83 Gerber Road West South Windsor, CT 06074

        M 1 Reply Last reply
        0
        • T Tony Teveris

          If the DLL is displaying a dialog and the dialog code through it's messageing calls the callback is there a problem. Do dialogs operate in the same thread or different ? When I first did this I thought that same as you but it does fail. In the DLL I am using some 3rd part imaging software (LEAD) but it all links with the same liraries.

          Tony Teveris Gerber Scientific Products Senior Software Engineer Phone: 860 648 8151 Fax: 860 648 8214 83 Gerber Road West South Windsor, CT 06074

          M Offline
          M Offline
          Mark Salsbery
          wrote on last edited by
          #5

          Unless you've left out some code, it's all on one thread. As shown, there's only one message loop - running in the EXE's CWinApp object. How is the dialog created in the DLL? Does the dialog use a different thread for it's message loop? Mark

          Mark Salsbery Microsoft MVP - Visual C++ :java:

          T 1 Reply Last reply
          0
          • M Mark Salsbery

            Unless you've left out some code, it's all on one thread. As shown, there's only one message loop - running in the EXE's CWinApp object. How is the dialog created in the DLL? Does the dialog use a different thread for it's message loop? Mark

            Mark Salsbery Microsoft MVP - Visual C++ :java:

            T Offline
            T Offline
            Tony Teveris
            wrote on last edited by
            #6

            the DLL function AFX_MANAGE_STATE(AfxGetStaticModuleState( )); nRet = DoDialogBoxParam(IDD_BCI_DLG, hParentWnd, (DLGPROC)BCIDlgProc, (LPARAM) pBciDlgData); the partent windows is that of the main app, the dialog resource is in the DLL

            Tony Teveris Gerber Scientific Products Senior Software Engineer Phone: 860 648 8151 Fax: 860 648 8214 83 Gerber Road West South Windsor, CT 06074

            M 1 Reply Last reply
            0
            • T Tony Teveris

              the DLL function AFX_MANAGE_STATE(AfxGetStaticModuleState( )); nRet = DoDialogBoxParam(IDD_BCI_DLG, hParentWnd, (DLGPROC)BCIDlgProc, (LPARAM) pBciDlgData); the partent windows is that of the main app, the dialog resource is in the DLL

              Tony Teveris Gerber Scientific Products Senior Software Engineer Phone: 860 648 8151 Fax: 860 648 8214 83 Gerber Road West South Windsor, CT 06074

              M Offline
              M Offline
              Mark Salsbery
              wrote on last edited by
              #7

              DoDialogBoxParam? I meant at the MFC/Win32 level - I have no idea what your functions do :) Is the dialog created using MFC or Win32? Modal or modeless? Also important is what type of DLL you're using - MFC extension DLL or regular DLL linked to MFC (see Kinds of DLLs[^]). Mark

              Mark Salsbery Microsoft MVP - Visual C++ :java:

              T 1 Reply Last reply
              0
              • M Mark Salsbery

                DoDialogBoxParam? I meant at the MFC/Win32 level - I have no idea what your functions do :) Is the dialog created using MFC or Win32? Modal or modeless? Also important is what type of DLL you're using - MFC extension DLL or regular DLL linked to MFC (see Kinds of DLLs[^]). Mark

                Mark Salsbery Microsoft MVP - Visual C++ :java:

                T Offline
                T Offline
                Tony Teveris
                wrote on last edited by
                #8

                Sorry about that DLGPROC pfn; pfn = (DLGPROC) MakeProcInstance((FARPROC) pfnDialog, AfxGetApp()->m_hInstance); nRet = (L_INT) DialogBoxParam(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(nDialog), hWnd, pfn, lParam); FreeProcInstance((FARPROC) pfn); Regular DLL using / linked with MFC (NOT static, same as main app) within wincore.cpp here is where it fails // should be a normal window ASSERT(::IsWindow(m_hWnd)); // should also be in the permanent or temporary handle map CHandleMap* pMap = afxMapHWND(); ASSERT(pMap != NULL); I have to ask the programmer of the main app some questions. I agree with you so far so I think there has to be something in our code messing something up.

                Tony Teveris Gerber Scientific Products Senior Software Engineer Phone: 860 648 8151 Fax: 860 648 8214 83 Gerber Road West South Windsor, CT 06074

                M 1 Reply Last reply
                0
                • T Tony Teveris

                  Sorry about that DLGPROC pfn; pfn = (DLGPROC) MakeProcInstance((FARPROC) pfnDialog, AfxGetApp()->m_hInstance); nRet = (L_INT) DialogBoxParam(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(nDialog), hWnd, pfn, lParam); FreeProcInstance((FARPROC) pfn); Regular DLL using / linked with MFC (NOT static, same as main app) within wincore.cpp here is where it fails // should be a normal window ASSERT(::IsWindow(m_hWnd)); // should also be in the permanent or temporary handle map CHandleMap* pMap = afxMapHWND(); ASSERT(pMap != NULL); I have to ask the programmer of the main app some questions. I agree with you so far so I think there has to be something in our code messing something up.

                  Tony Teveris Gerber Scientific Products Senior Software Engineer Phone: 860 648 8151 Fax: 860 648 8214 83 Gerber Road West South Windsor, CT 06074

                  M Offline
                  M Offline
                  Mark Salsbery
                  wrote on last edited by
                  #9

                  Tony Teveris wrote:

                  I have to ask the programmer of the main app some questions.

                  Yes :) The module state stuff can affect CWnd pointers across the EXE/DLL module boundary depending on the type of DLL. This needs to be managed correctly. The CHandleMap is related to the module state. Your CView is in the EXE's map but in the DLL function, you've changed the module state, so when the callback is called, the code on the EXE side isn't finding the CView object in the DLL's map. That's why the type of DLL is important. With a properly initialized extension DLL, you don't need to use the AFX_MANAGE_STATE macro. Using an MFC extension DLL is definitely the best/easiest for passing CWnds back and forth across the EXE/DLL boundary. The drawback to an extension DLL is it can't be used by a non-MFC EXE. If you must use a standard DLL, then you'll need to manage the module state for your callback. Mark

                  Mark Salsbery Microsoft MVP - Visual C++ :java:

                  T 1 Reply Last reply
                  0
                  • M Mark Salsbery

                    Tony Teveris wrote:

                    I have to ask the programmer of the main app some questions.

                    Yes :) The module state stuff can affect CWnd pointers across the EXE/DLL module boundary depending on the type of DLL. This needs to be managed correctly. The CHandleMap is related to the module state. Your CView is in the EXE's map but in the DLL function, you've changed the module state, so when the callback is called, the code on the EXE side isn't finding the CView object in the DLL's map. That's why the type of DLL is important. With a properly initialized extension DLL, you don't need to use the AFX_MANAGE_STATE macro. Using an MFC extension DLL is definitely the best/easiest for passing CWnds back and forth across the EXE/DLL boundary. The drawback to an extension DLL is it can't be used by a non-MFC EXE. If you must use a standard DLL, then you'll need to manage the module state for your callback. Mark

                    Mark Salsbery Microsoft MVP - Visual C++ :java:

                    T Offline
                    T Offline
                    Tony Teveris
                    wrote on last edited by
                    #10

                    It is NOT an extension DLL, just a normal DLL. I see your point and will look into extension DLL or mangage the state in the callback. I think were done here - many thanks

                    Tony Teveris Gerber Scientific Products Senior Software Engineer Phone: 860 648 8151 Fax: 860 648 8214 83 Gerber Road West South Windsor, CT 06074

                    M 1 Reply Last reply
                    0
                    • T Tony Teveris

                      It is NOT an extension DLL, just a normal DLL. I see your point and will look into extension DLL or mangage the state in the callback. I think were done here - many thanks

                      Tony Teveris Gerber Scientific Products Senior Software Engineer Phone: 860 648 8151 Fax: 860 648 8214 83 Gerber Road West South Windsor, CT 06074

                      M Offline
                      M Offline
                      Mark Salsbery
                      wrote on last edited by
                      #11

                      Tony Teveris wrote:

                      It is NOT an extension DLL, just a normal DLL

                      Cool. Try adding this to the top of the callback... AFX_MANAGE_STATE(AfxGetAppModuleState()); Mark

                      Mark Salsbery Microsoft MVP - Visual C++ :java:

                      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