Seite 1 von 1

ListIconGadget und Maus

Verfasst: 18.04.2008 19:34
von ThoPie
Hallo,
ich verwende ein ListIconGadget. In der Auswertung des Ereignisses #WM_MOUSEMOVE möchte ich gern herausfinden über welcher Zelle (Zeile, Spalte) sich der Cursor gerade befindet.
Könnte mit bitte jemand einen Tipp geben.

Vielen Dank.

Verfasst: 18.04.2008 19:50
von scholly

Verfasst: 18.04.2008 21:14
von Fluid Byte
Du könntest es so machen:

Code: Alles auswählen

#LVN_HOTTRACK = #LVN_FIRST-21

Procedure WindowCallback(hWnd,uMsg,wParam,lParam)
    Select uMsg
        Case #WM_NOTIFY
        *lpnm.NMHDR = lParam
        
 		If *lpnm\hWndFrom = GadgetID(0) And *lpnm\code = #LVN_HOTTRACK 		
 			*lpnmlv.NMLISTVIEW = lParam
 			
 			Debug "ITEM #" + Str(*lpnmlv\iItem)
 		EndIf 		 	
    EndSelect
     
    ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

OpenWindow(0,0,0,320,240,"void",#WS_OVERLAPPEDWINDOW | 1)
CreateGadgetList(WindowID(0))
ListIconGadget(0,0,0,0,0,"Name",250)

For i=1 To 50 : AddGadgetItem(0,-1,"ListIcon Item #" +Str(i)) : Next

SetWindowCallback(@WindowCallback())

Repeat
	EventID = WaitWindowEvent()

	If EventID = #PB_Event_SizeWindow
		ResizeGadget(0,5,5,WindowWidth(0)-10,WindowHeight(0)-10)
	EndIf
Until EventID = #PB_Event_CloseWindow

Verfasst: 20.04.2008 14:13
von hjbremer
und nun das Ganze ohne Callback und mit etwas WindowsApi

und da ich keine globalen Variablen benutze, auch kein EnableExplizit etc. Dafür gibt es Strukturen !

Code: Alles auswählen

Structure myListIcon

id.l
sp.l
ze.l

EndStructure

Procedure Api_LVM_MousePosition(*lv.mylisticon)

  ;Position des horizontalen Scrollbalken ermitteln
  info.scrollinfo 
  info\cbSize = SizeOf(SCROLLINFO) 
  info\fMask  = #SIF_ALL 
  GetScrollInfo_(*lv\id,#SB_HORZ,info.scrollinfo)              ;info\nTrackPos ist kein Pixelwert
  horzposi = SetScrollPos_(*lv\id,#SB_HORZ,info\nTrackPos,0)   ;gibt Pixelwert zurück

  ;index der obersten Zeile ermitteln, dies ersetzt Abfrage vertikaler Scrollbalken
  topindex = SendMessage_(*lv\id,#LVM_GETTOPINDEX,0,0)

  ;Höhe der Zeilen ermitteln, setzt voraus das alle gleiche Höhe haben !!!
  ; wenn nicht dann für itemhöhe eine Repeatschleife einbauen! ähnlich Spalte ermitteln
  SendMessage_(*lv\id,#LVM_GETITEMRECT,0,r.rect)
  itemhoehe = r\bottom - r\top
    
  ;Höhe des Headers ermitteln
  header = SendMessage_(*lv\id, #LVM_GETHEADER, 0, 0) 
  #HDM_GETITEMRECT = #HDM_FIRST + 7
  SendMessage_(header, #HDM_GETITEMRECT, 1, r.rect) 
  headerhoehe = r\bottom - r\top + 1 ;die 1 ist ein Korrekturwert um die Zeile genau zu treffen
  
  ;Größe bzw. Position vom ListIconGadget ermitteln bezogen auf Screen links oben
  GetWindowRect_(*lv\id,gadget.rect)   
  
  ;=====================================================

  ;wo bin ich bezogen auf Screen links oben
  GetCursorPos_(cursorpos.point) 
 
  ;ist MausCursor im Gadget ? 
  If PtInRect_(gadget.rect,cursorpos\x,cursorpos\y)
  
     ;x + y = Position im Gadget bezogen auf 1. sichtbare Spalte/Zeile links oben  
     x = cursorpos\x - gadget\left
     y = cursorpos\y - gadget\top - headerhoehe 
     
     ;Spalte ermitteln
     If x > 0
     
         j=0 
         abstand=2 ;die 2 ist ein Korrekturwert um die Spalte genau zu treffen
  
         Repeat  ;Spaltenbreiten addieren bis Mausposi erreicht
          
              br = SendMessage_(*lv\id,#LVM_GETCOLUMNWIDTH,j,0)
              
              If br                   
                  abstand + br
                  j + 1
                  spalte = j
              Else
                  spalte = -1
                  Break
              EndIf
        
         Until x + horzposi < abstand  ;hier wird horizontaler Scrollbalken berücksichtigt
     
     EndIf
     
     ;Zeile/Index ermitteln          
     If y > 0  ;y kann negativ werden, wegen headerhoehe
     
         zeile = (y / itemhoehe) + topindex + 1
       
     EndIf
     
  ;MausCursor NICHT im Gadget
  Else
  
     zeile = -1
     spalte = -1
    
  EndIf   

*lv\ze = zeile
*lv\sp = spalte

ProcedureReturn spalte

EndProcedure

;=====================================================

Enumeration
 
 #win1
 #but1
 #lvg1
 #lvg2

EndEnumeration

lv1.mylisticon
lv2.mylisticon

fontnr1 = FontID(LoadFont(#PB_Any, "Arial", 8))  
fontnr2 = FontID(LoadFont(#PB_Any, "Arial", 12))  

hwnd = OpenWindow(#win1,0,0,640,480,"ListIcon Gadget",#PB_Window_SystemMenu|1) 
       CreateGadgetList(hwnd) 

       ButtonGadget(#but1,10,420,80,25,"Tue nix")
       
       lv1\id = ListIconGadget(#lvg1,10,12,300,400,"",0,#PB_ListIcon_GridLines) 
                AddGadgetColumn(#lvg1,0,"Spalte 1",150) 
                AddGadgetColumn(#lvg1,1,"Spalte 2",55) 
                AddGadgetColumn(#lvg1,2,"Spalte 3",55) 

       SetGadgetFont(#lvg1, fontnr1)

       lv2\id = ListIconGadget(#lvg2,320,12,300,400,"",0,#PB_ListIcon_GridLines) 
                AddGadgetColumn(#lvg2,0,"Spalte 1",200) 
                AddGadgetColumn(#lvg2,1,"Spalte 2",200) 
                AddGadgetColumn(#lvg2,2,"Spalte 3",200) 
                
       SetGadgetFont(#lvg2, fontnr2)

       For i = 1 To 62 
          nr$ = LSet(Str(i),3," ") 
          txt$ = "Text in Zeile "+nr$+" in Spalte 1"+#LF$+"Spalte 2"+#LF$+"Spalte 3"
          AddGadgetItem(#lvg1, -1, txt$) 
          AddGadgetItem(#lvg2, -1, txt$) 
       Next 

;=====================================================

Repeat

  event = WaitWindowEvent() 
  
  If Event = #PB_Event_Gadget Or Event = #PB_Event_Menu 
          
      welcherButton = EventGadget()  
      
      Select welcherButton
      
            Case #but1: Debug "Button 1 gedrückt"

      EndSelect
            
  ElseIf event = #WM_MOUSEMOVE
     
      Api_LVM_MousePosition(lv1)
      
      If lv1\sp > -1
          Debug "LV1 Spalte " + Str(lv1\sp)
          Debug "LV1 Zeile  " + Str(lv1\ze)
      EndIf
  
      Api_LVM_MousePosition(lv2)
      
      If lv2\sp > -1
          Debug "LV2 Spalte " + Str(lv2\sp)
          Debug "LV2 Zeile  " + Str(lv2\ze)
      EndIf
      
      Debug "---"
      
  EndIf

Until event = #PB_Event_CloseWindow 

End 


Verfasst: 20.04.2008 14:16
von edel
@hjbremer

Was machst du eigentlich, wenn ein Event mal nicht in
der Schleife ankommt ? Was ist denn so schlimm an einem
Callback ?

Verfasst: 20.04.2008 14:47
von hjbremer
ich mache nix, da ich die Prozedur selbst nicht in Verbindung mit WM_MouseMove benutze, aber THOPIE danach gefragt hat

und außerdem wenn ein WM_MouseMove in der Schleife mal nicht ankommt, was solls

und ich habe nix gegen Callbacks, im Gegenteil, aber viele Andere, besonders Anfänger verstehen das Prinzip noch nicht und können darum auch einen Callback nicht ihren Bedürfnissen anpassen. Hinzu kommt, um mit dem Ergebnis im Callback weiter zuarbeiten, bedarf es häufig globale oder shared Variablen. Und ich hasse globale Variablen.

Und außerdem die meisten Callback Beispiele sind garnicht bis schlecht erklärt. Nützt Anfängern auch nicht viel.

Und nun was positives, der Callback von FluidByte ist Spitze :allright: wenn man ihn denn versteht.

Verfasst: 20.04.2008 14:56
von edel
Wenn jemand nach WM_MOUSEMOVE fragt, dann muss er das ja irgendwo
her haben. In der PB Hilfe steht dazu sicherlich nichts. Von daher ist es gar
nicht mal so verkehrt, es ihm gleich richtig zu zeigen. Ein Event das offiziell
nicht unterstuetzt wird, gehoert mit Sicherheit nicht in die PB Eventschleife,
auch wenn es manchmal leichter bzw kuerzer ist.