Search icon Steuerung im Bearbeitungs von Eingabebereich überlappt

8

Ich versuche, ein Steuerelement für die Suche in MFC zu erstellen, das ständig ein Symbol im Steuerungsfenster anzeigt (unabhängig vom Status und dem Text des Steuerelements). Ich habe so etwas vor vielen Jahren geschrieben und funktionierte sehr gut, aber der Code funktioniert nicht mehr auf Windows 7 und neuer (vielleicht sogar Vista, aber habe das nicht versucht). Was passiert ist, ist, dass das Bild im Steuerelement mit dem Eingabebereich überlappt (siehe Bild unten).

Die Idee hinter dem Code:

  • hat eine Klasse, die von CEdit abgeleitet ist (die das Malen in OnPaint übernimmt)
  • Das Symbol wird auf der rechten Seite angezeigt und der Bearbeitungsbereich wird basierend auf der Größe des Symbols
  • verkleinert
  • Die Größenanpassung wird bei ein- und mehrzeiligen Bearbeitungen unterschiedlich durchgeführt. Für eine einzelne Zeile rufe ich SetMargins auf und für mehrzeilige Bearbeitungen rufe ich SetRect .
  • Diese Größenanpassung wird in PreSubclassWindow() , OnSize() und OnSetFont() angewendet.

So wird die Eingabegröße für die Bearbeitung angewendet:

%Vor%

Das folgende Bild zeigt das Problem mit den Einzelzeilen-Bearbeitungen (die Bilder wurden für eine bessere Ansicht herangezoomt). Der gelbe Hintergrund dient nur zur Hervorhebung, in echtem Code verwende ich die Systemfarbe COLOR_WINDOW . Sie können sehen, dass, wenn die Einzelzeilenbearbeitung Text hat und die Eingabe hat, das linke Bild übermalt wird. Dies passiert nicht bei der mehrzeiligen Bearbeitung, bei der SetRect das Formatierungsrechteck korrekt festlegt.

Ich habe versucht, ExcludeClipRect zu verwenden, um den Bereich des Bearbeitungsbereichs zu entfernen Das Bild wird angezeigt.

%Vor%

Dies scheint keine Auswirkung auf das Ergebnis zu haben.

Als Referenz ist dies die Malmethode, die vor Jahren geschrieben wurde und früher unter Windows XP gut funktionierte, aber nicht mehr korrigiert wurde.

%Vor%

Ich habe mir andere Implementierungen ähnlicher Edit-Steuerelemente angeschaut und sie haben jetzt alle den gleichen Fehler.

Offensichtlich ist die Frage, wie kann ich den Bildbereich aus dem Eingabebereich des Steuerelements ausschließen?

    
Marius Bancila 11.08.2016, 08:39
quelle

1 Antwort

0

Ich denke was passiert, ist das CPaintDC ruft BeginPaint() auf, was ein WM_ERASEBKGND an das Bearbeitungsfeld sendet. Ich konnte es nicht ignorieren, also schätze ich, dass es an ein internes STATIC Fenster gesendet wird? Nicht sicher.

Der Aufruf von ExcludeClipRect() in Ihrem OnPaint() -Handler führt nichts aus, weil EDIT den Clipping-Bereich entweder in BeginPaint() oder in seinem eigenen WM_PAINT -Handler auf den gesamten Client-Bereich zurücksetzt.

Allerdings sendet EDIT einen WM_CTRCOLOREDIT direkt vor dem eigentlichen Bemalung an seinen Eltern, aber scheinbar nach dem Festlegen der Ausschneide-Region. So können Sie ExcludeClipRect() dort aufrufen. Klingt wie ein Implementierungsdetail, das sich mit zukünftigen Versionen der allgemeinen Steuerelemente ändern kann. In der Tat scheint es so zu sein.

Ich habe einen schnellen Test ohne MFC unter Windows 7 gemacht, hier ist meine Fensterprozedur:

%Vor%

Ich habe dann das EDIT Fenster subclassiert, um mein eigenes Icon in WM_PAINT zu zeichnen, und dann die Nachricht weitergeleitet, so dass ich nicht alles selbst zeichnen musste.

%Vor%

Beachten Sie, dass ich BeginPaint() und EndPaint() (das Äquivalent zum Erstellen eines CPaintDC ) in WM_PAINT nicht aufrufen konnte, da der Rahmen nicht gezeichnet wurde. Ich vermute, es hat etwas damit zu tun, BeginPaint() zweimal aufzurufen (einmal manuell, einmal per EDIT ) und die Behandlung von WM_ERASEBKGND . YMMV, insbesondere mit MFC.

Schließlich setze ich die Ränder direkt nach dem Erstellen der EDIT :

%Vor%

Sie müssen die Ränder möglicherweise erneut aktualisieren, wenn sich die Systemschriftart ändert.

    
isanae 29.08.2016 18:45
quelle