LB Booster
Programming >> Liberty BASIC language >> List view: detecting columnclick
http://lbb.conforums.com/index.cgi?board=lblang&action=display&num=1467984573

List view: detecting columnclick
Post by Hans on Jul 8th, 2016, 1:29pm

Does anybody has experience in detecting clicking the header in a List View using WN_COLUMNCLICK?

My list view works excelent, but detecting the columnclick doesn't work so far.

Hans




Re: List view: detecting columnclick
Post by Richard Russell on Jul 8th, 2016, 3:51pm

on Jul 8th, 2016, 1:29pm, Hans wrote:
My list view works excelent, but detecting the columnclick doesn't work so far.

Unfortunately the LVN_COLUMNCLICK notification arrives in a WM_NOTIFY message. Although you can intercept WM_NOTIFY messages using WMLiberty.DLL there are typically so many of them that they are likely to flood the handler and crash your program. sad

Ideally what you want is a version of WMLiberty.dll that provides more detailed filtering, so that rather than intercepting every WM_NOTIFY message it intercepts only those containing (say) a LVN_COLUMNCLICK notification. Unfortunately I'm not aware that such a DLL exists.

What have you tried so far? If you are lucky you may get away with using WMLiberty.dll to intercept all WM_NOTIFY messages, but it is risky.

Richard.
Re: List view: detecting columnclick
Post by Hans on Jul 15th, 2016, 7:39pm

I use msghook.dll. The central part in my code is:
Code:
'prepare callbacks
    hMsgProc = hwnd(#view.GetMsgHookCallback)
    calldll #MsgHook, "TrapMsgFor",hLV as ulong, r as boolean
    calldll #MsgHook, "TrapMsgFor",hSlide as ulong, r as boolean
    calldll #MsgHook, "WatchMsg", hLV as ulong, _WM_LBUTTONDBLCLK as long, r as boolean
    calldll #MsgHook, "WatchMsg", hLV as ulong, _WM_LBUTTONUP as long, r as boolean
    calldll #MsgHook, "WatchMsg", hLV as ulong, _WM_RBUTTONUP as long, r as boolean
    calldll #MsgHook, "WatchMsg", hLV as ulong, LVM.COLUMNCLICK as long, r as boolean
    calldll #MsgHook, "WatchMsg", hSlide as ulong, _WM_LBUTTONUP as long, r as boolean
    calldll #MsgHook, "WatchMsg", hParent as ulong, _WM_NOTIFY as long, r as boolean
    calldll #user32, "GetWindowLongA",hMsgProc as ulong,_GWL_ID as short,callbackID as long
    calldll #MsgHook, "CreateGetMsgProcHook", hParent as ulong, callbackID as long, hMsgProc as ulong, hHook as ulong
 

The callback part is:
Code:
[view.callback]
    calldll #MsgHook, "GetMsg", msg as struct, ret as void
    mesg=msg.message.struct
    select case mesg
    case _WM_LBUTTONDBLCLK
        if fname$<>"" then Notice "test" : goto [content.edit]
    case _WM_LBUTTONUP
        if msg.hndl.struct=hSlide then goto [navigate.scroll]
        rec=LVGETSINGSEL(hLV)
        r=DBVIEWNEXTLOAD(hLV,hSlide,rec,record,first,last,"edit")
    case _WM_RBUTTONUP
        if fname$<>"" then
            rec=LVGETSINGSEL(hLV) : record=first+rec-1
            goto [content.edit]
        end if
    case _WM_NOTIFY
        if msg.hndl.struct=hParent then print "x"
    case LVM.COLUMNCLICK
        test=test
    end select
goto [view.scanloop]
 

"[view.scanloop]" is in stead of "wait". Here I catch some keystrokes.

I hope someone has some experience with msghook.

Hans
Re: List view: detecting columnclick
Post by Hans on Jul 15th, 2016, 7:43pm

I never meet crashes using this code.
_WM_LBUTTONDBLCLK works as expected, so does _WM_LBUTTONUP and _WM_RBUTTONUP.
Re: List view: detecting columnclick
Post by Richard Russell on Jul 15th, 2016, 10:48pm

on Jul 15th, 2016, 7:43pm, Hans wrote:
I use msghook.dll

I'm not familiar with msghook.dll. I would be very interested to know how it compares with WMLiberty.dll; perhaps it has some advantages. Because I've not met it before msghook.dll is not on the list of DLLs (known to be) compatible with LBB. If you have ascertained that it is compatible I will update the list.

Quote:
I never meet crashes using this code.
_WM_LBUTTONDBLCLK works as expected, so does _WM_LBUTTONUP and _WM_RBUTTONUP.

That you don't have crashes, even when you intercept WM_NOTIFY messages (which you do in the code you listed) is encouraging and may suggest that you will be able to make it work, despite the probable high volume of messages.

The code you would need is something like this:

Initialisation Code:
    LVN.COLUMNCLICK = -108
    struct nmhdr, hwndFrom as ulong, idFrom as long, code as long 
 


Intercept Code:
    case _WM_NOTIFY
        nmhdr.struct = msg.lparam.struct
        if nmhdr.code.struct = LVN.COLUMNCLICK then
          ' handle columnclick here
        end if
 

Richard.

Re: List view: detecting columnclick
Post by Hans on Jul 18th, 2016, 3:01pm

The original site of msghook does not exist anymore. But still it can be downloaded at: http://vb.mvps.org/tools/MsgHook/.

So far I don't have succes. I inserted the pieces of code you offered. The program never gets within de part of "case _WM_NOTIFY", which makes all the rest useless.

I added Code:
calldll #MsgHook, "WatchMsg", hLV as ulong, _WM_NOTIFY as long, r as boolean 

in the part "prepare callbacks", that did not help either.

Hans
Re: List view: detecting columnclick
Post by Richard Russell on Jul 18th, 2016, 9:26pm

on Jul 18th, 2016, 3:01pm, Hans wrote:
So far I don't have success.

I know it can be made to work because I've done it successfully in BBC BASIC. In that case I used the embedded assembler to write my own custom message filter, to avoid overloading BASIC with the high volume of WM_NOTIFY messages.

So, as a last resort, my code could be ported to LBB using the 'BBC BASIC escape' feature (starting a line with an exclamation mark). Obviously the end result would be completely incompatible with LB 4, but at least you would end up with a working solution. Whether you want to go down that route is another matter!

Richard.

Re: List view: detecting columnclick
Post by Hans on Jul 19th, 2016, 09:27am

After repeated searching I found a piece of code on the LB forum that does the trick with WMLiberty. After my vacation I'll study it. Maybe I can find what I am doing wrong, maybe WMLiberty is just better for this.

Have a good summer
Hans
Re: List view: detecting columnclick
Post by SarmedNafi on Jul 19th, 2016, 11:57am

I will remain Waiting you Hans.

We got a red summer here.
Sarmed
Re: List view: detecting columnclick
Post by Hans on Aug 30th, 2016, 1:20pm

Using WMLiberty has serious drawbacks. On punishment of crashes, you can not use Wait, Confirm, Notice, Prompt, PopupMenu, Input and Input$(1) in your code. And who knows what else. On a crash you don't get a clou what happend. My code is quit large, so I don't want to get lost.
Maybe I'll try something with a translucent graphicbox placed over the header. Then I can track clicks on that graphicbox and translate that to which header is clicked.

Hans
Re: List view: detecting columnclick
Post by Richard Russell on Aug 30th, 2016, 3:00pm

on Aug 30th, 2016, 1:20pm, Hans wrote:
Using WMLiberty has serious drawbacks. On punishment of crashes, you can not use Wait, Confirm, Notice, Prompt, PopupMenu, Input and Input$(1) in your code.

My understanding is that most, if not all, of these limitations are specific to LB 4 and don't apply to LBB. For example I'm certain that it's OK to use WAIT with WMLiberty in LBB, and my expectation would be that the rest are OK too.

Do you have evidence that any of those statements cause problems when using WMLiberty with LBB? If so I would be interested to see examples that demonstrate the problem.

The one thing I do know is bad, when using WMLiberty, is calling the Sleep API for a lengthy period (e.g. for more than a couple of milliseconds) because that will introduce an undesirable latency in handling the trapped message. This is particularly an issue if trying to intercept WM_NOTIFY messages.

Richard.