vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Blitzschnelles Erstellen von grafischen Diagrammen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

Fortgeschrittene Programmierung
Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 23.12.06 12:10

Grüß euch,

ich kämpfe mit einer selbst gebauten Zeichenfunktion:
Public Sub DrawPicture(ByVal hDC As Long, oPicture As StdPicture, ByVal X1 As _
  Integer, ByVal Y1 As Integer, Optional ByVal Width1 As Integer = -1, Optional _
  ByVal Height1 As Integer = -1, Optional ByVal X2 As Integer = -1, Optional _
  ByVal Y2 As Integer = -1, Optional ByVal Width2 As Integer = -1, Optional _
  ByVal Height2 As Integer = -1)
Dim lPicture As Long
Dim lPicOld As Long
 
lPicture = CreateCompatibleDC(hDC)
lPicOld = SelectObject(lPicture, oPicture.Handle)
 
If Width2 = -1 Then Width2 = oPicture.Width / HimetricPixel
If Height2 = -1 Then Height2 = oPicture.Height / HimetricPixel
If Width1 = -1 Then Width1 = Width2
If Height1 = -1 Then Height1 = Height2
If X2 = -1 Then X2 = 0
If Y2 = -1 Then Y2 = 0
 
Call StretchBlt(hDC, X1, Y1, Width1, Height1, lPicture, X2, Y2, Width2, _
  Height2, vbSrcCopy)
 
Call SelectObject(lPicture, lPicOld)
Call DeleteDC(lPicture)
End Sub
Diese Funktion soll die PaintPicture-Methode der einzelnen Objekte ersetzen, da ich noch div. Abfragen,.. einbauen will. Also Fakt ist, ich will statt beispielsweise picBox.PaintPicture(..) Call DrawPicture(picBox.hdc,..) verwenden. Wichtig dabei ist, dass das Zielobjekt als hDC-Parameter angegeben wird und das zu zeichnende Bild als Picture/StdPicture.

Kurios dabei ist, dass diese Funktion mancmal funktioniert und das Bild so zeichnet, wie es gezeichnet werden soll, manchmal jedoch wird die Funktion zwar ausgeführt, aber die Ausgabefläche bleibt leer, es wird also nichts gezeichnet.

Liegt hier ein Fehler in der Funktion vor (nehme ich an ;) )? Bzw. wer weiß, wie man diese Funktion dauerhaft funktionierend macht? ;)
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: TTSAddict
Datum: 23.12.06 12:28

Lass mich raten... es macht nur dann Probleme, wenn Quelle und Ziel unterschiedliche Abmessungen haben?
Wenn ja - mit dem Problem schlage ich mich auch herum.
Nicht nur StretchBlt, auch AlphaBlend aus der MSIMG32 macht die gleichen Probleme.
In deiner Funktion sehe ich jedenfalls keinen Fehler.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 23.12.06 12:30

Hi,

danke für deine Antwort!
Hm, gute Frage, daran habe ich noch nicht gedacht... Wäre aber komisch, denn mit StretchBlt selbst hatte ich noch nie Probleme. Zum Stretchen ist diese Funktion ja da *gg*
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: TTSAddict
Datum: 23.12.06 12:38

Eben das habe ich mir auch gedacht als mich mein Code im Stich gelassen hat...
Wenn Ziel und Quelle ÄHNLICHE Abmessungen haben, scheint es immer zu klappen,
ansonsten bekomme ich das von dir beschriebene Verhalten. Mehr konnte ich dazu
auch noch nicht herausfinden.

Seltsamerweise habe ich mal ein Programm gehabt, das Thumbnails von BELIEBIG großen Bildern erstellt hat, und es hat immer geklappt (mit StretchBlt wohlgemerkt).
Kann aber zu deinem bzw unserem Code keine nennenswerten Unterschiede feststellen.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 23.12.06 12:40

Hi,

hm.. wirklich kurios... Wie hast du das Problem dann gelöst? Bzw. welchen Workaround oder welchen anderen Umweg hast du gewählt?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: TTSAddict
Datum: 23.12.06 12:46

Nun....
zwei Anwendungsfälle werden bei mir durch dieses Verhalten gestört.
Ersterer sollte ein Hintergrundbild auf einer MDI Form zeichnen, abhängig von der Größe der Form. Darauf habe ich schlicht verzichtet und das Bild mit einer festen Größe versehen.

Der zweite Fall ist eine Ähnliche Funktion wie bei dir. Ich habe dort vor dem Blitten das Bild mit Hilfe einer Bibliothek (FreeImage) - die sowieso schon im Projekt eingebunden war - gestretcht, und danach auf das Ziel geblittet. Das ist zwar nicht unbedingt schnell, aber um Geschwindigkeit ging es bei dem Projekt auch nicht.
Wenn du was schnelles brauchst, ist das keine Lösung.
Mich würde auch immernoch interessieren, warum das hier so nicht funktioniert. Ich bleibe auf jeden Fall am Ball.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 23.12.06 13:02

