Announcement

Collapse
No announcement yet.

Warum wird falsches Canvas.Handle genommen?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Warum wird falsches Canvas.Handle genommen?

    Hallo,<br>

    in einer von TCustomPanel abgeleiteten Komponente berechne ich zuerst einen<br>
    rechteckigen Bereich des Canvas, auf dem ich malen kann (Paintarea) und kopiere<br>
    dann eine Bitmap auf diesen Bereich:<br>

    with FPaintArea do<br>
    BitBlt(Canvas.Handle,left,top,right,bottom,FBitmap .Canvas.Handle,0,0,SRCCOPY);<br>

    Das funktioniert auch sehr gut - solange BorderStryle=bsNone ist.<br>
    Bei BorderStyle=bsSingle scheint er das Canvas.handle von IRGENDEINEM Fenster zu<br>
    nehmen und da zu malen. Ich habe es sogar schon auf dem Dedsktop selber gesehen.<br>
    Nun ist BorderStyle keine notwendige Eigenschaft; ich wüßte aber trotzdem gerne,<br>
    was da passiert bzw. was man machen muss, damit er das "richtige" Canvas.handle nimmt.<br>
    Das hängt sicher damit zusammen, dass beim Setzen von BorderStyle mit CM_RECREATEWND<br>
    gearbeitet wird, aber dazu finde ich keine Beschreibung.<br>

    Helft mir bitte!<br>

    Gruß<br>
    Matthias

  • #2
    Versuch mal vor dem Zeichen FPaintArea.HandleNeeded; if FPaintArea.Showing then zeichne mit FPaintArea.Canvas;<br>

    Ich vermute das Du NICHT in der .Paint; Methode, also ausgelösst durch wm_Paint, zeichnest, sondern einfach parallel zum X'beligen Zeitpunkt zeichnest. Dies kann zu solchen Problemen führen.<br>

    Hage

    Comment


    • #3
      Hallo Hagen,<br>

      das funktioniert leider auch nicht.<br>
      Das betrifft "sowohl als auch". Selbst in der Paint-Methode, in der mit dem gleichen<br>
      Code gezeichnet wird, funktioniert es nicht. (Paint malt zweimal. Einmal falsch - in die<br>
      obere linke Ecke vom Dektop.canvas) und einmal richtig, dahin, wo es soll.<br>
      FPaintArea ist nichts weiter als ein Rechteck, das die Malfläche angibt. <br>
      (Berücksichtigung der ganzen Bevel)<br>
      Berechnet wird es woanders.<br>
      Das erste Canvas ist das Canvas der Komponente (TMyPanel=class(TCustomPanel)).<br>
      Die Bitmap wird in der Komponente definiert und bearbeitet. Sie ist auch ordentlich vorhanden.<br>
      Bei Borderstyle:=bsNone; funktioniert ja auch alles bestens.<br>

      Ich kann mir das jedenfalls nicht erklären. Das Canvas und das Handle der Komponente ist doch da!<br>
      Warum nimmt er etwas anderes? Und dann auch nur, wenn die Komponente einen Rand hat!?<br>

      Gruß<br>
      Matthia

      Comment


      • #4
        Ist der Source für's Panel sehr lang ? Falls ja soweit zusammenstuzen das Du ihn hier posten kannst und er denoch den Fehler beinhaltet.<br>
        Anders kann ich Dir nicht helfen, da das Problem wirklich seltsam ist.<br>
        Hast Du vielleicht die Methoden .CreateParams() oder .CreateWnd deines Panels überschrieben ?

        Gruß Hage

        Comment


        • #5
          Hallo Hagen,<br>

          Du hast wieder genau das richtige Gespür!<br>
          Ich habe das gestern Abend noch rausbekommen: Ich habe meine FPaintArea in einem überschriebenen<br>
          CreateWnd berechnen lassen und das will er nicht.<br>
          Eigentlich brauche ich eine aktualisierte FPaintArea für das, was ich noch in CreateWnd machen muss.<br>
          Da muss er nämlich auch malen und die Malfläche (FPaintArea) hängt natürlich auch davon ab, ob er<br>
          Scrollbars anzeigern muss oder nicht.<br>
          Und davon weiß ich nichts vor CreateWnd, oder?<br>

          Ich kapiere ja, dass das falsch sein könnte, weil er dann mehrmals mit unterschiedlichen Rechtecken<br>
          malen will (obwohl die gleich sein müssten - wenn sich nichts mit den Scrollbars tut),<br>
          aber wieso wirkt das auf die Zuweisung des CANVAS?<br>

          Na ja, es gibt eben noch viele Dinge zwischen Himmel und Erde... ;-)<br>

          Danke!<br>
          Matthia

          Comment


          • #6
            FPaintArea sollte eigentlich im .Paint selber berechnet werden, es ist dort der späteste Zeitpunkt, d.h. eventl. Änderungen des FPaintArea haben immer zur Folge das auch neu gezeichnet werden muß.<br>
            Im .CreateWnd; sollte erst NACH dem inherited CreateWnd; mit Windows.GetWindowRect(Handle, FPaintArea) gearbeitet werden. Das liegt daran das TWinControl.BoundsRect noch nicht aktuell ist. TWinControl.ClientRect kann aber auch benutzt werden da dieses intern ebefalls Windows.GetWindowRect() und Konsorten benutzt.<br>
            Allerdings sollte trotzt "ungültigem" FPaintRect NICHT in nicht zum Fenster gehörende Bereiche gezeichnet werden. Dies sollte eigentlich durch Canvas.ClipRect verhindert werden. Deshalb verstehe ich auch nicht warum trotzdem außerhalb des Fensterbereichs gezeichnet werden kann.<br>
            Falls Du das Problem nicht beseitigt bekommst dann arbeite im .Paint mit IntersectClipRect(Canvas.Handle, Self.BoundsRect....); oder mit SelectClipRgn(Canvas.Handle, CreateCorrectRegionOfControl(...));<br>
            CreateCorrectregion... ist hier nur eine Beispielfunktion.<bR>
            Eventl. kann man auch im .CreateParams() die Fensterklasse mit cs_OwnDC Classsytle versehen werden. In diesem Moment erhalten alle deine Panels einen eigenen DC=DeviceContext=Canvas.Handle und arbeiten nicht mehr auf dem Parent-Window-DC.<br>

            Gruß Hage

            Comment


            • #7
              Hallo Hagen,<br>

              natürlich mache ich alles in CreateWND erst nach dem inherited.<br>
              Und dann habe ich FPaintarea nur über Clientrect berechnet.<br>
              Aber selbst, wenn ich es mit irgendwelchen festen Werten in CreateWnd<br>
              (FPaintarea:=rect(10,10,100,100)) nimmt er dann zum Zeichnen ein anderes Handle.<br>
              Wenn ich die Berechnung von FPaintarea dagegen völlig aus CreateWnd rausnehme, funktioniert es.<br>
              Ich glaube, ich musste das wegen der Scrollbars (und meiner Faulheit) in CreateWnd machen,<br>
              da Clientrect evtl. vorhandene Scrollbars berücksichtigt; man braucht es nicht selber zu machen.<br>
              Interessant ist aber auch, warum das nur schief geht, wenn der borderstyle auf bsSingle steht.<br>
              Bei bsNone funktioniert es auch ohne Probleme...<br>
              Ich werde mal die Komponente soweit kürzen, wie es noch auftritt und dann gucken (und weiterfragen ;-)).<br>
              Deine Vorschläge probiere ich natürlich dabei auch alle aus.

              Gruß<br>
              Matthia

              Comment


              • #8
                Hm, eigentlich wäre dann FPaintArea überflüssig da du ja im .Paint; immer innerhalb von Self.ClientRect zeichnen willst. .ClientRect berücksichtigt von vornherein den NON-Clientarea, sprich Boderstyle, und die Scrollbars da diese ebenfalls im NC Bereich gezeichnet werden.

                Gruß Hage

                Comment


                • #9
                  Hallo Hagen,<br>

                  ich weiß jetzt, was falsch war. Ich hatte in einer Methode Canvas.Lock und Canvas.Unlock drin.<br>
                  Das war es!<br>
                  Ich glaube, ich wollte so erreichen, dass erst neu gezeichnet wird, wenn alles gesetzt ist.<br>
                  Muss ich aber noch mal genau gucken, was da war.<br>
                  Auf jeden Fall scheint da CreateWnd beim RecreateWnd wegen des Randes Probleme zu machen.<br>
                  Wieso er dann jedoch irgend einen anderen Canvas nimmt???<br>

                  Clientrect berücksichtigt zwar Borderstyle und Scrollbar, aber kein<br>
                  BevelInner und Bevelouter - oder habe ich das falsch interpretiert?<br>

                  Gruß<br>
                  Matthia

                  Comment


                  • #10
                    Wenn Du an irgendeiner Stelle mit Canvas.Lock/.Unlock arbeitest muß man immer an jeder Stelle mit Canvas.Lock arbeiten. Trotzdem dürfte das besagte Problem nicht auftreten, da ein gesperrter Canvas eigentlich einen "ungültigen" DC zurückgeben sollte, das wäre logisch.

                    Gruß Hage

                    Comment

                    Working...
                    X