"Klick ins EditorGadget klickt nicht immer"

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Eckhard.S
Beiträge: 136
Registriert: 22.07.2006 17:19
Wohnort: Meschede/Sauerland

"Klick ins EditorGadget klickt nicht immer"

Beitrag 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
Viele Grüße aus dem Sauerland
Eckhard

PureBasic 4.0 Vollversion, WinXP
Make a better world :D
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Beitrag 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
Benutzeravatar
PBZecke
Beiträge: 399
Registriert: 02.09.2004 17:34

Beitrag 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
Nein, ich habe die Suche nicht benutzt, und deshalb auch nichts dazu gefunden... :lol:
Benutzeravatar
Eckhard.S
Beiträge: 136
Registriert: 22.07.2006 17:19
Wohnort: Meschede/Sauerland

Beitrag 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 ???
Viele Grüße aus dem Sauerland
Eckhard

PureBasic 4.0 Vollversion, WinXP
Make a better world :D
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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...)
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
PBZecke
Beiträge: 399
Registriert: 02.09.2004 17:34

Beitrag 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.)
Nein, ich habe die Suche nicht benutzt, und deshalb auch nichts dazu gefunden... :lol:
Benutzeravatar
Eckhard.S
Beiträge: 136
Registriert: 22.07.2006 17:19
Wohnort: Meschede/Sauerland

Beitrag 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.
Viele Grüße aus dem Sauerland
Eckhard

PureBasic 4.0 Vollversion, WinXP
Make a better world :D
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag 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


Benutzeravatar
PBZecke
Beiträge: 399
Registriert: 02.09.2004 17:34

Beitrag 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
Nein, ich habe die Suche nicht benutzt, und deshalb auch nichts dazu gefunden... :lol:
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten