DLL TwainMessages



  • Hi,

    ich verkapsle Bildgebende Geräte in verschiedenen DLL's so auch TWAIN.

    Twain ist leider nur funktionsfähig, wenn man es mit einem Fenster
    verbindet das als MessageServer fungiert.

    Soweit alles kein Problem, also erzeugt die DLL ein kleines CWnd
    was im weiteren mit den Twain MessageServer verbunden wird.

    Nun werden Nachrichten normal über PreTranslate an den MessageServer
    weiter geleitet. Hier beginnt der Spass.

    PreTranslateMessage wird erstmal nicht in der DLL von der MainApp außerhalb
    "Getriggert" heißt da kommt auch keine Nachricht.

    "CWnd::DefWindowProc" hingegen wird angerufen, also hier die MSG-Struct manuell
    aufgefüllt, und funktioniert. Leider ist es so,das einige Aktionen in dem
    von Twain generierten UserInterface(Pop-Dialog) nicht verarbeitet werden,
    erst wenn ich mit der Maus auf mein,in InitInstanz erstellten CWnd drüber
    fahre,geht es weiter. Mit WindowsHook geht es natürlich will aber den
    Rechner nicht mit solchen Aktionen ruinieren.

    LRESULT CTwain::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    {
    	MSG msg = {};
    
    	msg.hwnd    = m_hWnd;
    	msg.lParam  = lParam;
    	msg.message = message;
    	msg.wParam  = wParam;
    
    	ProcessTwainMsg(&msg);
    
    	return CWnd::DefWindowProc(message, wParam, lParam);
    }
    

    Woran kann es eigentlich liegen,das die Nachrichten nicht auflaufen in
    DefWindowProc außer man bewegt die Maus auf dem erszeugten Hilfsfenster ?
    (wird also im TwainDialog Close gedrückt passiert solange nichts)

    Das Hilfsfenster wird beim initieren der DLL erzeugt,CTwain ist von CWnd hergeliiten:

    BOOL CVfwCapApp::InitInstance()
    {
    	CWinApp::InitInstance();
    
    	m_pMainWnd = (CWnd *) new CTwain();
    
    	LPCTSTR lpszClassName = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW,::LoadCursor(NULL, IDC_ARROW),(HBRUSH) ::GetStockObject(WHITE_BRUSH),::LoadIcon(NULL, IDI_APPLICATION));
    	if (!((CTwain *)m_pMainWnd)->CreateEx(0, lpszClassName, "TwainWnd", WS_THICKFRAME | WS_VISIBLE, 100, 100, 100, 100, 0, 0))//WS_THICKFRAME WS_DLGFRAME WS_DISABLED
    		return CVersions::DbgMsg(false, "CVwCapWrap::Create Error AfxWin\n");
    
    	return TRUE;
    }
    
    int CVfwCapApp::ExitInstance()
    {
    	if (m_pMainWnd)
    	{
    		((CTwain *)m_pMainWnd)->Delete();
    
    		delete m_pMainWnd,m_pMainWnd = 0;
    	}
    
    	return CWinApp::ExitInstance();
    }
    

    Danke für Hinweise:
    K.



  • Man kann auch das ApplicationWindow das die DLL erzeugt
    ermitteln, leider ist nicht immer der Titel eindeutig.

    Abhilfe schaft in Basic oder C# die Funktion FindWindowLike ^^

    Die kann man sich auch selber herleiten :

    struct result_stru
    {
    	char* text;
    	UINT(__stdcall*GET)(HWND, LPSTR, UINT);
    	HWND hRet;
    };
    
    BOOL WINAPI StruEnumProc(HWND hwnd, result_stru* stru)
    {
    	char loc_buf[128];
    	stru->GET(hwnd, loc_buf, 127);
    	if (strstr(loc_buf, stru->text))
    	{
    		stru->hRet = hwnd;
    		return FALSE;
    	}
    
    	return TRUE;
    }
    
    //case sensitive!
    HWND FindWindowTitleContains(char* text)
    {
    	result_stru res = { text, (UINT(__stdcall *)(HWND, LPSTR, UINT))GetWindowTextA, 0 };
    	EnumWindows((WNDENUMPROC)StruEnumProc, (LPARAM)&res);
    	return res.hRet;
    }
    
    //case sensitive!
    HWND FindWindowClassContains(char* text)
    {
    	result_stru res = { text, RealGetWindowClassA, 0 };
    	EnumWindows((WNDENUMPROC)StruEnumProc, (LPARAM)&res);
    	return res.hRet;
    }
    

    if(!(hWnd = ::FindWindowTitleContains("FensterTeilString")))
    return FALSE;

    geht auch via Classname.

    Ganz glücklich wurde ich aber nicht bei der Aktion.

    Grüße
    K.


Anmelden zum Antworten