Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Stupid Code Tricks

Status
Not open for further replies.

Scott24x7

Programmer
Jul 12, 2001
2,826
JP
I'm feeling particularly idiotic today.
I was looking through data in one of my Combobox dropdowns, and realized that my mouse wheel did not move me through it's contents. I know there is a "MouseWheel" event and I know it gives negative numbers for moving one way, and positive numbers for moving the other way. But that's about all the VFP help file tells you...
I'm really surprised it doesn't just "work" but then again, that's probably silly of me to think so.

So the question, which I'm sure has an incredibly easy, but unobvious answer in the scheme of the help files, is, How do you get the mouse wheel to scroll the items in a combo/list box?


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
It does scroll by default when the cursor is in the textbox, and not inside the list.
 
Well that's annoying...
Is there any way to get the mouse to move objects in the list?


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Do any events fire then?
MouseOver?
I guess I can test that with a MESSAGEBOX.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Yes, there's no chance, when there is no event. The dropdown list even hasn't got an object reference.
You'll find the event tracking in the dbugger frame or window in its Tools menu. In the simplest case let it track all events and write them to the debugout window.
Of course open that debugout window and put it aside, now try a combobox.

You'll get no events at mousewheel within the dropdown list. There is nothing you can do about that but more genereically bind to mouse events, maybe via BINDEVENTS to windows messages. Then combine that with the mouse position and your knowledge about the dropdown list. Even just the position of that is tricky. If you somehow know it's open you still would need to compute whether it's really dropped down or popping up above the textbox portion. I'm talking of a listbox at windows edges or at screen/display edges opening up in different directions as needed to be visible.

The Windows Message of the mouse wheel is #define WM_MOUSEWHEEL 0x020A

What works is the debugout window shows events of WM_MOUSEWHEEL when establishing this mouseeventhandler, also while in the dropdown list portion of a combobox:
Code:
Public goMouseEventhandler
goMouseEventhandler = Createobject("mouseevents")

#Define WM_MOUSEWHEEL  0x020A
#Define GWL_WNDPROC    -4

Define Class mouseevents As Custom
   nOldProc = 0

   Procedure Init()
      Declare Integer GetWindowLong In WIN32API ;
         integer HWnd, ;
         integer nIndex

      Declare Integer CallWindowProc In WIN32API ;
         integer lpPrevWndFunc, ;
         integer HWnd,Integer Msg,;
         integer wParam,;
         integer Lparam

      This.nOldProc=GetWindowLong( _vfp.HWnd, GWL_WNDPROC)

      Bindevent(_vfp.HWnd,WM_MOUSEWHEEL,This,"mousewheel",1+2+4)

   Endproc

   Procedure MouseWheel()
      Lparameters HWnd As Integer, Msg As Integer, wParam As Integer, Lparam As Integer

      Debugout wParam, Lparam

      nRetvalue=CallWindowProc(This.nOldProc,HWnd,Msg,wParam,Lparam)
      Return nRetvalue
   Endproc

Enddefine

Good luck with that. You'll need to make use of the wParam and lParam values you get and you need to know, whether the mouse position is located within the items list. You might decide to make the mousewheel scroll the itmes independent of the muose position. Then only the sign of wParam matters. But you need to know whether the list is popped out or collapsed.

Bye, Olaf.
 
See Set Eventtracking and Set Coverage in Help

I recommend Event Tracking rather than Coverage in this case. But it's a matter of taste.

In fact, I've just done Event Tracking for a simple combo box, and I don't see any events at all firing for when the mouse is over the list portion - not even a MouseMove.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Well that's all encouraging...
At least last time I was trying to do something impossible. :) (Click, Double-Click for those of you involved in THAT disaster).
I thought it was just me forgetting to do something "right" in the MouseWheel event.
I do totally understand why this was "overlooked", because really until recently MouseWheel was not a heavily used "feature" of the mouse. (And hey, look at the Mac, still only 1 button...)
So with it an unpopular option, their coverage of it as it is was probably "advanced" for 2004.
Alas, I think you have all convinced me this is "too hard bucket" especially when I still have other critical functionality to look after. If no one has come up with a reasonable solution for this in the last 15 years of VFP, in the immortal words of Wierd Al Yankovic "Never mind, I give up".


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
The code I gave actually does give events when you scroll your mousewheel, totally independent on where you do so. The "only" thing you need is relate it with the currently open combobx list or current object under the mouse. There's a sys function for that with SYS(1270,x,y), wonder if that gives you the combobox object, if you are over the dropdown list.

Bye, Olaf.
 