Mhm, ok.. ja, müsste schnell sein, die Funktion ;)
Gut, ich werde einfach mal weiterforschen ;)

Danke
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Zardoz
Datum: 23.12.06 13:45

Hi Master,
die Api StretchBlt ist weniger fehlertolerant als PaintPicture. Bei fehlerhaften Angaben
kommt es zu Problemen. Alle Angaben müssen in Pixel umgerechnet werden. Apis
arbeiten nur mit Pixeln. Quellbreite und Quellhöhe dürfen nicht größer sein, als das
Quellbild, Zielbreite und Zielhöhe dürfen nicht größer sein, als das Zielbild. Alle
Koordinatenangaben (X1, Y1, ...) müssen sich innerhalb der Bitmaps befinden. Vor
StretchBlt muss mit der Api SetStretchBltMode der Modus eingestellt werden. Bei
älteren OS's darf der Faktor zwischen Quelle und Ziel nicht größer als ca. 16 (bzw.
1/16) sein. Das Ziel muss zum Zeitpunkt des Aufrufs angelegt sein, das heißt man
kann nicht in ein leeres StdPicture zeichnen.
Zur Kontrolle solltest du den Rückgabewert von StretchBlt anzeigen.
Wenn das Ziel eine nicht sichtbare Picturebox ist, muss Autoredraw auf True, wenn
es eine sichtbare Picturebox ist, nach dem Zeichnen ein Doevents oder ein
Ziel.Refresh.
Du solltest eine Variable nicht hdc nennen, das ist eine Eigenschaft.
Ändere diese Zeile:
lPicture = CreateCompatibleDC(hDC)
mal so:
lPicture = CreateCompatibleDC(Me.hDC)

Gruss,

Zardoz

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 23.12.06 19:15

Hi,

danke für deine ausführliche Antwort!

ich zerlege einmal kurz deine Argumente:

1. Alle Angaben sind in Pixel - ich arbeite nur mit dieser Einheit ;)
2. Quellgrößen/Zielgrößen - auch klar, prinzipiell verkleinere ich die Bilder nur, wenn überhaupt... Ansonsten bleibt die Größe gleich
3. Koordinatenangabe - auch klar
4. SetStretchBltMode-API - danke für den Tipp.. habe ich mal hinzugefügt (ohne Erfolg)
5. Faktor bei älteren OS: So stark wird eigentlich nicht gezoomt. Auf meinem XP sollte es aber in jedem Fall hinhauen
6. Ziel vorhanden - wie meinst du das? Ich zeiche entweder in ein UC oder auf eine PictureBox
7. AutoRedraw/Doevents - Refresh bereits vorhanden
8. Funktion befindet sich in einem Modul, dh. hdc ist einzigartig

Bis auf Punkt 4 hat sich somit nichts geändert, aber jeder Hinweis ist Gold wert ;)
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Zardoz
Datum: 29.12.06 01:57

Hallo Master,

zu 6: Bei UC und Picturebox stellt sich das Problem nicht. Das kann vorkommen,
wenn eine Variable als StdPicture definiert wurde.

zu 7: Worauf steht denn Autoredraw?

zu 8: In dem Fall sollte es gehen. Der Code ist aber lesbarer, wenn Variable
und Eigenschaft nicht den selben Namen haben.

Ich habe StretchBlt schon oft benutzt, aber bisher keine Probleme damit. Das
sollte, unter Einhaltung der Bedingungen, funktionieren. Die an die Api
übergebenen Variablen sollten vom Typ Long sein (Width1 ...). Der
Umrechnungsfaktor (HimetricPixel) sollte vom Typ Single oder Double sein.

Gruss,

Zardoz

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 29.12.06 08:06

Hi Zardoz,

Thx für deine Antwort!

6. ok - ist UC ;)
7. AutoRedraw auf True, weiters wird nach dem Zeichnen noch ein Refresh durchgeführt
8. Hm, werteich als Schönheits-OP, die zum Leben nicht erforderlich ist ;) Sollte also trotzdem funktionieren, denke ich...

Long? Hm, ok, probiere ich mal aus... HimetricPixel ist bereits auf Single...
Gut, werde weitere Tests durchführen und melde mich dann wieder
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 30.12.06 18:48

Ok.. Hmhmhm...

Ich habe soeben etwas Interessantes entdeckt. Und zwar funktioniert die Zeichenroutine sehrwohl. Allerdings - so bin ich gerade draufgekommen - habe ich iM mit icons getestet (einfacherweise "Me.Icon") und da haperts. Nehme ich ein Bitmap oder sonstwas funktioniert's, nur bei Icons hängts oft.

Die Frage, die sich mir nun stellt: wieso?
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Gateway
Datum: 31.12.06 15:47

