ComboBox noscroll

Für allgemeine Fragen zur Programmierung mit PureBasic.
BSP
Beiträge: 188
Registriert: 01.02.2009 14:04

ComboBox noscroll

Beitrag von BSP »

Hallo Allerseits.
Ich habe nach langer Zeit mal wieder eine Frage.

Befinde ich mich mit der Maus auf einer Combobox,
kann ich einfach durch drehen des Mausrad's einen Eintrag auswählen,
ohne die Box aufzuklappen.
Genau das möchte ich verhindern.
Eine Auswahl darf nur aus der aufgeklappten Box erfolgen.
Könnt Ihr helfen?

Schon mal Danke im Voraus für Eure Mühe.
MfG: Bernd

Code: Alles auswählen

OpenWindow(0, 0, 0, 100, 50, "Scroll Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ComboBoxGadget(0, 10, 10, 80, 26)
For i = 1 To 10
  AddGadgetItem(0, -1, "Eintrag " + Str(i))
Next
SetGadgetText(0, "Eintrag 5")

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
PB 5.31 (x86) & (x64) Win10
Benutzeravatar
Pelagio
Beiträge: 423
Registriert: 11.11.2004 17:52
Computerausstattung: Intel Core i3-4170 CPU 3,70 GHz
8,00 GB Arbeitsspeicher
WIN 10 Pro 64 Bit Betriebssystem
Wohnort: Bremen

Re: ComboBox noscroll

Beitrag von Pelagio »

Guten Morgen BSP,

ich habe aus der WINAPI etwas herausgezogen und glaube das es Dir helfen könnte und wenn auch nur als Anregung..

Code: Alles auswählen

Procedure.w MouseWheelDelta() 
	Protected x.w

	x.w = ((EventwParam()>>16)&$FFFF) 
	ProcedureReturn -(x / 120) 
EndProcedure

OpenWindow(0, 0, 0, 100, 50, "Scroll Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ComboBoxGadget(0, 10, 10, 80, 26)
For i = 1 To 10
  AddGadgetItem(0, -1, "Eintrag " + Str(i))
Next
SetGadgetText(0, "Eintrag 5")

Repeat
	EventID = WaitWindowEvent()
	Select EventID
		Case #WM_MOUSEWHEEL
			If (MouseWheelDelta()=1)
				SetGadgetState(0, GetGadgetState(0)-1)
			Else
				SetGadgetState(0, GetGadgetState(0)+1)
			EndIf
		Case #PB_Event_CloseWindow: End
	EndSelect
ForEver
:allright:
Ohne Zeit kein Fleiß
Auf neustem Stand zu sein ist eine Kunst die nicht jeder perfektioniert [Win10Pro(64); PB6.03 LTS]. :allright:
Benutzeravatar
RSBasic
Admin
Beiträge: 8022
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: ComboBox noscroll

Beitrag von RSBasic »

Hallo Pelagio,

dein Beispiel funktioniert nicht zuverlässig. Wenn man ganz schnell das Mausrad dreht, dann kann man trotzdem bisschen scrollen.
Deine Vorgehensweise ist eher ein Workaround. Sinnvoller und richtigerweise wäre ein Callback. Dort kann man das Scrollen gezielt und viel besser abschalten, als in der eingeschränkten PB-Eventschleife.

\\Edit:
Also so:

Code: Alles auswählen

EnableExplicit

Define i

Global ComboBoxCB

Procedure ComboBoxCB(hWnd, Message, wParam, lParam)
  Select Message
    Case #WM_MOUSEWHEEL
      ProcedureReturn 1
  EndSelect
  
  ProcedureReturn CallWindowProc_(ComboBoxCB, hWnd, Message, wParam, lParam)
EndProcedure

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ComboBoxGadget(0, 10, 10, 80, 26)
  For i = 1 To 10
    AddGadgetItem(0, -1, "Eintrag " + Str(i))
  Next
  SetGadgetText(0, "Eintrag 5")
  
  
  ComboBoxCB = SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, @ComboBoxCB())
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Omi
Beiträge: 143
Registriert: 25.03.2013 09:59

Re: ComboBox noscroll

Beitrag von Omi »

Hi!
Da ich das "Feature" gar nicht so sinnfrei finde (ungewollte Umschaltung bei Fokus) häng' ich mal das Linux-Pendant an (die APIs sind sich hier ja mal selten einig :wink: ) ...

Code: Alles auswählen

EnableExplicit

ImportC ""
	g_signal_connect(*instance, detailed_signal.p-utf8, *c_handler, *data, destroy= 0, flags= 0) As "g_signal_connect_data"
EndImport

; Object constants
#Win_Main  = 0

#But1      = 0
#CBox1     = 1


Global.i gEvent, gQuit

ProcedureC Callback_GadgetNoScroll(*widget.GtkWidget, *event.GdkEventScroll, user_data)
	Protected.i Result= #False
	
	If user_data = #CBox1
		If *event\type = #GDK_SCROLL
			If GetGadgetState(#But1)
				Result= #True
			EndIf
		EndIf
	EndIf
	ProcedureReturn Result
EndProcedure

Procedure Create_WinMain()
	Protected.i I
	
	If OpenWindow(#Win_Main, 0, 0, 400, 180, "Suppresses ComboBoxGadget mouse scrolling", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
		ButtonGadget(#But1,     5,  5, 390, 40, "No ComboBox mouse scrolling", #PB_Button_Toggle)
		ComboBoxGadget(#CBox1,  5, 50, 350, 21)
		For I = 1 To 10
			AddGadgetItem (#CBox1, -1, "Eintrag " + Str(i))
		Next I
		SetGadgetText(#CBox1, "Eintrag 5")
		
		g_signal_connect(GadgetID(#CBox1), "scroll-event", @Callback_GadgetNoScroll(), #CBox1)
	EndIf
EndProcedure

Create_WinMain()

Repeat
	gEvent= WaitWindowEvent()
	
	Select gEvent
		Case #PB_Event_CloseWindow
			gQuit= #True
			
	EndSelect
	
Until gQuit
Gruß, Charly
PureBasic Linux-API-Library: http://www.chabba.de
BSP
Beiträge: 188
Registriert: 01.02.2009 14:04

Re: ComboBox noscroll

Beitrag von BSP »

Hallo RSBasic.
Klasse. Spitze. So war's erhofft.
Danke.
Bernd.
PS. Bitte nicht böse sein, das ich "EnableExplicit" aus kommentiert habe.
So experimentiert es sich leichter. Smile.

Code: Alles auswählen

;EnableExplicit

Define i

Enumeration
  #gadg_combo1
  #gadg_combo2
  #gadg_combo3
  #gadg_rt_trackbar
EndEnumeration


Global ComboBoxCB

Procedure MouseOver(gadg)
  GetWindowRect_(GadgetID(gadg),re.RECT)
  GetCursorPos_(pt.POINT)
  ProcedureReturn PtInRect_(re, pt\y << 32 + pt\x)
EndProcedure


Procedure ComboBoxCB(hWnd, Message, wParam, lParam)
  Select Message
    Case #WM_MOUSEWHEEL
      ProcedureReturn 1
  EndSelect
  ProcedureReturn CallWindowProc_(ComboBoxCB, hWnd, Message, wParam, lParam)
EndProcedure

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ComboBoxGadget(#gadg_combo1, 10, 10, 80, 26)
  For i = 1 To 10
    AddGadgetItem(#gadg_combo1, -1, "Eintrag " + Str(i))
  Next
  SetGadgetText(#gadg_combo1, "Eintrag 5")
  
  ComboBoxGadget(#gadg_combo2, 100, 10, 80, 26)
  For i = 1 To 10
    AddGadgetItem(#gadg_combo2, -1, "Eintrag " + Str(i))
  Next
  SetGadgetText(#gadg_combo2, "Eintrag 6")
  
  ComboBoxGadget(#gadg_combo3, 190, 10, 80, 26)
  For i = 1 To 10
    AddGadgetItem(#gadg_combo3, -1, "Eintrag " + Str(i))
  Next
  SetGadgetText(#gadg_combo3, "Eintrag 6")
  
  x = 10
  y = 50
  w = WindowWidth(0) -50
  h = 26
  TrackBarGadget(#gadg_rt_trackbar, x,y, w, h, 0, 100);, #PB_TrackBar_Vertical);#PB_TrackBar_Ticks | 
  SetWindowLongPtr_(GadgetID(#gadg_rt_trackbar), #GWL_STYLE,   GetWindowLongPtr_(GadgetID(#gadg_rt_trackbar), #GWL_STYLE)   | #TBS_ENABLESELRANGE) ; Vertiefung
  SetWindowLongPtr_(GadgetID(#gadg_rt_trackbar), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(#gadg_rt_trackbar), #GWL_EXSTYLE) | #WS_EX_LAYOUTRTL)    ; Spiegeln
  #schritt = 25 : schritt = 25
  ;   For a=0 To 100 Step #schritt ; (Schade. Eine einfache var wäre schöner).
  ;     SendMessage_(GadgetID(#gadg_rt_trackbar),#TBM_SETTIC,0,a)
  ;   Next
  a = 0
  Repeat ; Dann also so.
    SendMessage_(GadgetID(#gadg_rt_trackbar),#TBM_SETTIC,0,a)
    a + schritt
  Until a > 100
  
  
  ComboBoxCB = SetWindowLongPtr_(GadgetID(#gadg_combo1), #GWL_WNDPROC, @ComboBoxCB())
  ComboBoxCB = SetWindowLongPtr_(GadgetID(#gadg_combo2), #GWL_WNDPROC, @ComboBoxCB())
  ComboBoxCB = SetWindowLongPtr_(GadgetID(#gadg_combo3), #GWL_WNDPROC, @ComboBoxCB())
  ComboBoxCB = SetWindowLongPtr_(GadgetID(#gadg_rt_trackbar), #GWL_WNDPROC, @ComboBoxCB())
  ; Wird eine Box auskommentiert, kann man die Box mit der Maus scrollen.
  ; Das es auch mit der Trackbar funktioniert sieht man,
  ; wenn man den "CASE #WM_MOUSEWHEEL" Block aus der Eventschleife auskommentiert.
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
        
      Case #WM_KEYDOWN ;----- ( #WM_KEYDOWN
                       ;Debug EventwParam()
        Select EventwParam()
          Case #VK_UP ; 38
            speed + 1 : If speed > 100 : speed = 100 : EndIf
            SetGadgetState(#gadg_rt_trackbar, speed)
            ;rt_draw_regler(speed)
          Case #VK_DOWN ; 40
            speed - 1 : If speed < 0 : speed = 0 : EndIf
            SetGadgetState(#gadg_rt_trackbar, speed)
            ;rt_draw_regler(speed)
        EndSelect
        
      Case #WM_MOUSEWHEEL ;----- ( #WM_MOUSEWHEEL
        If Not MouseOver(#gadg_combo1) And Not MouseOver(#gadg_combo2) And Not MouseOver(#gadg_combo3)
          a = EventwParam()
          If a > 0
            speed = speed / schritt : speed = speed * schritt ; Funktioniert, weil INTEGER rundet auf / ab.
            speed + schritt : If speed > 100 : speed = 100 : EndIf
          Else
            a = speed % schritt : If a : speed - a + schritt : EndIf
            speed - schritt : If speed < 0 : speed = 0 : EndIf
          EndIf
          SetGadgetState(#gadg_rt_trackbar, speed)
        EndIf
        
    EndSelect
  ForEver
EndIf
PB 5.31 (x86) & (x64) Win10
Antworten