Bug? hdc = StartDrawing()

Fragen und Bugreports zur PureBasic 4.0-Beta.
Benutzeravatar
mk-soft
Beiträge: 3853
Registriert: 24.11.2004 13:12
Wohnort: Germany

Bug? hdc = StartDrawing()

Beitrag 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:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Wo wird denn da ein falsches Context zurueck gegeben ?
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Beitrag von a14xerus »

welches handle ist es denn, was von windowoutput() zurückgegeben wird?
Benutzeravatar
mk-soft
Beiträge: 3853
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag 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?
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

Lass dir doch nicht alles aus der Nase ziehen.
Was ist daran falsch, ich seh da keinen Fehler mit StartDrawing ?
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Beitrag 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
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
mk-soft
Beiträge: 3853
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag 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.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag 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]
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag 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.
Windows 10 Pro, 64-Bit / Outtakes | Derek
Gesperrt