Textfarbe einer Combobox ändern



  • Ich habe eine SDI Anwendung mit Formviews. Das werden irgendwann mal etwa 80 Stück sein, deswegen möchte ich das doch lieber zentral irgendwo machen. 🙂

    Diese Formviews haben alle eine gemeinsame Basisklasse die von CFormView abgeleitet ist. Mein Versuch, die Farben dort zu ändern ist bisher nicht erfolgreich, der Thread dazu ist etwas weiter unten zu finden.

    Also habe ich den Ansatz gestartet, die Farbe direkt in der Controlklasse zu ändern. Ich habe ja schon für fast alle Controls eine eigene. 😃
    Da stürzt er aber immer beim Aufruf der Basisklasse ab, egal ob Combobox oder Edit (mehr habe ich noch nicht getestet).
    Die Behandlung durch die Basisklasse möchte ich aber eigentlich nicht weglassen, da ich sonst deren Arbeit auch machen muss bzw. den Code davon bei mir reinkopieren - ist doch auch nicht Sinn der Sache, oder?

    So wie du das machst, direkt im Dialog / Formview, habe ich auch schon eingebaut, das funktioniert an der Stelle auch.



  • Servus,

    sage mal warum machst du das nicht ein bisschen einfacher als jede ComboBox mit einer anderen Schrift zu versehen.

    Habe hier etwas nettes:

    ReadOnlyComboBox.cpp

    // ReadOnlyComboBox.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "ReadOnlyComboBox.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    /////////////////////////////////////////////////////////////////////////////
    // CReadOnlyComboBox
    
    CReadOnlyComboBox::CReadOnlyComboBox()
    {
    }
    
    CReadOnlyComboBox::~CReadOnlyComboBox()
    {
    }
    
    BEGIN_MESSAGE_MAP(CReadOnlyComboBox, CComboBox)
    	//{{AFX_MSG_MAP(CReadOnlyComboBox)
    	ON_WM_ENABLE()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CReadOnlyComboBox message handlers
    
    void CReadOnlyComboBox::OnEnable(BOOL bEnable) 
    {
    	CComboBox::OnEnable(bEnable);
    
    	CEdit*	pEdit = (CEdit*)GetWindow(GW_CHILD);
    	pEdit->EnableWindow(TRUE);
    	pEdit->SetReadOnly(!bEnable);
    }
    

    ReadOnlyComboBox.h

    #pragma once
    // ReadOnlyComboBox.h : header file
    //
    
    /////////////////////////////////////////////////////////////////////////////
    // CReadOnlyComboBox window
    
    class CReadOnlyComboBox : public CComboBox
    {
    // Construction
    public:
    	CReadOnlyComboBox();
    
    // Implementation
    public:
    	virtual ~CReadOnlyComboBox();
    
    protected:
    	afx_msg void OnEnable(BOOL bEnable);
    	DECLARE_MESSAGE_MAP()
    };
    
    /////////////////////////////////////////////////////////////////////////////
    

    Die beiden bindest du in dein Projekt ein, gibst der ComboBox eine Control-Membervariable. In der *.h in der die Var angelegt wird machst du noch ein "#include ReadOnly...h" und setzt für deine Var die Klasse "CReadOnlyComboBox", anstatt "CComboBox". Wenn du jetzt die ComboBox auf Disable = true setzt erhälst du ein schönes ReadOnly Control. 😉

    *winke*
    Hellsgore



  • Super Idee!

    Das baue ich gleich mal in meine Klasse rüber. 🙂



  • 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. 😃


Anmelden zum Antworten