"Alt + X" Taste abfangen?



  • Hallo,
    @panschev, wo soll das eingefügt werden???

    @johen, danke, hat ein bißchen was gebracht, aber ich kann immer noch nicht die gewünschte funktion aufrufen, wenn ich "alt + d" drücke!
    ansonsten wirden die tasten schon abgefangen, in der CApp Klasse, also nicht in der Dlg Klasse, wie kann ich jetzt aus der Anwendungsklasse auf die Funktionen der Dialogklasse zugreifen, bzw. sie aufrufen? 😕

    BOOL CDlgApp::ProcessMessageFilter(int code, LPMSG lpMsg)
    {
    	if(m_haccel)
    	{
    		if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg)) 
    		{
    			extern OnClear(); // OnClear(); ist teil der Dialogklasse, soll die Inhalte des Dlg's löschen! 
    // wie kann ich die aufrufen??
    			return(TRUE);
    		}
    	}
    
    	return CWinApp::ProcessMessageFilter(code, lpMsg);
    }
    

    danke
    pixel



  • Hallo,
    habs so gemacht, bin mir aber nicht sicher ob dass die schönste lösung ist! 😕

    BOOL CDialogApp::ProcessMessageFilter(int code, LPMSG lpMsg)
    {
    	if(m_haccel) // m_haccel hat den  "Alt + D" Code!
    	{
    		if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg)) 
    		{
    			CDialogDlg *cDialog = (CDialogDlg*)AfxGetApp()->GetMainWnd(); // Referenz auf die Dialogklasse, die die auszuführende Funktion hat
    			cDialog->OnClear();
    
    			return(TRUE);
    		}
    	}
    
    	return CWinApp::ProcessMessageFilter(code, lpMsg);
    }
    

    Wenn jetzt der Benutzer auf "Alt + D" drückt wird die gewünschte Funktion aufgerufen!!! 😕 🤡

    Bin für verbesserungen dankbar!
    grüsse
    pixel



  • Du hast ja dann einen Accelerator in den Resourcen definiert und dort auch eine ID vergeben... und genau dies wird dann ausgelöst!

    Also Du musst nur in Deiner "WinApp.cpp" ganz oben das folgende ändern von

    BEGIN_MESSAGE_MAP(CMFCAppApp, CWinApp)
    	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
    END_MESSAGE_MAP()
    

    nach

    BEGIN_MESSAGE_MAP(CMFCAppApp, CWinApp)
    	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
    	ON_COMMAND(ID_ACCELERATOR32775, OnAcc1)
    END_MESSAGE_MAP()
    

    (wobei ID_ACCELERATOR32775 einfach Deine ID ist).

    Und dann musst Du natürlich noch eine Methode "OnAcc1" im WinApp implementieren... diese wird dann aufgerufen 😉



  • Erstmal sry hatte sowieso die Taste D mit Taste X verwechselt. Einfügen kannst du meine Variante in einer Nachrichtenbehandlungsroutine für PreTranslateMessage, also z.B so:

    BOOL CMainFrame::PreTranslateMessage(MSG* pMsg) 
    {
    	if ((GetAsyncKeyState(VK_CONTROL)) && (GetAsyncKeyState('D')))
    		MessageBox("Strg + D gedrückt");
    
    	return CFrameWnd::PreTranslateMessage(pMsg);
    }
    


  • Ups...
    @johen, so krieg ich's einfach nicht hin! wird wohl beim alten bleiben müssen!!!!
    probiert hab ich es aber trotzdem:

    BEGIN_MESSAGE_MAP(CDialogApp, CWinApp)
    	//{{AFX_MSG_MAP(CForeCheckApp)
    		// NOTE - the ClassWizard will add and remove mapping macros here.
    		//    DO NOT EDIT what you see in these blocks of generated code!
    	//}}AFX_MSG
    	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
    	ON_COMMAND(IDR_ACCELERATOR1, OnAcc)
    END_MESSAGE_MAP()
    ...
    // weiter im code...
    
    BOOL CDialogApp::InitInstance()
    {
    
    	// Standard initialization
    	// If you are not using these features and wish to reduce the size
    	//  of your final executable, you should remove from the following
    	//  the specific initialization routines you do not need.
    
    #ifdef _AFXDLL
    	Enable3dControls();			// Call this when using MFC in a shared DLL
    #else
    	Enable3dControlsStatic();	// Call this when linking to MFC statically
    #endif
    
    	m_haccel = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1));
    
    	CDialogDlg dlg;
    
    	m_pMainWnd = &dlg;
    	int nResponse = dlg.DoModal();
    	if (nResponse == IDOK)
    	{
    		// TODO: Place code here to handle when the dialog is
    		//  dismissed with OK
    	}
    	else if (nResponse == IDCANCEL)
    	{
    		// TODO: Place code here to handle when the dialog is
    		//  dismissed with Cancel
    	}
    
    	// Since the dialog has been closed, return FALSE so that we exit the
    	//  application, rather than start the application's message pump.
    	return FALSE;
    }
    ....
    // weiter im code..
    BOOL CDialogApp::ProcessMessageFilter(int code, LPMSG lpMsg)
    {
    	if(m_haccel)
    	{
    		if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg)) 
    		{
    
    			//CDialogDlg *cDialog = (CDialogDlg*)AfxGetApp()->GetMainWnd();
    			//cDialog->OnClear();
    
    			return(TRUE);
    		}
    	}
    
    	return CWinApp::ProcessMessageFilter(code, lpMsg);
    }
    
    ....
    // die Funktion die aufgerufen werden soll, hier einfach ein AfxMessageBox();
    
    BOOL CDialogApp::OnAcc()
    {
    	AfxMessageBox(L"Hallo");
    
    	return TRUE;
    }
    

    Ich komm einfach nicht auf die lösung, auser die vohin, die ich selber gemacht habe, das ON_COMMAND wird nicht aufgerufen! 😕 😞
    mfg
    pixel



  • Nicht

    ON_COMMAND(IDR_ACCELERATOR1, OnAcc)
    

    !!!!!!!

    Sondern hier musst Du die ID des speziellen Accelerators angeben!!!

    Also z.B. ID_MYACCELERATOR1
    den Du zuvor in den Ressourcen definiert hast (in einer Zeile):

    ID_MYACCELERATOR1 Ctrl A VIRTKEY

    Also:

    ON_COMMAND(ID_MYACCELERATOR1, OnAcc)
    

    Wenn Du es so lässt wie jetzt, dann gibt es nur Probleme, weil es ja bei JEDEM Acc jetzt ausgeführt wird (also falls mal Dein Menü einen Acc hat wird die Methode auch aufgerufen!)



  • Dialoge rufen standardmäßig nicht die Accelatoren auf, das mußt du ihnen schon selber beibringen:

    Jochen Kalmbach schrieb:

    Siehe auch:
    http://www.codeproject.com/dialog/pretransdialog01.asp

    (der Abschnitt "Using ProcessMessageFilter to handle dialog-based accelerator keys" dürfte für dich interessant sein)



  • CStoll schrieb:

    Dialoge rufen standardmäßig nicht die Accelatoren auf, das mußt du ihnen schon selber beibringen

    Das hat er ja jetzt genau nach Nishs Anweisung gemacht 😉 Nur in dem CP articel fehlt leider, wie man denn die Methoden für einen Accelerator definiert...



  • Hi,
    @panschev, macht nichts, es war nur ein beispiel für tasten, aber funktionieren tut es icht? 😕

    BOOL CDialogDlg::PreTranslateMessage(MSG* pMsg )
    {
    
    	if ((GetAsyncKeyState(VK_CONTROL)) && (GetAsyncKeyState('D')))
    			AfxMessageBox(L"");
    
    	if(pMsg->message==WM_KEYDOWN)
    	{
    
    		//if ((GetAsyncKeyState(VK_CONTROL)) && (GetAsyncKeyState('D')))
    		//	AfxMessageBox(L"");
    
    		if(pMsg->wParam == VK_DELETE)
    		{
    			if(IDYES == AfxMessageBox(L"Löschen Ergebnisse?!", MB_YESNO))
    				this->OnClear();
    
    		}
    	}	
    
    	return CDialog::PreTranslateMessage(pMsg);
    }
    

    @jochen,
    fehlt hier bei mir ein ::SendMessage()???

    😕 😕 😕 😕
    mfg



  • Was hat denn jetzt dieses Posting mit meinem Vorschlag zu tun? Wo sind hier die Acceleratoren?



  • Hallo Jochen,
    jetzt hab ichs richtig gemacht!!!
    Sorry, ich hab dich zu erst falsch verstanden gehabt mit dem IDR_ACCELERATOR1 den ich beim ersten versucht habe!

    Das läuft jetzt!

    BEGIN_MESSAGE_MAP(CDialogApp, CWinApp)
    	//{{AFX_MSG_MAP(CDialogApp)
    		// NOTE - the ClassWizard will add and remove mapping macros here.
    		//    DO NOT EDIT what you see in these blocks of generated code!
    	//}}AFX_MSG
    	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
    	ON_COMMAND(ID_ACC, OnAcc) // ID_ACC, ist der Wert aus dem Accelerator( den ich bis jetzt versucht habe -> IDR_ACCELERATOR1
            // ON_COMMAND(IDR_ACCELERATOR1)
    END_MESSAGE_MAP()
    

    Danke noch mal !
    pixel



  • Hi nochmal,

    Sondern hier musst Du die ID des speziellen Accelerators angeben!!!

    Also z.B. ID_MYACCELERATOR1
    den Du zuvor in den Ressourcen definiert hast (in einer Zeile):
    ID_MYACCELERATOR1 Ctrl A VIRTKEY // den hab ich genommen!!!!

    Jetzt gehts!
    mfg
    pixel



  • Super!!! Und jetzt ist es auch "richtig" gelöst...



  • ja 🤡

    *lol*



  • Hallo,

    zur Info, ich wollte eine bestimmte Tastenkombination abfangen, wie z.B. Alt + C, es klappt auch fast richtig, nur:
    Es wird manchmal ein Fehler angezeigt beim schliessen über den x-Button, im System Menu, des Dialogs? 😕

    Und das auch nicht immer, dass ist die Fehlerzeile auf die gezeigt wird:

    BOOL CDialogApp::ProcessMessageFilter(int code, LPMSG lpMsg)
    {
    	if(m_haccel)
    	{
    		if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_haccel, lpMsg)) // hier wird Fehler angezeigt, das ist die line 86 im Programm!!! 
    		{
    			return(TRUE);
    		}
    		else
    			return(FALSE);
    	}
    
    	return CWinApp::ProcessMessageFilter(code, lpMsg);
    }
    

    Die Fehlermeldung ist:

    Unhandled exception in ProgrammName.exe: 0x0000005: Access Violation
    // Der Stack zeigt auf:
    CDialogApp::ProcessMessageFilter(int 0, tagMSG * 0x0012f2fc {msg=0x00008002 wp=0x00000000 lp=0x00000000}) line 86 + 22 bytes

    Kann ich das irgendwie abfangen, wenn der benutzer auf den Schliessen 'X' Button klickt dass dann keine Prozessmessage aufgerufen wird?

    Grüsse
    pixel



  • Hallo,
    keiner eine Idee wie ich diesen 'X' abfangen kann ohne dass der Accelerator sich meldet?! 😞

    mfg
    pixel


Anmelden zum Antworten