Seite 1 von 2

"Klick ins EditorGadget klickt nicht immer"

Verfasst: 02.09.2006 17:59
von Eckhard.S
Im foldenden Code würde ich erwarten, dass das Linksklicken mit der Maus in das obere EditorGadget immer eine Debugausgabe verursacht. Leider tut es das bei mir nicht immer und nicht ganz nachvollziehbar. Liegt dies am Splitter? Weiß jemand, wie man es beheben kann? Oder habe ich etwas anderes nicht beachtet?

Code: Alles auswählen

;PB4
;{************* Variablen Deklaration *************
     
framebreite = 250              ; Fenster
Global Schrift$ = "Courier New"
Global Schriftgroesse = 9
                                               
Global FontID1
FontID1 = LoadFont(1, Schrift$, Schriftgroesse)  ; Font für die Darstellung 
    
;} 

Enumeration 
  #window
EndEnumeration  

Enumeration
  #Splitter 
  #edit1
  #edit2
  #edit3 
EndEnumeration 

;{************* Fensteraufbau *************
  


hwnd = OpenWindow(#window,0,0,800,600,fensterueberschrift$,#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget) 
SetWindowColor(0,RGB(100, 150, 100))
CreateGadgetList(hwnd) 

EditorGadget(#edit1,0,0,0,0) 
EditorGadget(#edit2,0,0,0,0, #PB_Window_Invisible )                          
EditorGadget(#edit3,0,0,0,0, #PB_Editor_ReadOnly) 
SetGadgetFont(#edit1, FontID1)
SetGadgetFont(#edit2, FontID1)
SetGadgetFont(#edit3, FontID1)

SplitterGadget(#Splitter, framebreite, 32, WindowWidth(#Window)- framebreite - 10, WindowHeight(#Window)- 60,#edit1, #edit3) 
AddGadgetItem(#edit1,0,"Editor 1 ") 

 SendMessage_(GadgetID(#edit1),#EM_SETTARGETDEVICE, #Null, Flag)  ; automatischer Umbruch
 SendMessage_(GadgetID(#edit2),#EM_SETTARGETDEVICE, #Null, Flag) 
 SendMessage_(GadgetID(#edit3),#EM_SETTARGETDEVICE, #Null, Flag) 


;} End Fensteraufbau


  
; ************* Hauptprogramm *************
 
 Repeat 
 Select WaitWindowEvent() 

   Case #WM_KEYDOWN 
     Debug "#KEYDOWN: " + Str(EventwParam()) 
    
   Case #PB_Event_CloseWindow 
     Break
    
   Case #PB_Event_Gadget 
     Select EventGadget() 
       Case #edit1  ;  Editorfenster 1 
       Debug "Klick ins Fenster" 
            
     EndSelect
       
  EndSelect 
ForEver 

End

Verfasst: 02.09.2006 19:25
von a14xerus
Ich würde sagen es liegt dadran, das das fenster ggf schon markiert ist...
Weil bei mir liefer es jedesmal einen debug, wenn ich zb was markeire, oder erst das andere gadget auswähle

Verfasst: 02.09.2006 19:33
von PBZecke
Das Editorgadget unterstützt EventTypes nicht. Und WaitWindowEvent liefert
Dir da irgendwas zurück Doppelklick, MouseDown oder was. Deshalb so
unregelmäßig

Hab mal was geändert:

Code: Alles auswählen

;PB4
;{************* Variablen Deklaration *************
     
framebreite = 250              ; Fenster
Global Schrift$ = "Courier New"
Global Schriftgroesse = 9
                                               
Global FontID1
FontID1 = LoadFont(1, Schrift$, Schriftgroesse)  ; Font für die Darstellung
   
;}

Enumeration
  #window
EndEnumeration 

Enumeration
  #Splitter
  #edit1
  #edit2
  #edit3
EndEnumeration

;{************* Fensteraufbau *************
 


hwnd = OpenWindow(#window,0,0,800,600,fensterueberschrift$,#PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget)
SetWindowColor(0,RGB(100, 150, 100))
CreateGadgetList(hwnd)

EditorGadget(#edit1,0,0,0,0)
EditorGadget(#edit2,0,0,0,0, #PB_Window_Invisible )                         
EditorGadget(#edit3,0,0,0,0, #PB_Editor_ReadOnly)
SetGadgetFont(#edit1, FontID1)
SetGadgetFont(#edit2, FontID1)
SetGadgetFont(#edit3, FontID1)

SplitterGadget(#Splitter, framebreite, 32, WindowWidth(#Window)- framebreite - 10, WindowHeight(#Window)- 60,#edit1, #edit3)
AddGadgetItem(#edit1,0,"Editor 1 ")

 SendMessage_(GadgetID(#edit1),#EM_SETTARGETDEVICE, #Null, Flag)  ; automatischer Umbruch
 SendMessage_(GadgetID(#edit2),#EM_SETTARGETDEVICE, #Null, Flag)
 SendMessage_(GadgetID(#edit3),#EM_SETTARGETDEVICE, #Null, Flag)


;} End Fensteraufbau


 
; ************* Hauptprogramm *************
 
 Repeat
 Select WaitWindowEvent()

   Case #WM_KEYDOWN
     Debug "#KEYDOWN: " + Str(EventwParam())
   
   Case #PB_Event_CloseWindow
     Break
   
   Case #WM_LBUTTONUP
     Select EventGadget()
       Case #edit1  ;  Editorfenster 1
          Debug "Klick ins Edit Fenster"

           
     EndSelect    
     
   Case #PB_Event_Gadget

       
  EndSelect
ForEver

Verfasst: 02.09.2006 22:17
von Eckhard.S
Ja, das wäre schon mal eine bessere Möglichkeit, weil jetzt immer das Loslassen der Maus erkannt wird. Warum geht es nicht zuverlässig beim Drücken mit mit #WM_LBUTTONDOWN ???

Verfasst: 02.09.2006 22:30
von Kaeru Gaman
schätze mal, weil in jedem durchlauf der Button down ist.

du musst dirn flag machen, so in der art (pseudocode):

Code: Alles auswählen

If Event=#Buttondown 
  If ButtonFlag = #False
    Aktion()
    ButtonFlag = #True
  EndIf
Else
  ButtonFlag = #False
EndIf
beim ersten durchlauf, wo der Button down ist, setzt du ein flag und reagierst.
durch das Flag wird in weiteren durchläufen die reaktion verhindert.

du könntest das löschen des Flags auch mit ButtonUp verbinden.

(nur mal auf die schnelle, hoffe, es war nicht zu ungenau erklärt...)

Verfasst: 02.09.2006 23:06
von PBZecke
Ich vermute, dass Windows bei #WM_LBUTTONDOWN die DBLClick Time bis
zum nächsten #WM_LBUTTONDOWN abwartet, um ein Doppelclick Event
feststellen zu können. Hab jetzt auf die schnelle keine Lösung parat, wie man
das umgehen kann, werde aber mal darüber nachdenken.

Wichtiger wäre aber sowieso das ButtonUp! Da der Anwender ja erst jetzt die
Maustaste loslässt. Und damit erst eine Aktion ausgelöst werden sollte.
ButtonDown benötigt man eigentlich nur für solche Aktionen wie Ziehen mit
der Maus. (Auswahlrahmen, Zeichnen usw.)

Verfasst: 03.09.2006 09:55
von Eckhard.S
PBZecke hat geschrieben:... werde aber mal darüber nachdenken.
Das wäre prima, wenn es klappt. Beim Drücken der Maustaste soll nämlich das Wort das darunter liegt detektiert werden und nicht erst beim Loslassen.

Verfasst: 03.09.2006 12:17
von edel
Bin mir jetzt nicht mehr sicher ob du sowas gesucht hast , wenn nicht auch nicht schlimm...

Beispiel :

Code: Alles auswählen

    
  
  Macro LOWORD(Value)
    Value & $FFFF
  EndMacro
  
  Macro HIWORD(Value)
    (Value >> 16) & $FFFF
  EndMacro 
  
  #window = 0
  #editor = 0
  #text   = 1
  
  
  Procedure Callback(hwnd,msg,wParam,lParam) 
    Protected pt.POINT , hdc.l , linelength.l
    Protected line.l , index.l , lineindex.l 
    Protected pbid.l = getprop_(hwnd,"PBID") 
    Protected *char.character , Size.SIZE
    Protected old = GetGadgetData(pbid)
    Protected linetext.s
    
    If msg = #WM_MOUSEMOVE ; #WM_LBUTTONDOWN ;
      
      pt\x        = LOWORD(lParam)
      pt\y        = HIWORD(lParam)
      
      index       = SendMessage_(hwnd,#EM_CHARFROMPOS,0,@pt)  
      line        = SendMessage_(hwnd,#EM_EXLINEFROMCHAR,0,index)   
      lineindex   = SendMessage_(hwnd,#EM_LINEINDEX ,line,0)  
      linetext    = GetGadgetItemText(pbid,line,0)
      
      ;ende suchen
      *char = @linetext + (index - lineindex)
      While *char\c 
        
        If *char\c = 32 Or *char\c = 10 ; leerzeichen und linefeed
          *char\c = 0 
          Break
        EndIf
        
        *char + SizeOf(character)
      Wend
      
      ;anfang suchen 
      *char = @linetext + (index - lineindex)
      While *char\c And *char > @linetext
        If *char\c = 32 ; leerzeichen
          *char + 1 
          Break
        EndIf 
        *char - SizeOf(character)
      Wend 
      
      SendMessage_(hwnd,#EM_POSFROMCHAR ,@pt,lineindex + *char -@linetext)  
      
      ;breite und hoehe des wortes holen
      hdc = GetDC_(hwnd) 
      GetTextExtentPoint32_(hdc,*char,Len(PeekS(*char)),@Size)
      ReleaseDC_(hwnd,hdc)
      
      ;pruefen ob sich die maus ueber dem wort befindet
      If Size\cy + pt\y >= HIWORD(lParam) And pt\y <= HIWORD(lParam) And Size\cx + pt\x >= LOWORD(lParam) And pt\x <= LOWORD(lParam)    
        SetGadgetText(#text,PeekS(*char)) 
      Else
        SetGadgetText(#text,"")
      EndIf
      
    EndIf
    
    
    ProcedureReturn CallWindowProc_(old,hwnd,msg,wParam,lParam)
  EndProcedure
  
  Procedure SubclassGadget(gadget) 
    If IsGadget(gadget)
      Protected old = SetWindowLong_(GadgetID(gadget),#GWL_WNDPROC,@Callback()) 
      ProcedureReturn SetGadgetData(gadget,old) 
    EndIf 
  EndProcedure
  
  
  hwnd = OpenWindow(#window,#PB_Ignore,#PB_Ignore,400,400,"")
  
  CreateGadgetList(hwnd) 
  
  font = LoadFont(0,"Curier New",10) 
  SetGadgetFont(#PB_Default,font)
  
  EditorGadget(#editor,0,0,400,370) : SubclassGadget(#editor)
  TextGadget(#text,0,375,400,23,"",#PB_Text_Border)
  
  text.s  = "Hallo  ... Halloooooo ?" + Chr(10)
  text    + "blabla"
  
  SetGadgetText(#editor,text)
  
  Repeat 
    event = WaitWindowEvent()
    
  Until event = #WM_CLOSE



Verfasst: 03.09.2006 13:02
von PBZecke
War mir klar dass es ohne CallBack nicht gehen würde. Aber den benötigt
Eckhard für die Worterkennung ja ohnehin.

Habe mir erlaubt den code so anzupassen, dass er wie von Eckhard
gewünscht funktioniert.


Code: Alles auswählen

  Macro LOWORD(Value)
    Value & $FFFF
  EndMacro
 
  Macro HIWORD(Value)
    (Value >> 16) & $FFFF
  EndMacro
 
  #window = 0
  #editor = 0
  #text   = 1
 
 
  Procedure Callback(hwnd,msg,wParam,lParam)
    Protected pt.POINT , hdc.l , linelength.l
    Protected line.l , index.l , lineindex.l
    Protected pbid.l = GetProp_(hwnd,"PBID")
    Protected *char.character , Size.SIZE
    Protected old = GetGadgetData(pbid)
    Protected linetext.s
   
    If msg =  #WM_LBUTTONDBLCLK Or msg = #WM_LBUTTONDOWN
     
      pt\x        = LOWORD(lParam)
      pt\y        = HIWORD(lParam)
     
      index       = SendMessage_(hwnd,#EM_CHARFROMPOS,0,@pt) 
      line        = SendMessage_(hwnd,#EM_EXLINEFROMCHAR,0,index)   
      lineindex   = SendMessage_(hwnd,#EM_LINEINDEX ,line,0) 
      linetext    = GetGadgetItemText(pbid,line,0)
     
      ;ende suchen
      *char = @linetext + (index - lineindex)
      While *char\c
       
        If *char\c = 32 Or *char\c = 10 ; leerzeichen und linefeed
          *char\c = 0
          Break
        EndIf
       
        *char + SizeOf(character)
      Wend
     
      ;anfang suchen
      *char = @linetext + (index - lineindex)
      While *char\c And *char > @linetext
        If *char\c = 32 ; leerzeichen
          *char + 1
          Break
        EndIf
        *char - SizeOf(character)
      Wend
     
      SendMessage_(hwnd,#EM_POSFROMCHAR ,@pt,lineindex + *char -@linetext) 
     
      ;breite und hoehe des wortes holen
      hdc = GetDC_(hwnd)
      GetTextExtentPoint32_(hdc,*char,Len(PeekS(*char)),@Size)
      ReleaseDC_(hwnd,hdc)
     
      ;pruefen ob sich die maus ueber dem wort befindet
      If Size\cy + pt\y >= HIWORD(lParam) And pt\y <= HIWORD(lParam) And Size\cx + pt\x >= LOWORD(lParam) And pt\x <= LOWORD(lParam)   
        SetGadgetText(#text,PeekS(*char))
      Else
        SetGadgetText(#text,"")
      EndIf
     
    EndIf
   
   
    ProcedureReturn CallWindowProc_(old,hwnd,msg,wParam,lParam)
  EndProcedure
 
  Procedure SubclassGadget(gadget)
    If IsGadget(gadget)
      Protected old = SetWindowLong_(GadgetID(gadget),#GWL_WNDPROC,@Callback())
      ProcedureReturn SetGadgetData(gadget,old)
    EndIf
  EndProcedure
 
 
  hwnd = OpenWindow(#window,#PB_Ignore,#PB_Ignore,400,400,"")
 
  CreateGadgetList(hwnd)
 
  font = LoadFont(0,"Curier New",10)
  SetGadgetFont(#PB_Default,font)
 
  EditorGadget(#editor,0,0,400,370) : SubclassGadget(#editor)
  TextGadget(#text,0,375,400,23,"",#PB_Text_Border)
 
  text.s  = "Hallo  ... Halloooooo ?" + Chr(10)
  text    + "blabla"+ Chr(10)
 
  SetGadgetText(#editor,text)
 
  Repeat
    event = WaitWindowEvent()
   
  Until event = #WM_CLOSE

Verfasst: 03.09.2006 13:09
von Kaeru Gaman
okeee, dann lag ich mit meiner vermutung ja mal meilenweit daneben.
hab wohl auch das kernproblem falsch verstanden.

danke, dass ihr es lediglich ignoriert habt, und nicht in beschimpfungen ausgebrochen seid. :D