Cursor verlässt CEdit



  • Guten Abend

    Ich glaub ich muss hier gleich was ausm Fenster schmeissen 😃

    Bin nun schon sicher seit 4h dran meine von CEdit abgeleitete klasse so zu modifizieren wie ich sie gerne hätte. Läuft alles ok bis auf EINE SACHE. Ich kriegs einfach nicht gebacken rauszufinden, wann das Editfeld KEINEN Hover hat und auch keinen Fokus. Sowas wie WM_MOUSELEAVE bei CButton (denn da hab ichs hingekriegt). Ich habe recherchiert, recherchiert, gesucht, noch n Bissel recherchiert, dann wieder weitergesucht bis zum Zeitpunkt wo mir einfach der Kragen platzt und ich die Frage hier stellen muss. Durch das ewige suchen und ausprobieren bin ich auch schon bis zu TrackMouseEvent() gekommen. Von Focus bis Hover geht alles, nur dieses MouseOut nicht. Folgendes habe ich bereits:

    CNumericEdit::CNumericEdit()
    {
        ...
    
    	m_bOverControl = FALSE;
    }
    
    CNumericEdit::~CNumericEdit() { }
    
    BEGIN_MESSAGE_MAP(CNumericEdit, CEdit)
    	//{{AFX_MSG_MAP(CNumericEdit)
    	ON_WM_MOUSEMOVE()
    	ON_WM_CTLCOLOR()
    	ON_CONTROL_REFLECT(EN_SETFOCUS, OnSetFocus)
    	ON_WM_CHAR()
    	ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillFocus)
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    BOOL CNumericEdit::PreTranslateMessage(MSG* pMsg) { m_ToolTip.RelayEvent(pMsg); return CEdit::PreTranslateMessage(pMsg); }
    void CNumericEdit::UpdateTipText(LPSTR newText)	  { m_ToolTip.UpdateTipText(newText, this, 1); }
    void CNumericEdit::PreSubclassWindow() 
    {
        //CREATE TOOLTIP
        CRect rect; GetClientRect(rect);
        m_ToolTip.Create(this); m_ToolTip.AddTool(this, "Numeric Input-Field", rect, 1);
    
    	m_bTracking = 0;
    
    	CEdit::PreSubclassWindow();
    }
    
    /*********************************************************************************************************************/
    /*********************************************************************************************************************/
    
    HBRUSH CNumericEdit::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
    {
    	//HIER WÜRDE ICH GERNE DIE ENTSPRECHENDEN "STYLES" VERGEBEN JE NACH
            //HOVER, FOCUS ODER WAS AUCH IMMER. 3 ZUSTÄNDE.
    
    	return hbr;
    }
    
    /*********************************************************************************************************************/
    /*********************************************************************************************************************/
    
    void CNumericEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
    {
    	//Überprüfungszeug, nichts was im Weg stehen könnte
    }
    
    /*********************************************************************************************************************/
    /*********************************************************************************************************************/
    
    void CNumericEdit::OnMouseMove(UINT nFlags, CPoint point)
    {
    	//So, hier ist der Übeltäter
    
    	if(!m_bTracking)
    	{
    		TRACKMOUSEEVENT tme;
    		tme.dwFlags		= TME_LEAVE | TME_HOVER;
    		tme.cbSize		= sizeof(tme);
    		tme.hwndTrack	= GetSafeHwnd();
    		tme.dwHoverTime = HOVER_DEFAULT;
    
    		m_bTracking		= _TrackMouseEvent(&tme);		
    	}
    
    	CDC* pDC = GetDC();
    	OnCtlColor(pDC, pDC->GetWindow(), CTLCOLOR_EDIT);
    
    	CEdit::OnMouseMove(nFlags, point);	
    }
    
    /*********************************************************************************************************************/
    /*********************************************************************************************************************/
    
    void CNumericEdit::OnSetFocus()  { m_bFocusControl = TRUE;  Invalidate(); }
    void CNumericEdit::OnKillFocus() { m_bFocusControl = FALSE; Invalidate(); }
    

    Wenn ich jetzt mit der Maus ins Editfeld "fahre", kann ich meinen Style setzen wie gewünscht. Auch wenn ich den Focus drauf hab kann ich meinen Style setzen. Jetzt würd ich aber noch gerne wenn ich wieder rausgehe, dass wieder der Standard-Style angezeigt wird. Und das krieg ich einfach nicht hin. Wie muss ich dieses TrackMouseEvent abfragen um rauszufinden ob der jetzt draussen ist und dann ne Membervariable auf TRUE zu setzen oder so? Ich hoffe mir kann jemand helfen 😞

    Grüsse und danke



  • Gibts hier denn wirklich niemanden der mir wenigstens Anhaltspunkte geben könnte wo mein Fehler liegt? 😞



  • Ich hab das Gefühl dass das gar nicht so ohne weiteres geht? Hab mir jetzt nochmal alles in Ruhe überlegt und dann ist mir eingefallen, dass der ja OnMouseMove nur dann aufruft wenn die Maus eben in diesem Editfeld ist. Ich kann also gar nicht feststellen wann der draussen ist. Dann dachte ich beim Konstruktor einen Thread zu starten der dann die ganze Zeit durchläuft und mit TrackMouseEvent checkt ob der im Editfeld ist oder nicht. Wenn nein, setzt er die globale Variable auf FALSE . Ich hab da aber ein Problem. Ich weiss nicht genau wie ich den CDC und das CWnd von meinem Editfeld kriege aus einem anderen Thread (weil ich ja die OnCtlColor aufrufen muss). Kann mir da wer helfen bitte?

    UINT CNumericEdit::CheckOverThread(LPVOID pParam)
    {
    	CNumericEdit* pDlg   = (CNumericEdit*)pParam;
    
    	while(pDlg->m_bOverControl == TRUE)
    	{
    		TRACKMOUSEEVENT tme;
    		tme.dwFlags		= TME_LEAVE;
    		tme.cbSize		= sizeof(tme);
    		tme.hwndTrack	= pDlg->m_hWnd;
    		tme.dwHoverTime = HOVER_DEFAULT;
    
    		pDlg->m_bTracking = _TrackMouseEvent(&tme);
            //IF THE CURSOR IS NOT IN THE CONTROL
    		if(pDlg->m_bTracking == TRUE) pDlg->m_bOverControl = FALSE;
    
    	----->>	CDC* pDC = GetDC();
    	----->>	OnCtlColor(pDC, pDlg->m_hWnd, CTLCOLOR_EDIT);
    	}
    
    	return 0;
    }
    


  • Ihr könnt euch sicher denken wie ich Selbstgespräche liebe 😃 😉

    Nachdem sogar der separate Thread nur dann aktiv ist wenn ich übers CEdit fahre hab ich eingesehen dass es halt nicht möglich ist ohne Hilfestellung des Hauptdialogs. Schade. Muss ich halt n paar Zeilen im Dialog schreiben 🙂

    Ah und danke für die zahlreichen Hilfestellungen 🤡 😉 😃



  • Hm, ich vermute OnKillFocus tut es nicht ?
    Evtl. in Kombination mit WM_MOUSEMOVE ?

    Devil



  • Wie gesagt. Focus ist kein Problem, mit OnSetFocus und OnKillFocus ist das einfach. Das einzige Problem ist das "drüberfahren". Nur als kurzes Beispiel:

    Beim erstellen ist das Editfeld weiss. Dann fährt man mit der Maus drüber (man klickt NICHT rein) und es wird hellgrau (sozusagen als "markierung"). Dann geht man (immernoch ohne irgendwas geklickt zu haben) vom Editfeld weg und es wird wieder weiss. Wenn man nun wieder draufgeht und reinklickt wirds noch in einem dunkleren grau. Man gibt ein was man will, klickt raus und es ist wieder weiss...

    So, das Problem besteht nun einzig und allein darin, dem Editfeld zu sagen dass jetzt niemand drin ist und dass es weiss sein soll. Und genau DAS scheint gar nicht möglich zu sein weil ALLES was in der von CEdit abgeleiteten Klasse ist nunmal erst dann aufgerufen wird wenn ich mich mit dem Cursor über dem Editfeld befinde. Ist das verständlich? Ich kann also sogar einen separaten Thread laufen lassen der überprüft wo die Maus ist, der wird erst gestartet wenn ich über das Editfeld fahre. Und ich kann dem ja auch nie sagen dass es jetzt weiss sein soll wenns nur OnMouseMove aufruft wenn ich drüberbin und somit immer hellgrau sein sollte. Ich hab gar keine Zeit ihm zu sagen wann es weiss werden soll sozusagen...

    Und so muss ich, wie schade dies auch ist, im Hauptdialog nachhelfen und dort n paar Modifizierungen vornehmen...


Anmelden zum Antworten