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.