Kannst du mal den vollständigen code, mit api`s etc. posten?

Wer Rechtschreibfehler findet kann sie behalten oder meinen Deutschlehrer verklagen.

In der Mitte von Schwierigkeiten liegen die M?glichkeiten. [Alber Einstein]

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 31.12.06 16:35

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As _
  Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal _
hObject As Long) As Long
Private Declare Function StretchBlt Lib "gdi32.dll" (ByVal hdc As Long, ByVal X _
As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal _
hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As _
Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
 
Private Const HimetricPixel As Single = 26.46
 
Public Sub DrawPicture(ByVal hDC As Long, oPicture As StdPicture, ByVal X1 As _
  Integer, ByVal Y1 As Integer, Optional ByVal Width1 As Integer = -1, Optional _
  ByVal Height1 As Integer = -1, Optional ByVal X2 As Integer = -1, Optional _
  ByVal Y2 As Integer = -1, Optional ByVal Width2 As Integer = -1, Optional _
  ByVal Height2 As Integer = -1)
Dim lPicture As Long
Dim lPicOld As Long
 
lPicture = CreateCompatibleDC(hDC)
lPicOld = SelectObject(lPicture, oPicture.Handle)
 
If Width2 = -1 Then Width2 = oPicture.Width / HimetricPixel
If Height2 = -1 Then Height2 = oPicture.Height / HimetricPixel
If Width1 = -1 Then Width1 = Width2
If Height1 = -1 Then Height1 = Height2
If X2 = -1 Then X2 = 0
If Y2 = -1 Then Y2 = 0
 
Call StretchBlt(hDC, X1, Y1, Width1, Height1, lPicture, X2, Y2, Width2, _
  Height2, vbSrcCopy)
 
Call SelectObject(lPicture, lPicOld)
Call DeleteDC(lPicture)
End Sub
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Gateway
Datum: 31.12.06 16:52

Ich habs jetzt getestet und es funktioniert, aber qualitativ ist die paintpicture function wesentlich besser. Bei deiner function zeichnen sich viele quadrate ein. und auch viele farbfehler... das muss an der StretchBlt api liegen.

Wer Rechtschreibfehler findet kann sie behalten oder meinen Deutschlehrer verklagen.

In der Mitte von Schwierigkeiten liegen die M?glichkeiten. [Alber Einstein]

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 31.12.06 17:14

Hast du mit Icons oder mit Bitmaps getestet?

Bei mir treten nur Probleme bei den Icons auf
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Gateway
Datum: 31.12.06 17:15

Probleme hab ich ja nicht, aber als ich die jpg datei geladen hab sah es im vergleich zu dem paintpicture bild nich so toll aus

Wer Rechtschreibfehler findet kann sie behalten oder meinen Deutschlehrer verklagen.

In der Mitte von Schwierigkeiten liegen die M?glichkeiten. [Alber Einstein]

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Zardoz
Datum: 31.12.06 17:22

SetStretchBltMode

Gruss,

Zardoz

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 31.12.06 18:03

Ok, mein Fehler, vor StretchBlt gehört noch die Zeile

Call SetStretchBltMode(hdc, DELETESCANS)

Ist bei mir so auch schon in Verwendung, hab nur hier im Forum die aktualisierte Version ned reingestellt..
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Gateway
Datum: 01.01.07 22:41

kannste jetzt die endgültige version durchgeben?

Wer Rechtschreibfehler findet kann sie behalten oder meinen Deutschlehrer verklagen.

In der Mitte von Schwierigkeiten liegen die M?glichkeiten. [Alber Einstein]

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Probleme mit Zeichnen von Picture 
Autor: Master
Datum: 02.01.07 18:29

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As _
  Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal _
hObject As Long) As Long
Private Declare Function StretchBlt Lib "gdi32.dll" (ByVal hdc As Long, ByVal X _
As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal _
hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As _
Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
 
Private Const HimetricPixel As Single = 26.46
 
Public Sub DrawPicture(ByVal hDC As Long, oPicture As StdPicture, ByVal X1 As _
  Integer, ByVal Y1 As Integer, Optional ByVal Width1 As Integer = -1, Optional _
  ByVal Height1 As Integer = -1, Optional ByVal X2 As Integer = -1, Optional _
  ByVal Y2 As Integer = -1, Optional ByVal Width2 As Integer = -1, Optional _
  ByVal Height2 As Integer = -1)
Dim lPicture As Long
Dim lPicOld As Long
 
lPicture = CreateCompatibleDC(hDC)
lPicOld = SelectObject(lPicture, oPicture.Handle)
 
If Width2 = -1 Then Width2 = oPicture.Width / HimetricPixel
If Height2 = -1 Then Height2 = oPicture.Height / HimetricPixel
If Width1 = -1 Then Width1 = Width2
If Height1 = -1 Then Height1 = Height2
If X2 = -1 Then X2 = 0
If Y2 = -1 Then Y2 = 0
 
Call SetStretchBltMode(hdc, DELETESCANS)
Call StretchBlt(hDC, X1, Y1, Width1, Height1, lPicture, X2, Y2, Width2, _
  Height2, vbSrcCopy)
 
Call SelectObject(lPicture, lPicOld)
Call DeleteDC(lPicture)
End Sub
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel