The MASM Forum

General => The Workshop => Topic started by: jj2007 on December 06, 2012, 06:16:20 AM

Title: Cursor change event
Post by: jj2007 on December 06, 2012, 06:16:20 AM
In MS Word, you can adjust table columns by clicking on the border and dragging it left or right.

I would like to do the same with tables in a RichEdit control.
Adjusting column widths is not a big deal, but how to know that the mouse cursor is hovering over a vertical gridline?

When moving the mouse over the cell border/gridline, it changes from I-Beam to arrow right. So I thought catching WM_CURSORCHANGING would be a good start.

Problem is that there is no WM_CURSORCHANGING or WM_CURSORCHANGED message!
Hooking SetCursor is one possibility, but a system-wide hook is not high on my list of desirable options. Any other ideas?
Title: Re: Cursor change event
Post by: dedndave on December 06, 2012, 06:20:55 AM
you mean there are no notifications in a sub-classed proc for the edit control ?

if not - you may be bound to setting up a RECT to describe the line
then use WM_MOUSEMOVE, PtInRect, SetCapture, ReleaseCapture, WM_CAPTURECHANGED - a lot of overhead
Title: Re: Cursor change event
Post by: jj2007 on December 06, 2012, 06:51:43 AM
No notifications, neither in the main nor in the subclassed wndproc. I googled a lot, it seems it simply doesn't exist. On the other hand, I just timed the GetCursor call, it's a mere 3 µs on my trusty old Celeron M. So that could fit into the WM_MOUSEMOVE handler...
Title: Re: Cursor change event
Post by: MichaelW on December 06, 2012, 07:50:16 PM
You could take a look at TrackMouseEvent.
Title: Re: Cursor change event
Post by: jj2007 on December 06, 2012, 09:55:31 PM
Thanks, Michael.

TrackMouseEvent sounds interesting but the table case happens inside the same window...
GetCursor seems the way to go. Unfortunately, the cursor in question is not one of the IDC_xxx cursors - RichEdit loads the arrow-right cursor via LoadImage. Oh well.
Title: Re: Cursor change event
Post by: dedndave on December 06, 2012, 11:43:29 PM
Jochen,
can you give a bare-bones code example to play with ?
or is it too difficult
it would make it easier to try ideas  :P
Title: Re: Cursor change event
Post by: dedndave on December 06, 2012, 11:59:10 PM
maybe - each column has its' own RE control ?   :P
Title: Re: Cursor change event
Post by: jj2007 on December 07, 2012, 10:30:06 AM
Quote from: dedndave on December 06, 2012, 11:59:10 PM
maybe - each column has its' own RE control ?   :P

No, it's all in one control.
Re barebones example: see attachment. I am afraid it needs the very latest MasmBasic package (7 Dec 2012 (http://www.masm32.com/board/index.php?topic=94.0)), and you will have to open the attached file in \Masm32\RichMasm\RichMasm.exe

Once you see it in RichMasm, hit F6, click OK and go to System Apps, User plugin. You'll get all the messages of the main WndProc plus those of the subclassed RichEdit control. Move the mouse over the borders of the table and see what comes along. The 1080 etc messages look interesting.

The plugin technique is that you supply two WndProcs ($exp) which RichMasm uses before starting the normal processing. You return in edx a flag that tells RichMasm to either
- continue its own tailored processing (edx=0)
- return eax (edx=-1)
- continue with DefWindowProc (edx=-2)

Kind of hooking the editor (there is also the simpler PiEntryPoint export, like for qEditor plugins).

Here is the relevant code in RichMasm's main WndProc:

WndProc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
...
mov ecx, PluginCbMain
jecxz @F
push lParam
push wParam
push uMsg
push hWin
call ecx ; call the plugin WndProc
inc edx ; edx=0->1: proceed
jg @F
jne DWP ; -2->-1: only defwinproc
pop ebx ; -1->0: return eax
pop edi
pop esi
ret
@@:
SWITCH uMsg


P.S.: To modify the plugin, go to System Apps, hold Shift and click User plugin. This unloads the DLL and lets you build the new version, which is then available again in System Apps.
Title: Re: Cursor change event
Post by: dedndave on December 07, 2012, 10:49:58 AM
maybe - each column has its' own RE control ?

what i meant was - make it that way - lol


whao !   :icon_eek:
i just wanted to see a rich edit with a column - lol
wasn't expecting all that

let me have a look...
Title: Re: Cursor change event
Post by: jj2007 on December 07, 2012, 05:44:49 PM
Quote from: dedndave on December 07, 2012, 10:49:58 AM
let me have a look...

Have fun. If I remember well, you have your own message monitor - mine is not 100% complete. Maybe you spot something useful...

You can also use Print "Msg=", Hex$(whatever), CrLf$ etc inside the plugin.
Title: Re: Cursor change event
Post by: dedndave on December 07, 2012, 11:00:35 PM
well - i can't say it was helpful   :P

you are looking at contents of a buffer, as opposed to a line drawn in a window
a small distinction - but one that makes things difficult
the only thing that comes to mind is to handle your own columns
which sounds very messy
Title: Re: Cursor change event
Post by: jj2007 on December 07, 2012, 11:52:37 PM
Quote from: dedndave on December 07, 2012, 11:00:35 PM
you are looking at contents of a buffer, as opposed to a line drawn in a window

At the bottom of RichMasmPlugin4Dave.asc,. there is a "Table for testing". If you select it and go to Edit & Format, Autoformat, you'll see that manipulating the columns is actually not that difficult.

The difficult part is
a) knowing that the user wants to change a column width (and the cursor change when hovering over the border seems the clue to do that)
b) finding out which column (and that means parsing the \cellx codes to find the nearest match).
Title: Re: Cursor change event
Post by: dedndave on December 08, 2012, 12:29:41 AM
well - the GetCursor function can be used to see the cursor change, i would think
you won't know which cursor it is, as it returns a handle
but - you will know that it has changed

i would think the hard part is knowing which screen pixel locations the column lines are on, to begin with
functions like GetCursor and GetCursorPos should be very fast
they only have to get already-existing data from some table or structure and return it
Title: Re: Cursor change event
Post by: jj2007 on December 08, 2012, 04:18:20 AM
Quote from: dedndave on December 08, 2012, 12:29:41 AM
well - the GetCursor function can be used to see the cursor change, i would think
you won't know which cursor it is, as it returns a handle

There are only three cursors around - beam, hourglass and arrow right. Only the latter has a handle above 0ffffh, so that is easy. However, the arrow right is not linked to the border but rather to the no-typing area. Still, when you move in from the left, it is a precise x position that triggers the change. And GetCursor is indeed extremely fast.
Title: Re: Cursor change event
Post by: dedndave on December 14, 2012, 01:18:04 PM
well - if you get that part figured out....

i am working on a project that uses dividers
i copy/pasted some code from that to make this little example
i do not use the DragDetect or TrackMouseEvent mechanisms
it seems to work quite well - very fast

maybe you'll find it helpful   :P

EDIT: made a few minor changes and did some cleanup
Title: Re: Cursor change event
Post by: jj2007 on December 14, 2012, 02:01:11 PM
Very cute, Dave, thanks :t
Title: Re: Cursor change event
Post by: MichaelW on December 14, 2012, 06:55:36 PM
It works well Dave, but on my systems one of the 4 possible orientations at the intersection is missing.
Title: Re: Cursor change event
Post by: dedndave on December 14, 2012, 08:12:27 PM
you mean the ne/sw cursor ?
this particular application didn't really warrant the forth cursor

there are 3 cases:
you are on the vertical divider
you are on the horizontal divider
you are on both dividers

tell me what the 4th case is, and i'll put the cursor on it   :biggrin:
(and, before it hits the page, i am not counting "you are not on any divider" as a case - lol)
Title: Re: Cursor change event
Post by: dedndave on December 15, 2012, 03:12:06 AM
i made a few minor changes and did some cleanup
updated the previous post with a new attachment
Title: Re: Cursor change event
Post by: MichaelW on December 15, 2012, 03:30:46 AM
The Microsoft name for the one missing is Diagonal Resize 2, but I see now that the functionality is there for dragging in both diagonal directions. I was expecting different cursors for the two directions, but I now think it would be a needless complexity.
Title: Re: Cursor change event
Post by: Magnum on December 15, 2012, 04:07:10 AM
That is a pretty neat.

Will put that in my source code directory.

Andy
Title: Re: Cursor change event
Post by: dedndave on December 15, 2012, 04:38:33 AM
Michael,
if you look at the _main source, i do in fact load the 4th cursor
that's because i used it in the program from which i copied this code
that window composition is reversable   :P
and, i figured that someone else may want it
the LoadCursor ID names are... (there are more - see LoadCursor)
IDC_SIZENS
IDC_SIZEWE
IDC_SIZENWSE
IDC_SIZENESW
i think the "diagonal resize" name is for the cursor file, itself (C:\Windows\Cursors)

thanks Andy   :t
Title: Re: Cursor change event
Post by: dedndave on December 15, 2012, 04:46:07 AM
for this window, it made sense to use both diagonal sizing cursors
i use the ne/sw one for the first case and the nw/se one for the second

(http://img14.imageshack.us/img14/796/mano1.png)

(http://img577.imageshack.us/img577/3731/mano2.png)