Dialog in DLL packen
-
Hallo,
wie kann ich Dialog und Views in eine DLL packen und anschließend laden?Danke!! CU
PS: Hab in der Such Funktion schon einige Threads zu diesem Thema gefunden, aber konnte auf der HP von Unix-Tom nichts finden
-
hi,
die frage ist ob das einen sinn hat, ist/wird dein projekt so groß, das du seperat (für jedes modul) einee dll braucht.
es ist zumindestens möglich dialoge in dll zu verlagern aber ich habe dort einige sachen ändern müssen und man muß wissen was man tut.
z.b. umleiten der message auf die jeweilige dll
//private: BOOL CMplApp::LoopPreTranslateMessage(MSG* pMsg) { BOOL bRet=CWinApp::PreTranslateMessage(pMsg); if (!bRet) { CMapApp::CPair* pReg=m_tMap.PGetFirstAssoc(); while (pReg) { if(::IsBadCodePtr((FARPROC)pReg->value)) { // remove TRACE("CMplApp::LoopPreTranslateMessage IsBadCodePtr:%x\n", pReg->value); HANDLE nKey=(HANDLE)pReg->key; pReg=m_tMap.PGetNextAssoc(pReg); m_tMap.RemoveKey(nKey); } else { if (bRet=pReg->value(pMsg)) break; pReg=m_tMap.PGetNextAssoc(pReg); } } } return bRet; }
registrieren der dll
BOOL CMplKernelDApp::InitInstance() { CWinApp::InitInstance(); TRACE("CMplKernelD.dll wird initialisiert handle:%x!\n", m_hInstance); // add reg PostThreadMessage(WM_THREAD_APP, (WPARAM)m_hInstance, (LPARAM)&CMplKernelDApp::_PreTranslateMessage); return TRUE; } int CMplKernelDApp::ExitInstance() { TRACE("CMplKernelD.dll wird abgebrochen handle:%x!\n", m_hInstance); PostThreadMessage(WM_THREAD_APP, (WPARAM)m_hInstance, 0); return CWinApp::ExitInstance(); }
registerung entgegennehmen in der exe
// CRegTMD #define WM_THREAD_APP (WM_USER+0x101) BEGIN_MESSAGE_MAP(CMplApp, CWinApp) ON_THREAD_MESSAGE(WM_THREAD_APP, OnRegMap) END_MESSAGE_MAP() void CMplApp::OnRegMap(WPARAM wParam, LPARAM lParam) { if (lParam) { VERIFY(m_tMap[(HANDLE)wParam]=(pPreTranslateMessage)lParam); } else { m_tMap.RemoveKey((HANDLE)wParam); } }
und einhängen der message
BOOL CMplKernelDApp::_PreTranslateMessage(MSG* pMsg) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); return AfxGetApp()->PreTranslateMessage(pMsg); }
das war's soweit.
volker
hab ich noch vergessen:
class CMplApp : public CWinApp { typedef CMap<HANDLE, HANDLE, pPreTranslateMessage, pPreTranslateMessage>CMapApp; public: virtual BOOL PreTranslateMessage(MSG* pMsg); virtual BOOL InitInstance(); DECLARE_MESSAGE_MAP() private: void OnRegMap(WPARAM wParam, LPARAM lParam); private: CMapApp m_tMap; ... };
und natürlich
typedef BOOL (*pPreTranslateMessage)(MSG* pMsg);
[ Dieser Beitrag wurde am 21.03.2003 um 13:22 Uhr von vdittrich editiert. ]
-
@vdittrich
Ich verstehe Deine Ausführungen irgendwie nicht.
CWinApp ist der Hauptempfänger für Messages, die an den Thread bzw. Prozess gesendet werden.
Jede DLL, die an den Prozess gekapselt wird, nutzt die Messageloop dieses Prozesses. Warum sollten diese Messages an andere DLLs geleitet werden, ausser vielleicht für Debugging-Zwecke?
-
if (hwndDlgModeless == (HWND) NULL || !IsDialogMessage(hwndDlgModeless, &msg) && !TranslateAccelerator(hwndMain, haccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); }
es werden keine nachrichten von der main in einer exe auf die dll wetergeleitet.
jede dll hat ihre eigen nachrichtenschleife (thread)
-
jede dll hat ihre eigen nachrichtenschleife (thread)
Aber eine DLL ist doch gar kein Thread, dass hat nur M$ so gemacht, weil CWinApp das einzige Objekt mit den Prozess- und Resourcenhandles ... sein sollte.
Deshalb muss man ja auch innerhalb von MFC-Extension-DLLs in jeder Funktion, die diese Handles direkt von der DLL benötigt, AFX_MANAGE_STATE aufrufen!
-
if (hwndDlgModeless == (HWND) NULL || !IsDialogMessage(hwndDlgModeless, &msg) && !TranslateAccelerator(hwndMain, haccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); }
woher soll die main wissen das hwndDlgModeless ein dialogfeld in einer dll ist, und ein dialogfeld hat "ihre eigene nachrichtenverarbeitung" ?
siehe :
!IsDialogMessage(hwndDlgModeless, &msg) && !TranslateAccelerator(hwndMain, haccel, &msg))
-
woher soll die main wissen das hwndDlgModeless ein dialogfeld in einer dll ist
die main interessiert sich nicht dafür, ob das Dialogfeld nun in einer DLL liegt oder nicht. Einzig und allein der Thread, innerhalb dem das Fenster mit CreateWindow(Ex) erstellt wird, verwaltet die Messages bzw. stellt eine Messageloop zur Verfügung, die die Messages an alle zum Thread gehörigen Fenster aufteilt und so auch die Tastendrücke übersetzt.
-
Deshalb muss man ja auch innerhalb von MFC-Extension-DLLs in jeder Funktion, die diese Handles direkt von der DLL benötigt, AFX_MANAGE_STATE aufrufen!
ja, ja, was gibt denn dann AfxGetApp() in deiner function zurück ??
class CMplKernelDApp : public CWinApp // ist meine dll { public: CMplKernelDApp(); void AddReg(rRegWnd& tRegWnd); ... }; void CRegWndD::AddReg(rRegWnd& tRegWnd) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); ((CMplKernelDApp*) AfxGetApp())->AddReg(tRegWnd); }
-
die main interessiert sich nicht dafür, ob das Dialogfeld nun in einer DLL liegt oder nicht.
die nachrichtenschleife (ich bezeichnete sie als main) weil im allgemeinen eine anwendung ein hauptfenster hat, interessiert es schon ob ein dialogfeld aufgerufen wird.
if (hwndDlgModeless == (HWND) NULL || !IsDialogMessage(hwndDlgModeless, &msg) &&
wird überprüft !!! hab auch lange gesucht und habe dann den code entworfen.
ich benutzte in dll dialogfelder um meine anwendung in mehrere module zu zerlegen.fakt ist das PreTranslateMessage von dialogfeldern nicht korrekt bearbeitet werden.
tab, mouseover, mouseleave werden nicht bearbeitet.
wirde auch in der hilfe beschrieben.
-
fakt ist das PreTranslateMessage von dialogfeldern nicht korrekt bearbeitet werden.
tab, mouseover, mouseleave werden nicht bearbeitet.
dann hast du was anderes falsch gemacht
-
@vdittrich
Habe folgende Fehler in Deinem Code gefunden:registrieren der dll BOOL CMplKernelDApp::InitInstance() { CWinApp::InitInstance(); TRACE("CMplKernelD.dll wird initialisiert handle:%x!\n", m_hInstance); // add reg PostThreadMessage(WM_THREAD_APP, (WPARAM)m_hInstance, (LPARAM)&CMplKernelDApp::_PreTranslateMessage); return TRUE; } int CMplKernelDApp::ExitInstance() { TRACE("CMplKernelD.dll wird abgebrochen handle:%x!\n", m_hInstance); PostThreadMessage(WM_THREAD_APP, (WPARAM)m_hInstance, 0); return CWinApp::ExitInstance(); }
1. PostThreadMessage verlangt keine Message und keine hInstance als 1. und 2. Parameter
2. Selbst wenn es so wäre, so ist m_hInstance im Aufruf der DLL nämlich die Instanz der DLL, welche aber zum Hauptprozess gehört, also wird die Message an den Hauptprozess gesendet
3. InitInstance der DLL wird NUR beim Laden der DLL aufgerufen. D.h. solltest Du eine weitere Instanz Deiner Anwendung starten wollen, welche logischerweise die gleiche DLL benutzt, funzt InitInstance gar nicht mehr.
-
meine anwendung funktioniert, ich habe mir z.b postmessage (übergabe von parametern ) gedanken gemacht. (siehe codeauszug)
void CMplApp::OnRegMap(WPARAM wParam, LPARAM lParam) { if (lParam) { VERIFY(m_tMap[(HANDLE)wParam]=(pPreTranslateMessage)lParam); ...
wenn ihr es anzweifelt, sucht in der msdn nach dialogfelder und message und ihr werdet zu einer schlüssigen meinung kommen.
es wurde nicht umsonst so viel das problem beschrieben.schönes wochenende !!!
[ Dieser Beitrag wurde am 21.03.2003 um 16:30 Uhr von vdittrich editiert. ]
-
Original erstellt von <->:
**Hallo,
wie kann ich Dialog und Views in eine DLL packen und anschließend laden?Danke!! CU
PS: Hab in der Such Funktion schon einige Threads zu diesem Thema gefunden, aber konnte auf der HP von Unix-Tom nichts finden**
-
@vdittrich
Bitte gib mir mal nen Link für die MSDN, find im Moment nix!
-
ok,
das ist die version einer MFC-Erweiterungs-DLL.
ich nutze reguläre DLLs, gibt es da ein vom microsoft vorgesehenen script?
volker
-
ich nutze reguläre DLLs
Hm, Du willst also, dass eine Anwendung, die auf MFC basiert, über Nicht-MFC-Schnittstellen auf eine DLL zugreift, welche nur richtig arbeitet, wenn Ihr bekannt ist, ob die Anwendung für MFC erstellt wurde?
->
Wenn ich jemandem etwas über C++ erzähle, der keine Ahnung vom Programmieren hat, und möchte, dass dieser es einem anderen weitererzählt, bin ich mir sicher, dass es nicht so ankommt, wie ich es erzählt habe.
-
ja,
ist vb oder vba mfc-dll kompatibel ?
volker