Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Textfeld schützen!

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
22.11.2004, 13:31 Uhr
~chullain
Gast


Hallo,

wie kann ich den in meinem Programm ein Textfeld schützen, indem es schreibgeschützt ist. Wenn ich nämlich Textfeld->EnableWindow(FALSE) mache, wird das Textfeld deaktiviert und ich sehe den Text dadrin auch grau hinterlegt, so das man ihn nicht mehr lesen kann, ich möchte aber erreichen, dass der Text deutlich schwarz hervorsticht, so wie wenn ich in den Dialogeigenschaften das Feld auf schreibgeschützt stelle...
...das möchte ich aber aus dem Programm heraus, machen...

Gruss,

chullain
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
22.11.2004, 14:19 Uhr
Tommix



Hallo,
SetReadOnly dürfte sein, was Du suchst.

Gruß, Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
22.11.2004, 15:49 Uhr
~chullain
Gast


Hab jetzt mal mit SetReadOnly ausprobiert, jedoch wenn ich das so mache...


C++:
GetDlgItem(IDC_EDIT2)->SetReadOnly(FALSE);


...kriege ich die Fehlermeldung:

Code:

'SetReadOnly' : Ist kein Element von 'CWnd'


meine MemberVariablen sind nämlich nur normale CString-Elemente und keine CEdit-Textfelder...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
22.11.2004, 16:33 Uhr
FloSoft
Medialer Over-Flow
(Administrator)



C++:
((CEdit*)GetDlgItem(IDC_EDIT2))->SetReadOnly(FALSE);



oder so, evtl heißt das auch etwas anders als SetReadOnly, guck einfach mal in die msdn
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
22.11.2004, 18:32 Uhr
Spacelord
Hoffnungsloser Fall


@Flo:
Das ist genau das Problem von dem ich letztens im Offtopic Forum gesprochen habe .
Das wird wohl so funktionieren aber dieser C-Cast nach CEdit ist technisch nicht ok weil das temporäre Objekt hinter dem zurückgelieferten Zeiger wirklich vom Typ C(Temp)Wnd ist .
Die Ausnahme ist wenn das Controlobjekt von dir explizit selbst erzeugt wurde oder mit SubclassDlgItem als "Nachrichtenziel" registriert wurde.
In diesem Fall tauchen die Objekte in der permanenten Handle Map des Threads auf und es wird der korrekte Typ zurückgegeben.
Schau dir mal im Debugger an was GetDlgItem bei einem Control zurückgibt das du einfach per Resourceneditor in nen Dialog eingefügt hast,oder mach den Cast mal mit dynamic_cast.
Es ist wie gesagt sehr sehr häufig zu beobachten dass die implizite Annahme getroffen wird dass der zurückgegebene CWnd Pointer,als Basisklassenpointer nur als "Träger" dient um den Subklasseninstanzpointer zu speichern und dass die späte Bindung schon die richtige Methode aufrufen wird.
Unglücklicherweise hat die ganze Geschichte mit Polymorphie soviel zu tun wie George Bush mit dem Friedensnobelpreis.
Das es überhaupt funktioniert liegt eigentlich nur daran dass in den Tiefen der MFC eine Nachricht an die Kernel WND Struktur,die hinter m_hWnd steht geschickt wird und diese geeignet darauf reagieren kann weil es ja letztendlich(in diesem Fall) ein Edit ist.

Darüber wollte ich ja eigentlich schon längst mal nen Beitrag für die FAQ(obwohl ja eigentlich keiner danach fragt )geschrieben haben aber die Zeit fehlt einfach....

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
22.11.2004, 18:50 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja wenn du folgendes machst (IDC_EDIT istein Editfeld)


C++:
CWnd *wnd = GetDlgItem(IDC_EDIT);



und von dem CWnd das GetClassName (oder wie auch immer das nochma heißt) aufrufst, kriegste "CEdit" o.ä raus. Also sollte der C-Cast kein Problem sein. Deiner Meinung nach dürfte man dann z.b sowas acuh nicht machen:


C++:
CWnd *wnds[4];
wnds[0] = new CBlaDialog(...);
wnds[1] = new CMuhDialog(...);
wnds[2] = new CGrmlWnd(...);
wnds[3] = new CGrawaffelEDit(...);



Aber es funktioniert da das MFC die zuordnung Base-Class <-> Sub-Class ausnahmsweise vernünftig handelt.

bei meinem kleinen beispiel funktionert dann z.b auch


C++:
((CBlaDialog*)wnds[0])->MeineBlaDlgFunc(...);



Das ist ja auch einer der "Sinne" (imho) der Vererbung das man "Childs" durch die "Parent"-Class zusammenfassen kann und dann an geeigneter Stelle wieder "zurückcasten" kann. (jedenfalls bei der MFC)

Auch wenn so nur in der Laufzeit feststeht was für Klasse eigentlich hinter einem CWnd-Pointer steckt. Theoretisch könnte man (fast) alle MFC Klassen in CObject's casten und man würde keine Daten verlieren, da ja alle Daten irgendwo im Speicher liegen und die klassen-instanzen alles nur pointer aus der handle-map sind, welche dann die Zuordnung übernimmt.

Ich denke da kann man sich streiten ob der C-Cast in diesem Falle "schlecht" ist oder nicht. Ich finde jedenfalls das es an dieser Stelle nicht verkehrt ist, man sieht sofort, aha das wird nun ein CEdit, also wird IDC_WASWEISICHWAS ein Editfeld sein.
--
class God : public ChuckNorris { };

Dieser Post wurde am 22.11.2004 um 18:53 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
22.11.2004, 19:34 Uhr
Spacelord
Hoffnungsloser Fall



Zitat von FloSoft:

und von dem CWnd das GetClassName (oder wie auch immer das nochma heißt) aufrufst, kriegste "CEdit" o.ä raus. Also sollte der C-Cast kein Problem sein.


Naja,
genau das ist aber eben nicht der Fall.
Das kannst du mir ruhig glauben.
Was du da zurückgeliefert bekommst ist ein CTempWnd Objekt(oder besser ein Zeiger darauf).
Ich sag ja probier mal deinen Cast mit dynamic_cast oder setz mal ne Assert Annahme
die mit IsKindOf(RUNTIME_CLASS(CEdit)) prüft ob der Typ der Instanz vom Typ CEdit ist.


C++:
             CWnd* pwnd = GetDlgItem(IDC_EDIT1);
    ASSERT(pwnd->IsKindOf(RUNTIME_CLASS(CEdit)));




Damit fällst du böse auf die Nase!

Dein zweites Beispiel ist ok das funktioniert auch im Sinne von C++ !

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
22.11.2004, 20:14 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja z.b:


C++:
CWnd* pwnd = GetDlgItem(IDC_EDIT1);
// klar debug-assertion failed
CEdit *edit = (CEdit*)GetDlgItem(IDC_EDIT1);
// klar debug-assertion failed
CEdit *edit2 = dynamic_cast<CEdit*>(GetDlgItem(IDC_EDIT1));
// ha, edit2 == NULL ????



edit2 ist NULL, klar d.h er konnte nicht casten, tja nun wie kommst du nun an dein CEdit ran? Natürlich nur über eine Control-Member, aber wenn man das nicht will? -> C-Cast
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
22.11.2004, 20:44 Uhr
Spacelord
Hoffnungsloser Fall



Zitat von FloSoft:

edit2 ist NULL, klar d.h er konnte nicht casten, tja nun wie kommst du nun an dein CEdit ran? Natürlich nur über eine Control-Member, aber wenn man das nicht will? -> C-Cast


Wenn du damit auf spezifische Datenmember der Subklasse zugreifen willst,oder wenn virtuelle Funktionen ins Spiel kommen wird es aber sehr sehr haarig damit!!
Generell stellt sich doch die Frage warum man die Vorteile von C++ hervorhebt um dann doch Methoden zu nutzen deren einziger greifbarer Sinn darin besteht Instanzen von Controls zu vermeiden .Und um dieses dann auch noch konsequent durchzuziehen zu können mit C-Casts die Typprüfung zu unterlaufen ist ja auch nicht die feine englische Art .

Also für mich sind Controls Objekte und deshalb haben auch deren Instanzen in einem Dialog ihre Lebensberechtigung.Sauberer ist es sowieso.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
22.11.2004, 22:09 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


natürlich ist es mit controls sauberer, nur wenn du angenommen 900 controls hast, von Radio1 bis Radio900 (durchlaufende Ressourcenkennungen)

dann verzichtest denke ich selbst du auf Controlmember

denn ein


C++:
((CRadio*)GetDlgItem(IDC_RADIO1+Position))->...



ist dann eine einfachere Möglichkeit als 900 Controls anzulegen. (Evtl könnte man eine ControlRange-Definition verwenden, aber da müsste ich nachschaun, hab dazu keinen bock jetzt )

Ansonsten haste natürlich recht, Controls sind sauberer, nur manchmal will man halt drauf verzichten wenn man z.b den Zugriff nur ein einziges mal im ganzen projekt braucht, ich denke da legst selbst du nicht ein Control an...
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: