Author Topic: Cursor change event  (Read 12346 times)

jj2007

  • Member
  • *****
  • Posts: 10110
  • Assembler is fun ;-)
    • MasmBasic
Cursor change event
« 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?

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: Cursor change event
« Reply #1 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

jj2007

  • Member
  • *****
  • Posts: 10110
  • Assembler is fun ;-)
    • MasmBasic
Re: Cursor change event
« Reply #2 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...

MichaelW

  • Global Moderator
  • Member
  • *****
  • Posts: 1209
Re: Cursor change event
« Reply #3 on: December 06, 2012, 07:50:16 PM »
You could take a look at TrackMouseEvent.
Well Microsoft, here’s another nice mess you’ve gotten us into.

jj2007

  • Member
  • *****
  • Posts: 10110
  • Assembler is fun ;-)
    • MasmBasic
Re: Cursor change event
« Reply #4 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.

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: Cursor change event
« Reply #5 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

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: Cursor change event
« Reply #6 on: December 06, 2012, 11:59:10 PM »
maybe - each column has its' own RE control ?   :P

jj2007

  • Member
  • *****
  • Posts: 10110
  • Assembler is fun ;-)
    • MasmBasic
Re: Cursor change event
« Reply #7 on: December 07, 2012, 10:30:06 AM »
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), 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:

Code: [Select]
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.

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: Cursor change event
« Reply #8 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...

jj2007

  • Member
  • *****
  • Posts: 10110
  • Assembler is fun ;-)
    • MasmBasic
Re: Cursor change event
« Reply #9 on: December 07, 2012, 05:44:49 PM »
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.

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: Cursor change event
« Reply #10 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

jj2007

  • Member
  • *****
  • Posts: 10110
  • Assembler is fun ;-)
    • MasmBasic
Re: Cursor change event
« Reply #11 on: December 07, 2012, 11:52:37 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).

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: Cursor change event
« Reply #12 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

jj2007

  • Member
  • *****
  • Posts: 10110
  • Assembler is fun ;-)
    • MasmBasic
Re: Cursor change event
« Reply #13 on: December 08, 2012, 04:18:20 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.

dedndave

  • Member
  • *****
  • Posts: 8825
  • Still using Abacus 2.0
    • DednDave
Re: Cursor change event
« Reply #14 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
« Last Edit: December 15, 2012, 03:11:21 AM by dedndave »