ListIconGadget und Maus

Anfängerfragen zum Programmieren mit PureBasic.
ThoPie
Beiträge: 130
Registriert: 19.05.2006 15:18
Kontaktdaten:

ListIconGadget und Maus

Beitrag 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.
Benutzeravatar
scholly
Beiträge: 793
Registriert: 04.11.2005 21:30
Wohnort: Düsseldorf

Beitrag von scholly »

Ich bin blutiger PB-Anfänger.
seit 17.12.08: PB 4.3 unter XP Home(SP3)
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag 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
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag 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 

Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag von edel »

@hjbremer

Was machst du eigentlich, wenn ein Event mal nicht in
der Schleife ankommt ? Was ist denn so schlimm an einem
Callback ?
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Beitrag 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.
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
edel
Beiträge: 3667
Registriert: 28.07.2005 12:39
Computerausstattung: GameBoy
Kontaktdaten:

Beitrag 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.
Antworten