Textfarbe einer Combobox ändern



  • also wen du das wirklich nur auf ReadOnly haben woltest dan brauchst du doch nur eine membervariable von deiner combobox und dan m_combo.EnableWindow(TRUE);
    und alles ist fertig.

    MFG TaccoGo



  • Ne eben nicht.

    Er wollte eine Art Edit.ReadOnly haben. d.h. Grauer Hintgrund und schwarze Schrift. Setzt du bei einer ComboBox Enabled auf False, dann wird der Hintergrund Grau und die Schrift Hellgrau -> Schlecht zu erkennen. Also muss man das ganze umgehen und der ComboBox sagen das es sich auf ReadOnly setzen soll.

    *winke*
    Hellsgore



  • So, ich habe das rübergebaut, aber der Cast schlägt fehl. 😞

    Zuerst hatte ich es 1:1 kopiert. Da gab es einen deftigen Absturz.
    Dann habe ich es so gemacht:

    void CAdCbx::OnEnable(BOOL bEnable) 
    { 
        CComboBox::OnEnable(bEnable); 
    
        CEdit* pEdit = dynamic_cast<CEdit*>(GetWindow(GW_CHILD)); 
    	if (pEdit)
    	{
    		pEdit->EnableWindow(TRUE); 
    		pEdit->SetReadOnly(!bEnable); 
    	}
    }
    

    Nun stürzt er nicht mehr ab (ist ja klar, das verhindert die if), aber das SetReadOnly funktioniert natürlich auch nicht. 😞

    Hast du eine Idee, warum das nicht geht?



  • Schei&%&e mit Erdbeeren,

    du verwendest ein SDI oder? Dann muss ich mal ein bisschen rumtesten *g*. Hatte einfach eine Dialog basierende Anwendung gebastelt...

    Hellsgore



  • Das ist nett von dir. 🙂

    Ja, ich habe eine SDI mit FormViews. Ich teste mal, ob der Trick auch bei Edits funktioniert (oder auch nicht), dann muss ich nicht alles umschmeißen, was ich schon habe. 🙂

    Edit: Jawoll! Bei Edits funktioniert es. 😃



  • Ja klar bei Edits funzt das auf jedenfall. Die haben ja auch eine Eigenschaft mit ReadOnly.

    So, ich bin davon ausgegangen das er beim GetWindow(GW_CHILD) hängen geblieben ist. Darum habe ich versucht die ComboBox zu finden. Es ist zwar im Prinzip Blödsinn in einer Klasse von einem Control das eigene Control zu suchen aber es sollte eigentlich funtkionieren. Das ist eine Quick&Dirty (Aber ziemlich Dirty *g*) Lösung.

    ReadOnlyComboBox.cpp

    BOOL CALLBACK CReadOnlyComboBox::EnumChildProc(HWND hwnd,LPARAM lParam)
    {
        CWnd* pcWnd = FromHandle(hwnd);
        CString strClassName;
        TCHAR cClassName[255];
        memset(cClassName, 0, sizeof(cClassName));
    
        //Klassenname holen
        GetClassName(hwnd, cClassName, sizeof(cClassName));
        strClassName = cClassName;
    
        //Wenn 1 dann setze diabled
        if(lParam == 0)
        {
            //Wenn Edit dann setze Readonly
    		pcWnd->EnableWindow(TRUE);
            if(strClassName == "Edit")
            {
                CEdit* pEdit = static_cast<CEdit*>(pcWnd);
                pEdit->SetReadOnly(TRUE);
                return FALSE;
            }
    
        }
        //Wenn was anderes als 1 dann setze enabled
        else
        {
    		pcWnd->EnableWindow(TRUE);
            if(strClassName == "Edit")
            {
                CEdit* pEdit = static_cast<CEdit*>(pcWnd);
                pEdit->SetReadOnly(FALSE);
                return FALSE;
            }
    
        }   
        return TRUE;
    }
    
    void CReadOnlyComboBox::OnEnable(BOOL bEnable) 
    {
    	CComboBox::OnEnable(bEnable);
    
    	EnumChildWindows(this->m_hWnd,EnumChildProc, bEnable);
    
    	/*CEdit*	pEdit = (CEdit*)GetWindow(GW_CHILD);
    	pEdit->EnableWindow(TRUE);
    	pEdit->SetReadOnly(!bEnable);*/
    }
    

    ReadOnly....h

    public:
       static BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam);
    

    Musst du mal Testen. Ich habe hier keinen Compiler wo ich das mal eben durchjagen kann. Vielleicht geht es so.

    Hellsgore



  • Der geht nicht in die EnumChildProc rein. 😕

    In die Zeile mit EnumChildWindows kommt er aber.

    Allerdings funktionieren meine Edits doch nicht so gut wie ich dachte, die sind jetzt immer schreibgeschützt, da muss ich nochmal forschen... 😞



  • Setze bitte bei den Edit direkt auf ReadOnly. Die haben eine Eigenschaft dafür. Hier gaukelst du der ComboBox die Eigenschaft nur vor (obwohl er sie eigentlich hat).

    Hat er denn ein Handle im m_hwnd? Aber ich glaube ich kann dir im Moment nicht mehr weiterhelfen. Ohne Compiler ist es sehr schwer 🙂 .

    Schade eigentlich, hätte ja funktionieren können. 😃 Bei Dialogbasierenden Anwendungen geht das aufjedenfall.

    Hellsgore



  • Du kannst ja, wenn du magst, weiterforschen, wenn du einen Compiler hast.

    Das eilt nicht so sehr, das Projekt dauert noch einige Zeit, es gerade in die Phase, wo fertige Teile durch ausgewählte Endnutzer getestet werden dürfen.
    Ob die nun grau auf grau oder grün auf lila lesen müssen ist fast egal - hauptsache irgendwann geht es.

    Das mit dem m_hwnd gucke ich gleich noch...

    Hmm, direkt auf ReadOnly setzen ist doof, das sind fast 500 Zeilen, die ich durchgehen muss - naja dann ist es wenigstens ordentlich.
    ...übergeredet 😉



  • So, zurück zur Combobox:

    Ich hänge auf der Zeile:

    CEdit* pEdit = dynamic_cast<CEdit*>(GetWindow(GW_CHILD));
    

    und für this steht in der Überwachung:

    0x006c7a48 {CAdCbx
    hWnd=0x0014083a
    


  • Ich komme da immer noch nicht weiter. 😞

    Hat noch jemand Ideen, Tips, Lesevorschläge?





  • Vielen Dank! 🙂
    Da sind ja Sachen bei, wow!

    Leider hilft es mir nicht weiter. 😞
    Ich habe IMMER die gleiche Schriftfarbe, wenn ich die Combobox deaktiviere - egal was für eine ich einstelle.
    Und ich finde nicht, wo das einzustellen ist. 😞

    Hast du eine Idee?



  • Hallo, estartu_de

    in Fancy control gibt es ein Beispiel, wie man Checkbox inaktiv setzen kann. Mit EnableEditing wird interne Variable auf false oder true gesetzt und click wird abgefangen. Damit wird checkbox nicht anklickbar sein. Das weiße hintergrund in radiobutton und checkbox bleibt aber. (was ich aber sehr irritierend für Anwender finde) Es hängt wahrscheinlich an Windows. Wenn du aber EnableWindow ansetzt werden interne Funktionen von Windows wider aktive und Schrift Änderung nicht möglich. Ich habe nur herausgefunden das die Hintergrundfarbe nur mit SetSystem bei Button geändert werden kann, was eigentlich die gute Nachricht sein sollte, aber die Funktion ändert nicht nur die Hintergrundfarbe von einem checkbox sondern von allen radiobutton und button dazu und nicht nur in deinem Programm, sondern in ganzem System. Also kann ich dir leider nicht weiter helfen.

    Als Quick und Dirty Lösung kann ich nur vorschlagen, checkbox so klein wie möglich machen, so dass man nur Rechteck sieht und daneben ein Static Text Feld platzieren, damit beleibt denn Text immer. Ist nicht elegant, aber funktioniert. Wenn du etwas herausfindest poste bitte, es wird auch mich interessieren.

    MfG

    Alex



  • Hallo Du!

    Du beschreibst, wie das für eine Checkbox (also ein Häkchen) geht. Okay, das hätte ich dann auch noch gebraucht. 🙂
    Aber momentan suche ich nach einer Lösung für Comboboxen, also Klapplisten. Davon habe ich nämlich deutlich mehr.

    Hast du da auch eine Idee?



  • Sorry, ich war warscheinlich zu tief in meinen Gedanken. 🙂

    Was Comboboxen angeht, fuktioniert es wunderbar mit Fancy Controls

    z.B.

    CHMXComboBox	m_Combo;
    

    und jetzt kannst du das ganze steuern

    m_Combo.SetBkClr(GetSysColor(COLOR_INACTIVEBORDER));
    	m_Combo.EnableEditing(FALSE);
    	m_Combo.SetCurSel(0);
    

    und schon hast du es.

    Du kannst deine eigene Klasse ableiten, wie es in Beispiel gemacht wurde, um nicht alles zu übernehmen.

    Wenn du zufällig mit checkboxen wissen wurdest poste im board, habe ich nämlich damit ein großeres Problem. 😞

    MfG

    Alex



  • Jaaaaaa, es funktioniert! Was lange währt wird endlich gut. 🙂
    Vielen, vielen Dank! 👍

    Nun muss ich das noch mit meiner eigenen Klasse verhäkeln und dann passt das. 😃



  • Fertig mit Häkeln! 🙂 *keksfreu*

    Man nehme:
    im Header:

    class CAdCbx : public CComboBox
    {
    // Konstruktion
    public:
    	CAdCbx();
    	BOOL EnableWindow(BOOL bEnable = TRUE);
    // Attribute
    protected:
    	bool m_bEnableEditing;
    	CBrush m_brsBkGnd;
    
    // Überschreibungen
    	// Vom Klassen-Assistenten generierte virtuelle Funktionsüberschreibungen
    	//{{AFX_VIRTUAL(CAdCbx)
    	//}}AFX_VIRTUAL
    
    // Implementierung
    public:
    	virtual ~CAdCbx();
    
    	// Generierte Nachrichtenzuordnungsfunktionen
    protected:
    	//{{AFX_MSG(CAdCbx)
    	afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
    	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
    	//}}AFX_MSG
    	virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
    	bool EnableEditing(bool bEnableEditing = true);
    };
    

    im Cpp:

    CAdCbx::CAdCbx()
    	: m_bEnableEditing(true)
    {
    }
    
    CAdCbx::~CAdCbx()
    {
    	m_brsBkGnd.DeleteObject();
    }
    
    BEGIN_MESSAGE_MAP(CAdCbx, CComboBox)
    	//{{AFX_MSG_MAP(CAdCbx)
    	ON_WM_CTLCOLOR_REFLECT()
    	ON_WM_CTLCOLOR()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    bool CAdCbx::EnableEditing(bool bEnableEditing)
    {
    	m_bEnableEditing = bEnableEditing;
    
    	if (m_bEnableEditing) 
    	{
    		m_brsBkGnd.DeleteObject();
    		m_brsBkGnd.CreateSolidBrush(GetSysColor(COLOR_WINDOW));
    	}
    	else
    	{
    		m_brsBkGnd.DeleteObject();
    		m_brsBkGnd.CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
    	}
    	Invalidate();
    
    	return true;
    }
    
    LRESULT CAdCbx::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
    {
    	// TODO: Add your specialized code here and/or call the base class
    	if( !m_bEnableEditing )
    		if( message == WM_LBUTTONDOWN || message == WM_LBUTTONDBLCLK || message == WM_KEYDOWN || message == WM_VKEYTOITEM )
    			return FALSE;
    
    	return CComboBox::WindowProc(message, wParam, lParam);
    }
    
    HBRUSH CAdCbx::CtlColor(CDC* pDC, UINT nCtlColor) 
    {
    	// TODO: Change any attributes of the DC here
    	pDC->SetTextColor(RGB(0,0,0));
    	if (m_bEnableEditing) 
    	{
    		pDC->SetBkColor(GetSysColor(COLOR_WINDOW));
    	}
    	else
    	{
    		pDC->SetBkColor(GetSysColor(COLOR_BTNFACE));
    	}
    
    	// TODO: Return a non-NULL brush if the parent's handler should not be called
    	return (HBRUSH)m_brsBkGnd;
    }
    
    HBRUSH CAdCbx::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
    {
    	// TODO: Change any attributes of the DC here
    	pDC->SetTextColor(RGB(0,0,0));
    	if (m_bEnableEditing) 
    	{
    		pDC->SetBkColor(GetSysColor(COLOR_WINDOW));
    	}
    	else
    	{
    		pDC->SetBkColor(GetSysColor(COLOR_BTNFACE));
    	}
    
    	// TODO: Return a different brush if the default is not desired
    	return (HBRUSH)m_brsBkGnd;
    }
    
    BOOL CAdCbx::EnableWindow(BOOL bEnable)
    {
    	return EnableEditing(bEnable == TRUE);
    }
    

    Nun wird bei EnableWindow einfach nur der Hintergrund geändert und bei "deaktiviert" reagiert es nicht auf klicks. 😃

    So, ich hoffe ich habe nichts vergessen. 🙂


Anmelden zum Antworten