subclassing mit new erstellten klassen



  • hallo,

    class CFWndD AFX_EXT_CLASS : public CMiniFrameWnd
    {
      ...
    }
    
    {
      CMiniFrameWnd* pWnd=new CMiniFrameWnd();
      pWnd->Create(..);
    
      ...
      GotoSpaeter(pWnd);
      ...
    
    }
    
    {
      GotoSpaeter(CWnd* pWnd)
      {
        CFWndD* pSub=new CFWndD()
        pSub->SubclassWindow(pWnd->m_hWnd); // hier fehler
    
      }
      ...
    }
    

    wer kann mir weiterhelfen, mit der mfc geht es ohne:

    BOOL CMplClientD::SubclassWindow(HWND hwnd)
    {
      ASSERT(hwnd && ::IsWindow(hwnd)); 
      m_hWnd=hwnd;
      #pragma warning(disable:4244 4312)
      m_pWndProc=(WNDPROC)::SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (INT_PTR)SubClassFunc);
      #pragma warning(default:4244 4312)
      return TRUE;
    }
    

    nicht. die eigene subclassing hat allerdings den nachteil, das die korrekte
    Klasse mit CWnd* pWnd=CWnd::FromHandle(hwnd) nicht bekomme und die message
    kann nur so behandelt werden:

    // message
    LRESULT CMplClientD::_SubClassFunc(HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam)
    {
      switch (nMessage)
      {
        case WM_DESTROY:
          //TRACE("_SubClassFunc WM_DESTROY\n");
          #pragma warning(disable:4244)
          ::SetWindowLongPtr(hWnd, GWLP_WNDPROC, (INT_PTR)m_pWndProc);
          #pragma warning(default:4244)
          break;
    
        case WM_SIZE:
          //TRACE("_SubClassFunc WM_SIZE\n");
          LRESULT nRet=::DefWindowProc(hWnd, WM_SIZE, wParam, lParam);
          SetSizeChild(LOWORD(lParam), HIWORD(lParam));
          return nRet;
    
      }
      LRESULT nRet=m_pWndProc(hWnd, nMessage, wParam, lParam);
      switch (nMessage)
      {
        case WM_DESTROY:
          m_pWndProc=0; m_hWnd=0;
          break;
    
      }
      return nRet;
    }
    

    wer kennt eine möglichkeit mfc naher zu arbeiten.

    [ Dieser Beitrag wurde am 12.03.2003 um 07:56 Uhr von vdittrich editiert. ]

    [ Dieser Beitrag wurde am 12.03.2003 um 08:09 Uhr von vdittrich editiert. ]



  • Moment ...
    Du erstellst ein CMiniFrameWnd und willst es dann mit Deiner Klasse, welche von CMiniFrameWnd abgeleitet ist, subclassen!?!?
    Warum erstellst Du nicht gleich ein CFWndD mit new und rufst dann Create dieser Klasse auf?
    Dazu kannst Du sogar den Klassenassistenten verwenden, indem Du eine Klasse CFWndD von CWnd ableitest und dann jedes CWnd durch CMiniFrameWnd ersetzt.



  • hallo,

    das war ein prinzipelles beispiel, damit du weist wie ich das meine.

    richtig ist es so.

    ich erstelle ein CMiniFrameWnd und gebe den pointer weiter.
    in einem anderen modul (dll) werden unterschiedliche gui-elemente in diesem
    CMiniFrameWnd erzeugt (auch zusammengesetzte) und angezeigt. damit ich die elemente aurichten und "malen" kann, brauche ich einige message's.

    klar ich könnte in das CMiniFrameWnd ein "Container" erstellen und von diesen weiterarbeiten z.b.:

    void CFrameD::OnSize(UINT nType, int cx, int cy)
    {
      CFrameWnd::OnSize(nType, cx, cy);
      #ifdef _DEBUG
      {
        int n=0; CWnd* pWnd=GetWindow(GW_CHILD);
        while (pWnd)
        {
          if (n>1)
          {
            TRACE("CFWndD::OnSize hwnd:%x ID:%i\n", m_hWnd, ::GetWindowLong(m_hWnd, GWL_ID)); 
            ASSERT(0);
            return;
          }
          n++;
          pWnd=pWnd->GetWindow(GW_HWNDNEXT);
        }
      }
      #endif
      if (HWND hwnd=::GetWindow(m_hWnd, GW_CHILD))
      {
        ::SetWindowPos(hwnd, 0, 0, 0, cx, cy, SWP_NOZORDER);  
      }
    }
    

    aber das will ich eigendlich nicht (zu langsam bei der aktualisierung).

    CMiniFrameWnd deswegen damit ich flexiebel bin, betreff statusleiste ...



  • Hm, ok ....

    Was ist denn das beim Subclassen der MFC für ein Fehler?

    GotoSpaeter(CWnd* pWnd)
    {
    CFWndD* pSub=new CFWndD()
    pSub->SubclassWindow(pWnd->m_hWnd); // hier fehler

    }



  • und zwar in wincore.cpp

    BOOL CWnd::SubclassWindow(HWND hWnd)
    {
      if (!Attach(hWnd))         //hier weiter
        return FALSE;
    
      // allow any other subclassing to occur
      PreSubclassWindow();
    
      // now hook into the AFX WndProc
      WNDPROC* lplpfn = GetSuperWndProcAddr();
      WNDPROC oldWndProc = (WNDPROC)::SetWindowLongPtr(hWnd, GWLP_WNDPROC,
        (INT_PTR)AfxGetAfxWndProc());
      ASSERT(oldWndProc != AfxGetAfxWndProc());
    ..
    }
    
    BOOL CWnd::Attach(HWND hWndNew)
    {
      ASSERT(m_hWnd == NULL);     // only attach once, detach on destroy
      ASSERT(FromHandlePermanent(hWndNew) == NULL);
        // must not already be in permanent map
    
    //FromHandlePermanent(hWndNew) ist !=NULL -> hier ist der fehler 
    
      if (hWndNew == NULL)
        return FALSE;
    
      CHandleMap* pMap = afxMapHWND(TRUE); // create map if not exist
      ASSERT(pMap != NULL);
    
      pMap->SetPermanent(m_hWnd = hWndNew, this);
    
    #ifndef _AFX_NO_OCC_SUPPORT
      AttachControlSite(pMap);
    #endif
    
      return TRUE;
    }
    

    fehler:
    Second Chance Assertion Failed: File c:\develop\c++\myproject\cmpldll\cmpld.cpp, Line 43
    Unbehandelte Ausnahme bei 0x77f862e8 in Mpl.exe: Benutzerhaltepunkt.

    [ Dieser Beitrag wurde am 12.03.2003 um 09:51 Uhr von vdittrich editiert. ]



  • Sieht so aus, als wäre Dein CMiniFrameWnd schonmal subclassed. Dann wird nämlich das Handle in diese PermanentMap eingetragen und somit gibts FromHandlePermanent != NULL zurück.

    P.S. Die MFC ist weit davon entfernt, perfekt zu sein.
    Ich habe gerade mächtig Probleme, fensterlose ActiveX in ein View als OleClientItems einzubinden. Das wird nämlich einfach nicht unterstützt 😞 *kotz*



  • m ..., bei einem neu erstelltes objekt ist das immer so.

    ich hab schon überlegt ob ich es mit wtl- subclassing probiere,
    habe aber damit relativ wenig erfahrung und man hat dann einen misch aus mfc und wtl.

    mal sehen was mir einfällt oder meine eigene subclassig muß ich weiter verfeinern (funktioniert ja auch, halt nur nicht so mfc mäßig).

    ps:
    fensterlose ActiveX in ein View als OleClientItems ...
    ->hab ich überhaubt keine erfahrung. ich habe in meinem projekt vermieden mit view's zu arbeiten, ich mag die klasse nicht so richtig oder ich verstehen diese view's nicht so recht.


Anmelden zum Antworten