Seite 1 von 2

Bug? hdc = StartDrawing()

Verfasst: 03.03.2007 15:29
von mk-soft
StartDrawing() soll nach der Beschreibung das HDC zurückgeben.
Liefert aber das falsche Handle.

Code: Alles auswählen



;- Konstanten
Enumeration ; Window ID
  #Window
EndEnumeration

Enumeration ; Menu ID
  #Menu
EndEnumeration

Enumeration ; MenuItem ID
  #Menu_Exit
EndEnumeration

Enumeration ; Statusbar ID
  #Statusbar
EndEnumeration

Enumeration ; Gadget ID
  
EndEnumeration

; ***************************************************************************************

;- Globale Variablen
Global exit = 0

;- Fenster
style = #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 600, 400, "Fenster", style)
  ; Menu
  If CreateMenu(#Menu, WindowID(#Window))
    MenuTitle("&Datei")
      MenuItem(#Menu_Exit, "Be&enden")
  EndIf
  ; Statusbar
  CreateStatusBar(#Statusbar, WindowID(#Window))
  ; Gadgets
  If CreateGadgetList(WindowID(#Window))
  
  EndIf
  
  ; Test
  
  rect.rect
  With rect
    \left = 20
    \top = 60
    \right = \left + 200
    \bottom = 200
  EndWith
  
  text.s = "Hallo Welt 1" + #CRLF$ + "----------"
  hdc = StartDrawing(WindowOutput(#Window))
  DrawText_(hdc,text, Len(text), rect, #DT_CENTER)

  rect.rect
  With rect
    \left = 300
    \top = 60
    \right = \left + 200
    \bottom = 200
  EndWith
  text.s = "Hallo Welt 2" + #CRLF$ + "----------"
  hdc = GetDC_(WindowID(#Window))
  DrawText_(hdc,text, Len(text), rect, #DT_CENTER)

  
  
  
  ;-- Hauptschleife
  Repeat
    event   = WaitWindowEvent()
    window  = EventWindow()
    menu    = EventMenu()
    type    = EventType()
    Select event
      Case #PB_Event_Menu                       ; ein Menü wurde ausgewählt
        Select menu
          Case #Menu_Exit
            Exit = 1
        EndSelect
      Case #PB_Event_Gadget                     ; ein Gadget wurde gedrückt
      Case #PB_Event_CloseWindow                ; das Schließgadget vom Fenster wurde gedrückt
        Exit = 1
      Case #PB_Event_Repaint                    ; der Fensterinhalt wurde zerstört und muss neu gezeichnet werden (nützlich für 2D Grafik-Operationen) 
      Case #PB_Event_SizeWindow                 ; das Fenster wurde in der Größe verändert
      Case #PB_Event_MoveWindow                 ; das Fenster wurde verschoben
      Case #PB_Event_ActivateWindow             ; das Fenster wurde aktiviert (hat den Fokus erhalten)
      Case #PB_Event_SysTray                    ; das SysTray wurde aktiviert
    
    EndSelect
    
  Until Exit
EndIf

FF :cry:

Verfasst: 03.03.2007 16:10
von edel
Wo wird denn da ein falsches Context zurueck gegeben ?

Verfasst: 03.03.2007 16:23
von Kaeru Gaman
ich hab den code mal ergänzt um die ausgabe des contextes...

Code: Alles auswählen

  ; Test 
  
  rect.rect 
  With rect 
    \left = 20 
    \top = 60 
    \right = \left + 200 
    \bottom = 200 
  EndWith 
  
  text.s = "Hallo Welt 1" + #CRLF$ + "----------" 
  hdc = StartDrawing(WindowOutput(#Window))
  DrawText(10,120,Str(hdc))
  DrawText_(hdc,text, Len(text), rect, #DT_CENTER) 

  rect.rect 
  With rect 
    \left = 300 
    \top = 60 
    \right = \left + 200 
    \bottom = 200 
  EndWith 
  text.s = "Hallo Welt 2" + #CRLF$ + "----------" 
  hdc = GetDC_(WindowID(#Window)) 
  DrawText_(hdc,text, Len(text), rect, #DT_CENTER) 

  DrawText(310,120,Str(hdc))
  StopDrawing() 
  
  ;-- Hauptschleife 
die beiden werte sind unterschiedlich, allerdings frage ich mich,
ob in beiden fällen wirklich dasselbe gemeint ist...

Verfasst: 03.03.2007 17:06
von a14xerus
welches handle ist es denn, was von windowoutput() zurückgegeben wird?

Verfasst: 03.03.2007 17:08
von mk-soft
Nach PB Hilfe von StartDrawing
Der 'Ergebnis'-Wert ist das DC- (Device Context) Handle, welches ggf. von einigen WindowsAPI-Funktionen benötigt wird.
FF?

Verfasst: 03.03.2007 17:15
von edel
Lass dir doch nicht alles aus der Nase ziehen.
Was ist daran falsch, ich seh da keinen Fehler mit StartDrawing ?

Verfasst: 03.03.2007 17:16
von PMV
Hm, vielleicht wird intern nicht direkt auf dem DC des Fensters gemalt,
sondern erstellt ein neues DC ... was ich für sehr wahrscheinlich halte, da
sonnst StopDrawing() nicht benötigt werden würde :D ... ich denke mal,
hier wird das ganze zeug dann wieder frei gegeben, nach dem es auf
dem Fenster dargestellt wurde.

MFG PMV

Verfasst: 03.03.2007 17:25
von mk-soft
Dann bringt mir das zurück gegebene Device Context von StartDrawing(...) gar nichts wenn nicht die API 2D Funktionen mit der DC funktionieren.

Verfasst: 03.03.2007 17:31
von Fluid Byte
mk-soft hat geschrieben:Dann bringt mir das zurück gegebene Device Context von StartDrawing(...) gar nichts wenn nicht die API 2D Funktionen mit der DC funktionieren.
Schwachsinn. Bis auf DrawText_() kenne ich keine API Funktionen die nicht mit der StartDrawing() DC umgehen können. Das DrawText_() nicht geht liegt glaube ich am clipping.

[EDIT]
Grad' noch mal probiert. man braucht MoveToEx_() um das clipping zu korrigieren.

Code: Alles auswählen

OpenWindow(0,0,0,600,400,"untitled",#WS_OVERLAPPEDWINDOW | 1)

hdc = StartDrawing(WindowOutput(0))
SetRect_(drc.RECT,10,10,100,100)
MoveToEx_(hdc,10,10,0) ; auskommentieren um Unterschied zu sehen
DrawText_(hdc,"Leck mich fett!",-1,drc,0)
StopDrawing()
 
While WaitWindowEvent() ! 16 : Wend
[/EDIT]

Verfasst: 07.03.2007 14:37
von Fluid Byte
Ich denke hier sollten einige Dinge mal klargestellt werden:
mk-soft hat geschrieben:StartDrawing() soll nach der Beschreibung das HDC zurückgeben. Liefert aber das falsche Handle.
&
Kaeru Gaman hat geschrieben:die beiden werte sind unterschiedlich, allerdings frage ich mich, ob in beiden fällen wirklich dasselbe gemeint ist...
Die zurückgegebenen DC's von StartDrawing(), GetDC_(), GetWindowDC_() oder auch CreateDC_() lassen sich allesamt nicht miteinander vergleichen. Nicht einmal identische Aufrufe von GetDC_() sind miteinander zu vergleichen da jeder erneute Aufruf eine neue Speicheraddresse generiert. Also anders als bei PB's nativen StartDrawing() dessen zurückgegebener Wert mit entsprechenden Folgeaufrufen identisch ist. Was logisch erscheint da die DC für ein Fenster nur einmal ermittelt werden muss.
PMV hat geschrieben:Hm, vielleicht wird intern nicht direkt auf dem DC des Fensters gemalt, sondern erstellt ein neues DC ... was ich für sehr wahrscheinlich halte, da sonnst StopDrawing() nicht benötigt werden würde
Jede DC muss wieder freigegeben werden unabhängig davon ob sie ermittelt oder neu erstellt wurde. CreateDC_() braucht DeleteDC_() genau wie GetDC_() auch ReleaseDC_() benötigt.

So, nun kommen wir zum interesanten Teil:

Wie bereits festgestellt wird Text der mit dem API Befehl DrawText_() auf einer mittels StartDrawing() erstellten DC ausgegeben wird nicht korrekt dargestellt. Daraufhin habe Ich noch einige andere API Textbefehle, wie z.B TextOut_(), ausprobiert mit dem selben Ergebniss. Obwohl Ich im vorherigen Post gezeigt hab wie man die Position und das Clipping mittels MoveToEx_() korrigieren kann wird Text mit DrawText_() und beispielsweise dem #DT_VCENTER flag immer noch nicht richtig dargestellt. Allerdings kenne Ich nun die genaue Ursache des Problems:
PB Hilfe hat geschrieben:DrawText

The new x position of the text cursor (ie: just after the last printed character) is returned in 'Result' to allow easy text concatenation, if requiered.
Es gibt da einen netten Befehl der nennt sich SetTextAlign_() welcher folgenden Modus besitzt:
Platform SDK hat geschrieben:SetTextAlign(hdc,fMode)

Mode: TA_UPDATECP
The current position is updated after each text output call. The current position is used as the reference point.
Tatsächlich ist dieser Modus für alle mit PB erstellten DC's der Standard und erklärt somit das in der Hilfe erwähnte Verhalten von DrawText().

Die Lösung ist daher recht simpel denn man muss lediglich den Modus mit SetTextAlign_() auf Null setzen. Dieser Wert entspricht #TA_NOUPDATECP, #TA_TOP und #TA_LEFT. Damit sollten alle Darstellungsprobleme mit API Textbefehlen und PB's erstellten DC's behoben sein.