Forum: PC-Programmierung MFC CEdit schreibschutz wird im nicht modalen Dialog nicht angezeit


von A. R. (redegle)


Lesenswert?

Hallo,

wenn man in der MFC also in Visual Studio einen modalen Dialog erstellt 
ist die Hintergrundfarbe standardmäßig grau. Ein Anzeigeelement in Form 
eines CEdits hat, wenn es beschreibbar ist einen weißen Hintergrund. 
Wird das Anzeigeelement auf schreibgeschützt gestellt wird der 
Hintergrund grau. Ich vermute, dass intern einfach der Hintergrund 
transparent gemacht wird.

Verwende ich statt einem modalen Dialog einen nicht modalen Dialog wird 
die Hintergrundfarbe standardmäßig weiß. Wird auf diesem modalen Dialog 
ein Anzeigeelement vom Typ CEdit eingesetzt ist der Hintergrund immer 
weiß egal ob schreibgeschützt oder nicht.

Wie lässt sich dieses Problem am besten lösen?
Meine Ideen wären:

- Hintergrund grau zeichnen
- CEdit überschreiben

CEdit überschreiben würde eher ungern, da ich im Moment noch nicht weiß 
ob dann der Konfigurator für einen Dialog noch komplett verwendbar ist.

Währe nett wenn ich ein paar Tips bekommen könnte.

von Karl H. (kbuchegg)


Lesenswert?

A. R. schrieb:

> Wird das Anzeigeelement auf schreibgeschützt gestellt wird der
> Hintergrund grau. Ich vermute, dass intern einfach der Hintergrund
> transparent gemacht wird.

Nope.
Ein CEdit malt schon seinen Hintergrund in der Farbe, die im Windows als 
Hintergrund für Controls eingestellt ist. Ansonsten würden ja 
dahinterliegende Elemente durchscheinen.
Probiers aus: Setz zb ein Listcontrol in den Dialog, schieb das CEdit 
teilweise darüber und hol es mit der Tab-Order in den Vordergrund. Das 
CEdit (ReadOnly) hat immer noch einen grauen Hintergrund. Auch in den 
Bereichen, in denen es mit dem ListControl überlappt.


> Verwende ich statt einem modalen Dialog einen nicht modalen Dialog wird
> die Hintergrundfarbe standardmäßig weiß.

?
Bei mir nicht.

> Wird auf diesem modalen Dialog
> ein Anzeigeelement vom Typ CEdit eingesetzt ist der Hintergrund immer
> weiß egal ob schreibgeschützt oder nicht.

Auch das seh ich bei mir nicht.

von A. R. (redegle)


Lesenswert?

Danke für die Antwort.

>Ein CEdit malt schon seinen Hintergrund in der Farbe, die im Windows als
>Hintergrund für Controls eingestellt ist. Ansonsten würden ja
>dahinterliegende Elemente durchscheinen.

Macht Sinn! Lässt sich das eigendlich umgehen also lässt sich der 
Hintergrund durchsichtig machen?

>Probiers aus: Setz zb ein Listcontrol in den Dialog, schieb das CEdit
>teilweise darüber und hol es mit der Tab-Order in den Vordergrund. Das
>CEdit (ReadOnly) hat immer noch einen grauen Hintergrund. Auch in den
>Bereichen, in denen es mit dem ListControl überlappt.

Hab das letztens schon mal in einem VIEW versucht. Bzw. ich hatte 
versucht es durchsichtig zu machen. Ich kann also bestätigen, das der 
Hintergrund zuerst gezeichnet wird. Wo kann man eigendlich die Tab-Order 
einstellen?

>> Verwende ich statt einem modalen Dialog einen nicht modalen Dialog wird
>> die Hintergrundfarbe standardmäßig weiß.

>?
>Bei mir nicht.

Bei mir auch nicht!
Dachte es wäre auch bei einem nicht modalen Dialog so. Bei meiner 
Applikation handelt es sich um ein Objekt der Klasse CPropertyPage.
Hier muss ich mich für die fälschliche Information entschuldigen.

Habe nun folgende Tests durchgeführt:

Dialog modal --> grauer Hintergrund
Dialog nicht modal --> grauer Hintergrund
CPropertyPage modal --> weißer Hintergrund
CPropertyPage nicht modal --> weißer Hintergrund

Ich weiß nicht, ob es weiterhilft aber ich habe in der CPropertyPage 
Klasse die Methode OnCtlColor eingefügt:
1
HBRUSH CGraph_Dialog_Einstellungen_S2::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
2
{
3
  HBRUSH hbr = CPropertyPage::OnCtlColor(pDC, pWnd, nCtlColor);
4
  return hbr;
5
}

Sobald ich die entsprechende Seite des Sheets aufrufe ist der 
Hintergrund zuerst grau! Dann wird die Methode OnCtlColor einmal 
aufgerufen um ein CEDit Element zu zeichnen. Beim zweiten Aufruf wird 
der Hintergrund des Sheets weiß gezeichnet.

von Karl H. (kbuchegg)


Lesenswert?

A. R. schrieb:

> Hintergrund zuerst gezeichnet wird. Wo kann man eigendlich die Tab-Order
> einstellen?

Resource Editor
(Ist ein Menüpunkt)


> Ich weiß nicht, ob es weiterhilft aber ich habe in der CPropertyPage
> Klasse die Methode OnCtlColor eingefügt:
>
>
1
> HBRUSH CGraph_Dialog_Einstellungen_S2::OnCtlColor(CDC* pDC, CWnd* pWnd,
2
> UINT nCtlColor)
3
> {
4
>   HBRUSH hbr = CPropertyPage::OnCtlColor(pDC, pWnd, nCtlColor);
5
>   return hbr;
6
> }
7
>

Ah, da sieht die Sache jetzt schon anders aus.
Jetzt fragt das CEdit bei der PropertyPage nach, welchen Brush es für 
seinen Background benutzen soll. Schon mal reingesteppt, was die 
PropertyPage dazu zu sagen hat?

http://msdn.microsoft.com/de-de/library/0wwk06hc(v=vs.80).aspx

von A. R. (redegle)


Angehängte Dateien:

Lesenswert?

Leider kommt die Antwort etwas verspätet hatte aber bis Samstag wenig 
Zeit.

Ja ich habe schon geschaut was MSDN dazu sagt.

Die Methode OnCtlColor wird von den Steuerelementen aufgerufen. Dies 
geschieht auch bei einem VIEW, bei einem Dialog und bei einer 
CPropertyPage. Das heißt, dass der Unterschied ob der Hintergrund weiß 
oder grau ist schon vorher passiert.

Ich würde ersteinmal nur versuchen den Hintergrund grau zu bekommen. Um 
das Steuerelement CEdit möchte ich mich später kümmern. Ich möchte nicht 
zu viele Themen auf einmal ansprechen.

Wenn ich in der CPropertyPage kein Steuerelement einfüge bleibt der 
Hintergrund komplett grau ("Bild 0").

Sobald ich ein Steuerelement einfüge ist zuerst "Bild 1" zu sehen. 
Anschließend stoppt der Debugger in der Methode OnCtlColor der Klasse 
CPropertyPage. UINT nCtlColor = 4. Dann ist "Bild 2" zu sehen. Bei einem 
erneuten durchlauf (UINT nCtlColor = 6) ist "Bild 3" zu erkennen.

Laut MSDN steht 4 für Dialog box und 6 für Static control.

Anschließen wurde der Gerätekontext verändert.
1
HBRUSH CReg1Seite1::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
2
{
3
  HBRUSH hbr = CPropertyPage::OnCtlColor(pDC, pWnd, nCtlColor);
4
5
  // TODO:  Ändern Sie hier alle Attribute für den DC.
6
  pDC->SetTextColor(RGB(255, 0, 0));  //Textfarbe rot
7
  pDC->SetBkMode(OPAQUE);        //Hintergrund überzeichnen
8
  pDC->SetBkColor(RGB(100,100,100));  //Hingrundfarbe grau
9
10
  // TODO:  Gib einen anderen Pinsel zurück, wenn der Standard nicht erwünscht ist.
11
  return hbr;
12
}

Das hat dann die Steuerelemente beeinflusst. Der Hintergrund bleibt weiß 
"Bild 4".

von A. R. (redegle)


Lesenswert?

Scheinbar hab ich es zum laufen bekommen. Werde mich im Laufe der Woche 
nocheinmal melden wenn ich genauer sagen kann ob alles klappt. Wenn ja 
werde ich noch den Lösungsweg posten.

von A. R. (redegle)


Lesenswert?

Den Hintergrund ändert man indem man ein CBrush Elemente aus der Methode 
zurückgibt. Hierbei ist zu beachten, dass dieses CBrush Objekt nicht in 
der Methode erstellt werden darf. Denn dann wird das OBjekt gelöscht, 
sobald die Methode beendet wird.

Ich habe im Header einen Pointer auf ein Objekt der Klasse CBrush 
erstellt:
1
     CBrush* Brush;//Pointer auf ein Objekt der Klasse CBrush

Diesem Pointer wird im Konstruktor ein Objekt zugeweisen welches im 
Destruktor wieder freigegeben wird.

Konstruktor:
1
Brush = new CBrush(RGB(248, 248, 248));

Destruktor:
1
delete Brush;

In der Methode OnCtlColor muss dann ein Handle auf dieses Objekt für 
denn Fall, dass nCtlColor = 4 ist zurückgegeben werden.
1
HBRUSH CReg1Seite1::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
2
{
3
  HBRUSH hbr = CPropertyPage::OnCtlColor(pDC, pWnd, nCtlColor);
4
5
  switch (nCtlColor) {
6
  case 4:
7
    return (HBRUSH)(Brush->GetSafeHandle());
8
    break;
9
  default:
10
    return hbr;
11
    break;
12
  }
13
}

Das CEdit übernimmt wenn es schreibgeschützt ist die Hintergrundfarbe 
des Hintergrund es ist also quasi Transparent. Wenn es nicht 
schreibgeschützt ist wird der Hintergrund weiß überschrieben.

Habe nur noch nicht so ganze verstanden was genau die Funktion 
"GetSafeHandle()" macht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.