Yeah, and I like you've got some possibility here Olaf, it's pretty clever (extremely clever), but it's also an unpredictable kludge. What if they move the window? Even a little bit.
I'm afraid it's more work than I'm willing to give it. It's not that huge an interface issue in this case. I don't use the ComboBox's that often, and usually max 10 items in it, but most often 4 - 6 which all appear in the list, so just move down and click it. I have on larger drop-down, but it seems to be getting unwieldy for a dropdown, so I'll probably seek another way to deal with it anyway.

Hmmm, just thought of a way you might be able to "Fool" it using a Grid over a simulated drop-down in appearance, and .Visible property...
I may be able to simulate the appearance instead, and that would be preferable to struggling to invent events that don't exist... or don't fire when you think they should! :)


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Well, there is further distinction. The list is dropped with the DropDown event and when it collapses Valid event occurs.

I somewhat got it going by simply doing KEYBOARD '{DNARROW}' or KEYBOARD '{UPARROW}' controlled by SIGN(wParam) (1=up, -1=down).
The problem is, with the mouse within the list the scrolling is reverted right away, as the mousepointer hovering an item scrolls back to it. So you can only use the mouse wheel outside of the list, when it makes less sense. You can make use of the mousewheel when positioned on the scrollbar anyway, so it's really not a big help.

I'd rather not use a grid for a dropdownlist replacement. That's even more weird than binding to windows event messages.

Bye, Olaf.
 
Olaf,
Yeah, I know the grid is a weird kludge, but it has the merit of having the mouse behavior. So it's more a preference of "fooling what the user is seeing" as it is "make VFP try to do something it can't".
In the balance, I would take the grid option, but as I mention, it's actually a pretty small point, and wanted to use it instead of addressing the other real problem which is the list is too long, and it needs to really be managed in another way.

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Well, vfp can bind to windows messages, that's normal operation. Fooling the user to see a dropdown list when really working in a grid is no crime, but it might arise some other unknown behaviour. The binding to windows messages is no kludge, it's normal to do for many other applications and languages not offering the detailed event model already native in VFP classes, but guess how those events are triggered? It mainly boils down to windows sending messages to processes bound to hwnd.

You have missed the introduction of Bindevent, as that was new in VFP8 and Windows Message binding was added in VFP9. Samples has a good example on windows event binding and it's usage, eg for media change events (inserting a USB thumb drive or ejecting it) or even docking/undocking. And just because there is no native class in foxpro having these events, the windows messaging system is normal and not a secret thing.

Bye, Olaf.

 
Olaf,
I see, and I now understand your point. Yeah, I skipped really from VFP 7 to 9, didn't do anything of memory from VFP 8. So there were a few introductions I didn't get, and since I've not worked in them before, it feels very foreign to me. I try to "stay within" VFP as much as possible (like when I work with Excel, I prefer to do anything I possibly can do "In Cell" as opposed to going of to VBA and all the hassle that "macro's" bring along with them.
I like they tried to "predict the future" and allow hooks to things that the OS will do natively for you. But it's still a little outside my capability for the moment, and the focus on other functionality is driving me to "revisit" this later. For now, function before form, and this is a "form" issue.


Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Interesting, makes me wonder how he collapses the native dropdown list, or is it simply covered by the grid?
I'll have a look at this, too.

Thanks for pointing this out, Jockey.

Just to round up the windows message binding, if you simply replace the debugout wParam,lparam of my code with the following code, you'll also have scrolling as far as it goes. Not bound to anything, simply by using the up/downarrow keys, which provide the scroll effect in most scenarios automatically on the currently focused control:
Code:
If Sign(wParam)=1
   Keyboard '{UPARROW}'
Endif

If Sign(wParam)=-1
   Keyboard '{DNARROW}'
Endif

Now establish a simple combobox:
Code:
_screen.AddObject("cboCombo","combobox")
_screen.cboCombo.RowSource = "1,one,2,two,3,three,4,four,5,five,6,six,7,seven,8,eight,9,nine"
_screen.cboCombo.RowSourceType = 1
_screen.cboCombo.ColumnCount = 2
_screen.cboCombo.Visible = .t.

If you try this you'll see the mouse positioned within the dropdownlist does indeed change the item (number) in the textbox portion of the combobox while scrolling, but the list stays at the item under the mouse, simply because of the standard behavior. That's why this solution fails, as you can't override this standard behaviour.

If you put the mouse pointer to the side of the list the keyboard commands scroll the list, so it works to this extent without any further ado on anything you already have developed.

Bye, Olaf.
 
Cool, so my Grid idea wasn't so stupid afterall. :)

Best Regards,
Scott
ATS, CDCE, CTIA, CTDC

"Everything should be made as simple as possible, and no simpler."[hammer]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top