how to get position of cursor in EDIT control?? - Programmer

This is a discussion on how to get position of cursor in EDIT control?? - Programmer ; How does one get the position of the cursor in an edit control? I am not talking about the mouse cursor and that is what GetCaretPos() and GetCursorPos() do. I am talking about the blinking vertical line. There doesn't seem ...

+ Reply to Thread
Page 1 of 2 1 2 LastLast
Results 1 to 20 of 23

Thread: how to get position of cursor in EDIT control??

  1. how to get position of cursor in EDIT control??

    How does one get the position of the cursor in an edit control? I am not
    talking about the mouse cursor and that is what GetCaretPos() and
    GetCursorPos() do. I am talking about the blinking vertical line. There
    doesn't seem to be any way to get it?? I want to be able to get it in client
    or screen coordinates. Thanks!



  2. Re: how to get position of cursor in EDIT control??

    "Nobody" wrote in message
    news:dpbwb.10587$Bk1.14@fed1read05...
    > How does one get the position of the cursor in an edit control? I am not
    > talking about the mouse cursor and that is what GetCaretPos() and
    > GetCursorPos() do. I am talking about the blinking vertical line. There
    > doesn't seem to be any way to get it?? I want to be able to get it in

    client
    > or screen coordinates. Thanks!


    I participated in a thread about this a couple of weeks ago...

    http://www.google.com/groups?hl=en&l....phx.gbl#link7

    ....it wasn't you asking this back then was it? In any event, if you have a
    repro scenario wherein GetCaretPos is broken, I would love to see it and
    have MS look into it. As I said, AFAIK, GetCaretPos is the one and only API
    provided for this.

    --
    Jeff Partch [VC++ MVP]



  3. Re: how to get position of cursor in EDIT control??

    No it wasn't me... I checked out the thread and like the other poster said,
    GetCaretPos and GetCursorPos return the same values. I am running on XP with
    comctl6 if that makes a difference.

    I did however find a different function a few moments ago that returns the
    correct position. GetGUIThreadInfo does the trick.

    "Jeff Partch [MVP]" wrote in message
    news:eSD9pCisDHA.3224@tk2msftngp13.phx.gbl...
    > "Nobody" wrote in message
    > news:dpbwb.10587$Bk1.14@fed1read05...
    > > How does one get the position of the cursor in an edit control? I am not
    > > talking about the mouse cursor and that is what GetCaretPos() and
    > > GetCursorPos() do. I am talking about the blinking vertical line. There
    > > doesn't seem to be any way to get it?? I want to be able to get it in

    > client
    > > or screen coordinates. Thanks!

    >
    > I participated in a thread about this a couple of weeks ago...
    >
    >

    http://www.google.com/groups?hl=en&l....phx.gbl#link7
    >
    > ...it wasn't you asking this back then was it? In any event, if you have a
    > repro scenario wherein GetCaretPos is broken, I would love to see it and
    > have MS look into it. As I said, AFAIK, GetCaretPos is the one and only

    API
    > provided for this.
    >
    > --
    > Jeff Partch [VC++ MVP]
    >
    >




  4. Re: how to get position of cursor in EDIT control??

    By the way, I had subclassed an edit control and was calling this when I got
    a EM_SHOWBALLOONTIP message.

    "Nobody" wrote in message
    news:bgcwb.11124$Bk1.3290@fed1read05...
    > No it wasn't me... I checked out the thread and like the other poster

    said,
    > GetCaretPos and GetCursorPos return the same values. I am running on XP

    with
    > comctl6 if that makes a difference.
    >
    > I did however find a different function a few moments ago that returns the
    > correct position. GetGUIThreadInfo does the trick.
    >
    > "Jeff Partch [MVP]" wrote in message
    > news:eSD9pCisDHA.3224@tk2msftngp13.phx.gbl...
    > > "Nobody" wrote in message
    > > news:dpbwb.10587$Bk1.14@fed1read05...
    > > > How does one get the position of the cursor in an edit control? I am

    not
    > > > talking about the mouse cursor and that is what GetCaretPos() and
    > > > GetCursorPos() do. I am talking about the blinking vertical line.

    There
    > > > doesn't seem to be any way to get it?? I want to be able to get it in

    > > client
    > > > or screen coordinates. Thanks!

    > >
    > > I participated in a thread about this a couple of weeks ago...
    > >
    > >

    >

    http://www.google.com/groups?hl=en&l....phx.gbl#link7
    > >
    > > ...it wasn't you asking this back then was it? In any event, if you have

    a
    > > repro scenario wherein GetCaretPos is broken, I would love to see it and
    > > have MS look into it. As I said, AFAIK, GetCaretPos is the one and only

    > API
    > > provided for this.
    > >
    > > --
    > > Jeff Partch [VC++ MVP]
    > >
    > >

    >
    >




  5. Re: how to get position of cursor in EDIT control??

    Jeff,

    This whole issue is only a part of a bigger problem I was having with a bug
    in XP that you might want to point out to MS.

    Basically, if you have an edit control with the ES_NUMBER on XP and you type
    an invalid character like a letter, etc. XP shows a balloon tooltip telling
    you only numbers are acceptable through the EM_SHOWBALLOONTIP message. I
    think its a nifty little thing.

    Anyways, there is a huge bug in there somewhere that causes whole dialogs
    and windows to redraw like mad.

    For example, stick an edit control on a property sheet, give it the
    ES_NUMBER style, then hold down the 'A' key and the entire property sheet
    will flicker like crazy.

    My original question was in an attempt to fix this bug. I ended up fixing it
    in a completely different way that is pretty dirty, but gets the job done.

    After some ugly detective work, it seems there are many bugs involved here:

    1) the edit control or the tooltip is calling InvalidateRect with erase =
    TRUE on the parent or grandparent of the edit control (the property sheet in
    my example). I have proven a single InvalidateRect is getting called by
    hooking that function.

    2) the balloon tooltip is getting destroyed and recreated when it is still
    visible on the screen (more flicker). Ie when you hold down the 'A' key as
    in my example, the control keeps getting destroyed and recreated instead of
    getting left on the screen.

    3) The themed property sheet and/or dialogs dont handle this message very
    nicely.

    Unfortunately I can not post the code to my fix because portions are
    copyrighted... but the basic concept of it is:

    1) subclass the edit control
    2) trap EM_SHOWBALLOONTIP, if the the tooltip is currently visible on the
    screen, disregard this message, otherwise pass it to the original wndproc.
    3) trap EM_HIDEBALLOONTIP and set a flag to TRUE before calling the
    original wndproc.
    4) when this flag is TRUE, block the next InvalidateRect call and set flag
    to FALSE.

    this will prevent the balloon tooltip from getting destroyed/recreated all
    the time and will kill the flicker caused by when it is hidden.

    note: with my fix there is one obvious bug here in that if an edit control
    has multiple different tips, you will not get updated on the screen if there
    is one already there.

    I guess I can save the last tip and compare them when I get
    EM_SHOWBALLOONTIP messages to see if it is the same one.

    "Jeff Partch [MVP]" wrote in message
    news:eSD9pCisDHA.3224@tk2msftngp13.phx.gbl...
    > "Nobody" wrote in message
    > news:dpbwb.10587$Bk1.14@fed1read05...
    > > How does one get the position of the cursor in an edit control? I am not
    > > talking about the mouse cursor and that is what GetCaretPos() and
    > > GetCursorPos() do. I am talking about the blinking vertical line. There
    > > doesn't seem to be any way to get it?? I want to be able to get it in

    > client
    > > or screen coordinates. Thanks!

    >
    > I participated in a thread about this a couple of weeks ago...
    >
    >

    http://www.google.com/groups?hl=en&l....phx.gbl#link7
    >
    > ...it wasn't you asking this back then was it? In any event, if you have a
    > repro scenario wherein GetCaretPos is broken, I would love to see it and
    > have MS look into it. As I said, AFAIK, GetCaretPos is the one and only

    API
    > provided for this.
    >
    > --
    > Jeff Partch [VC++ MVP]
    >
    >




  6. Re: how to get position of cursor in EDIT control??

    "Nobody" wrote in message
    news:shcwb.11138$Bk1.9757@fed1read05...
    > "Nobody" wrote in message
    > news:bgcwb.11124$Bk1.3290@fed1read05...
    > > No it wasn't me... I checked out the thread and like the other poster

    > said,
    > > GetCaretPos and GetCursorPos return the same values. I am running on XP

    > with
    > > comctl6 if that makes a difference.
    > >
    > > I did however find a different function a few moments ago that returns

    the
    > > correct position. GetGUIThreadInfo does the trick.

    > By the way, I had subclassed an edit control and was calling this when I

    got
    > a EM_SHOWBALLOONTIP message.
    >


    Ahh, GetGUIThreadInfo -- learn something new every day. I'm still curious
    why GetCaretPos works for me, and not you two guys. Is there anything
    special about the nature of your implementation: cross-thread,
    cross-process, some sort of hook? What do you pass as the 'idThread'
    parameter? I'm probably not smart enough to understand it, but if an
    explanation can be had, I'd welcome it. And whatever the reason, it seems
    like there ought to be some sort of remark in the GetCaretPos documentation.
    --
    Jeff Partch [VC++ MVP]



  7. Re: how to get position of cursor in EDIT control??

    "Nobody" wrote in message
    news:Wqdwb.11649$Bk1.1112@fed1read05...
    > Jeff,
    >
    > This whole issue is only a part of a bigger problem I was having with a

    bug
    > in XP that you might want to point out to MS.
    >
    > Basically, if you have an edit control with the ES_NUMBER on XP and you

    type
    > an invalid character like a letter, etc. XP shows a balloon tooltip

    telling
    > you only numbers are acceptable through the EM_SHOWBALLOONTIP message. I
    > think its a nifty little thing.
    >
    > Anyways, there is a huge bug in there somewhere that causes whole dialogs
    > and windows to redraw like mad.
    >
    > For example, stick an edit control on a property sheet, give it the
    > ES_NUMBER style, then hold down the 'A' key and the entire property sheet
    > will flicker like crazy.


    Thanks, N. That is horrible. I was able to repro it in seconds. It seems
    like every week, some new theme related behavior (bug) comes up. FWIW, I'll
    definitely pass it on to MS.
    --
    Jeff Partch [VC++ MVP]



  8. Re: how to get position of cursor in EDIT control??

    Nope, it was a straight MFC dialog application straight out of the wizard
    (with the comctl 6.0 manifest). I threw an edit control on the dialog,
    subclassed it (of the SetWindowLong(GWL_WNDPROC) variety) and called
    GetCaretPos when I got EM_SHOWBALLOONTIP messages.

    I'm running VS 2003.NET on XP with all the latest patches.

    For the GetGUIThreadInfo, I am passing in the result of GetCurrentThreadId()
    which assumes you are calling the function from your main GUI thread. You
    can also pass in 0 and it will assume you want the foreground thread which
    is OK I guess, since you'll only ever have one caret active at a time and
    that'll be in the foreground thread.


    > Ahh, GetGUIThreadInfo -- learn something new every day. I'm still

    curious
    > why GetCaretPos works for me, and not you two guys. Is there anything
    > special about the nature of your implementation: cross-thread,
    > cross-process, some sort of hook? What do you pass as the 'idThread'
    > parameter? I'm probably not smart enough to understand it, but if an
    > explanation can be had, I'd welcome it. And whatever the reason, it seems
    > like there ought to be some sort of remark in the GetCaretPos

    documentation.



  9. Re: how to get position of cursor in EDIT control??

    "Nobody" wrote in message
    news:wcewb.11945$Bk1.5185@fed1read05...
    > Nope, it was a straight MFC dialog application straight out of the wizard
    > (with the comctl 6.0 manifest). I threw an edit control on the dialog,
    > subclassed it (of the SetWindowLong(GWL_WNDPROC) variety) and called
    > GetCaretPos when I got EM_SHOWBALLOONTIP messages.
    >
    > I'm running VS 2003.NET on XP with all the latest patches.
    >
    > For the GetGUIThreadInfo, I am passing in the result of

    GetCurrentThreadId()
    > which assumes you are calling the function from your main GUI thread. You
    > can also pass in 0 and it will assume you want the foreground thread which
    > is OK I guess, since you'll only ever have one caret active at a time and
    > that'll be in the foreground thread.


    That seems pretty straightforward. I don't recall whether I ran my test with
    a manifest or not (probably not as CEditView is broken with a manifest), but
    I'll try it again later using your description. After looking at it though,
    the only difference I can see in the implementation of GetGUIThreadInfo and
    GetCaretPos is when the calling thread is different than the thread that
    created the caret window *and* the window has the CS_OWNDC style. Is that
    latter condition ever true for an EDIT control? Otherwise, they both seem to
    pull the caret's x & y from the same place in the same way (and which is
    seemingly not the same place GetCursorPos gets its position from). I might
    have to try and recruit some help from the brain-trust on this one.
    --
    Jeff Partch [VC++ MVP]



  10. Re: how to get position of cursor in EDIT control??

    "Nobody" wrote in message
    news:wcewb.11945$Bk1.5185@fed1read05...
    > Nope, it was a straight MFC dialog application straight out of the wizard
    > (with the comctl 6.0 manifest). I threw an edit control on the dialog,
    > subclassed it (of the SetWindowLong(GWL_WNDPROC) variety) and called
    > GetCaretPos when I got EM_SHOWBALLOONTIP messages.
    >
    > I'm running VS 2003.NET on XP with all the latest patches.
    >
    > For the GetGUIThreadInfo, I am passing in the result of

    GetCurrentThreadId()
    > which assumes you are calling the function from your main GUI thread. You
    > can also pass in 0 and it will assume you want the foreground thread which
    > is OK I guess, since you'll only ever have one caret active at a time and
    > that'll be in the foreground thread.


    Okay, I've got the VC2003 wizard generated dialog app with a manifest
    running on XPSP1 and all critical updates. I subclass the ES_NUMBER edit
    control using SetWindowLong and this WNDPROC...

    LRESULT
    CALLBACK
    EditSubclassProc(
    HWND hWnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
    )
    {
    LRESULT lRet = 0;
    switch (uMsg)
    {
    case EM_SHOWBALLOONTIP:
    {
    POINT pointCaret, pointCursor;
    if (GetCaretPos(&pointCaret) &&
    GetCursorPos(&pointCursor))
    {
    TRACE(_T("Caret (%d, %d) : Cursor (%d, %d)\n"),
    pointCaret.x, pointCaret.y,
    pointCursor.x, pointCursor.y);
    GUITHREADINFO gti;
    gti.cbSize = sizeof(gti);
    if (GetGUIThreadInfo(
    GetCurrentThreadId(), &gti))
    {
    TRACE(_T("\tGui (%d, %d)\n"),
    gti.rcCaret.left, gti.rcCaret.top);
    }
    }
    // Fall through
    }
    default:
    {
    lRet = CallWindowProc(
    (WNDPROC)(LONG_PTR)GetClassLongPtr(
    hWnd, GCLP_WNDPROC), hWnd, uMsg,
    wParam, lParam);
    }
    }
    return lRet;
    }

    ....and in the trace output I get this...

    Caret (4, 1) : Cursor (439, 207)
    Gui (4, 1)

    ....GetCaretPos and GetGUIThreadInfo return the same position and not what
    GetCursorPos is returning. What are we doing differently?

    --
    Jeff Partch [VC++ MVP]



  11. Re: how to get position of cursor in EDIT control??

    Well darn it! After I resolved my flicker problem, I deleted my test
    project... I just tried to recreate it.. subclass the edit control, etc in
    the same way that I did before and now GetCaretPos is working. Weird!
    Obviously there is something here because I am not the only person who has
    run into this, but I don't know what caused it and I can't recreate it .
    On the other hand, it could have been a bug in the sample somewhere... too
    bad I deleted it... oops.



    "Jeff Partch [MVP]" wrote in message
    news:edF8JcjsDHA.536@tk2msftngp13.phx.gbl...
    > "Nobody" wrote in message
    > news:wcewb.11945$Bk1.5185@fed1read05...
    > > Nope, it was a straight MFC dialog application straight out of the

    wizard
    > > (with the comctl 6.0 manifest). I threw an edit control on the dialog,
    > > subclassed it (of the SetWindowLong(GWL_WNDPROC) variety) and called
    > > GetCaretPos when I got EM_SHOWBALLOONTIP messages.
    > >
    > > I'm running VS 2003.NET on XP with all the latest patches.
    > >
    > > For the GetGUIThreadInfo, I am passing in the result of

    > GetCurrentThreadId()
    > > which assumes you are calling the function from your main GUI thread.

    You
    > > can also pass in 0 and it will assume you want the foreground thread

    which
    > > is OK I guess, since you'll only ever have one caret active at a time

    and
    > > that'll be in the foreground thread.

    >
    > That seems pretty straightforward. I don't recall whether I ran my test

    with
    > a manifest or not (probably not as CEditView is broken with a manifest),

    but
    > I'll try it again later using your description. After looking at it

    though,
    > the only difference I can see in the implementation of GetGUIThreadInfo

    and
    > GetCaretPos is when the calling thread is different than the thread that
    > created the caret window *and* the window has the CS_OWNDC style. Is that
    > latter condition ever true for an EDIT control? Otherwise, they both seem

    to
    > pull the caret's x & y from the same place in the same way (and which is
    > seemingly not the same place GetCursorPos gets its position from). I might
    > have to try and recruit some help from the brain-trust on this one.
    > --
    > Jeff Partch [VC++ MVP]
    >
    >




  12. Re: how to get position of cursor in EDIT control??

    As I said in another post in the thread... my bad... after I got rid of the
    flicker in the balloon tip thing, I deleted the test project. I tried to
    re-create it, but I couldn't get the wrong GetCaretPos() this time. Usually
    my test projects are messy and sloppy and quickly done until I solve the
    problem... I'm thinking perhaps I messed it up somewhere... but that
    doesn't explain what happened with the other guy.

    I could have sworn I went over the GetCaretPos() portion of the code with a
    fine tooth comb, but maybe not...

    Sorry for wasting your time on this...


    "Jeff Partch [MVP]" wrote in message
    news:u8yVc9jsDHA.3436@tk2msftngp13.phx.gbl...
    > "Nobody" wrote in message
    > news:wcewb.11945$Bk1.5185@fed1read05...
    > > Nope, it was a straight MFC dialog application straight out of the

    wizard
    > > (with the comctl 6.0 manifest). I threw an edit control on the dialog,
    > > subclassed it (of the SetWindowLong(GWL_WNDPROC) variety) and called
    > > GetCaretPos when I got EM_SHOWBALLOONTIP messages.
    > >
    > > I'm running VS 2003.NET on XP with all the latest patches.
    > >
    > > For the GetGUIThreadInfo, I am passing in the result of

    > GetCurrentThreadId()
    > > which assumes you are calling the function from your main GUI thread.

    You
    > > can also pass in 0 and it will assume you want the foreground thread

    which
    > > is OK I guess, since you'll only ever have one caret active at a time

    and
    > > that'll be in the foreground thread.

    >
    > Okay, I've got the VC2003 wizard generated dialog app with a manifest
    > running on XPSP1 and all critical updates. I subclass the ES_NUMBER edit
    > control using SetWindowLong and this WNDPROC...
    >
    > LRESULT
    > CALLBACK
    > EditSubclassProc(
    > HWND hWnd,
    > UINT uMsg,
    > WPARAM wParam,
    > LPARAM lParam
    > )
    > {
    > LRESULT lRet = 0;
    > switch (uMsg)
    > {
    > case EM_SHOWBALLOONTIP:
    > {
    > POINT pointCaret, pointCursor;
    > if (GetCaretPos(&pointCaret) &&
    > GetCursorPos(&pointCursor))
    > {
    > TRACE(_T("Caret (%d, %d) : Cursor (%d, %d)\n"),
    > pointCaret.x, pointCaret.y,
    > pointCursor.x, pointCursor.y);
    > GUITHREADINFO gti;
    > gti.cbSize = sizeof(gti);
    > if (GetGUIThreadInfo(
    > GetCurrentThreadId(), &gti))
    > {
    > TRACE(_T("\tGui (%d, %d)\n"),
    > gti.rcCaret.left, gti.rcCaret.top);
    > }
    > }
    > // Fall through
    > }
    > default:
    > {
    > lRet = CallWindowProc(
    > (WNDPROC)(LONG_PTR)GetClassLongPtr(
    > hWnd, GCLP_WNDPROC), hWnd, uMsg,
    > wParam, lParam);
    > }
    > }
    > return lRet;
    > }
    >
    > ...and in the trace output I get this...
    >
    > Caret (4, 1) : Cursor (439, 207)
    > Gui (4, 1)
    >
    > ...GetCaretPos and GetGUIThreadInfo return the same position and not what
    > GetCursorPos is returning. What are we doing differently?
    >
    > --
    > Jeff Partch [VC++ MVP]
    >
    >




  13. Re: how to get position of cursor in EDIT control??

    "Nobody" wrote in message
    news:SSgwb.12275$Bk1.3627@fed1read05...
    > As I said in another post in the thread... my bad... after I got rid of

    the
    > flicker in the balloon tip thing, I deleted the test project. I tried to
    > re-create it, but I couldn't get the wrong GetCaretPos() this time.

    Usually
    > my test projects are messy and sloppy and quickly done until I solve the
    > problem... I'm thinking perhaps I messed it up somewhere... but that
    > doesn't explain what happened with the other guy.
    >
    > I could have sworn I went over the GetCaretPos() portion of the code with

    a
    > fine tooth comb, but maybe not...
    >
    > Sorry for wasting your time on this...


    No problem. Like you, I think it's compelling that two different separately
    people posted the same issue.
    --
    Jeff Partch [VC++ MVP]



  14. Re: how to get position of cursor in EDIT control??

    On Sun, 23 Nov 2003 15:29:10 -0800, "Nobody" wrote:

    >How does one get the position of the cursor in an edit control? I am not
    >talking about the mouse cursor and that is what GetCaretPos() and
    >GetCursorPos() do. I am talking about the blinking vertical line. There
    >doesn't seem to be any way to get it?? I want to be able to get it in client
    >or screen coordinates. Thanks!


    EM_GETSEL will return location of the vertical line, but in text
    postion, not screen coordinates. So it doesn't solve the problem you
    pose. I mention it just in case it helps solve the problem behind the
    one you pose.

    >
    >


    -----------------------------------------
    To reply to me, remove the underscores (_) from my email address (and please indicate which newsgroup and message).

    Robert E. Zaret
    PenFact, Inc.
    500 Harrison Ave., Suite 3R
    Boston, MA 02118
    www.penfact.com

  15. Re: how to get position of cursor in EDIT control??

    "Nobody" wrote in message
    news:Wqdwb.11649$Bk1.1112@fed1read05...
    > Jeff,
    >
    > This whole issue is only a part of a bigger problem I was having with a

    bug
    > in XP that you might want to point out to MS.
    >
    > Basically, if you have an edit control with the ES_NUMBER on XP and you

    type
    > an invalid character like a letter, etc. XP shows a balloon tooltip

    telling
    > you only numbers are acceptable through the EM_SHOWBALLOONTIP message. I
    > think its a nifty little thing.
    >
    > Anyways, there is a huge bug in there somewhere that causes whole dialogs
    > and windows to redraw like mad.
    >


    I've looked into this issue a bit further, and all of the points you make
    about its implementation prove true. It is not clear to me whether the thing
    invalidates and updates its entire parent rect for a reason, but it seems
    more like just taking the easy way out rather than a thoughtful solution. In
    any case, the result is quite unpleasant. One fly in the ointment that is
    your sketch of a workaround is that it appears that all of this is done in a
    local helper function (the same one that EM_HIDEBALLOONTIP forwards to),
    that is called directly as a subroutine. If this is true, then it bypasses
    your subclass interception completely. I like the relative simplicity of
    your solution though. One other thing I tried that seems a possible
    alternative is to give the dialog the WS_CLIPCHILDREN style. This eliminates
    the flicker, but at least two control types -- the groupbox and the
    CBS_SIMPLE style combobox have documented trouble with it...

    http://support.microsoft.com/default...Ben-us%3B79982
    http://support.microsoft.com/default...en-us%3B128110

    ....and there well may be others. What I did was EnumChildWindows in
    WM_INITDIALOG, and subclass the groupbox and simple combos (personally, I
    never seem to use these combos) with a WindowProc that handles WM_ERASEBKGND
    by SelectObject'ing a GetClientRect/hWndParent-sized CreateCompatibleBitmap
    into a CreateCompatibleDC, SendMessage'ing a WM_ERASEBKGND to the parent
    with this memory dc in the WPARAM, and then BitBlt'ing the control's portion
    of it to the source dc from the control's GetWindowRect/ScreenToClient
    coords before falling through to the default handler. This of course
    requires that the parent does all of its painting in response to
    WM_ERASEBKGND, which is what the WC_DIALOG class does by default. It just
    sounds more complicated than it really is.

    --
    Jeff Partch [VC++ MVP]



  16. Re: how to get position of cursor in EDIT control??

    Jeff,

    Thanks for looking into this...

    My thoughts on this are is that there is no reason to invalidate anything.
    The OS will automatically invalidate the correct areas when windows are
    shown and/or hidden. On the surface, blocking the InvalidateRect caused no
    side effects, but as a long time GUI developer, I know this things sometimes
    come back to bite you down the line

    Let me try to explain my work around a little more:

    1) subclass the edit control to MyEditHookProc() (lives in test.exe)

    2) in MyEditHookProc()

    trap EM_SHOWBALLOONTIP message
    if tooltip is visible, return 1, else pass message to original
    wndproc

    trap EM_HIDEBALLOONTIP message
    bBlockInvalidateRect = TRUE, pass message to original wndproc

    trap WM_KEYDOWN message
    if tooltip is visible AND key is invalid, return 0, else pass to
    original
    wndproc. I had to do the key checking in WM_KEYDOWN too
    because this is the handler that hides the balloon tip.

    3) Using an API hooking class, I install a hook for InvalidateRect() called
    MyInvalidateRect()

    if bBlockInvalidateRect == TRUE
    return TRUE
    else
    call original function

    4) My "IsToolTipVisible" function is kind of a hack, basically, I use
    EnumWindows to enumerate the top level windows and look for tooltip windows.
    Due to the location of the calls to this function, I am assuming that if
    there is a visible tooltip control, then it is the balloon tip. I guess
    there can be a few situations where there are multiple visible tooltips
    though.

    This all seems to be working...

    Are you sure you read the code correctly? it seemed to me that Windows was
    internally sending an EM_HIDEBALLOONTIP message when ever it hides the tip
    instead of calling the local helper function directly. Is this not the case?

    I put traces in the EM_HIDEBALLOONTIP handler and it is getting called when
    the tooltip is hidden.

    P.S. here is another one for you

    1) put a tree control on a property sheet
    2) give it the TVS_DISABLEDRAGDROP | TVS_FULLROWSELECT style
    3) add some items to it, expand everything so you can fill up as much of the
    window as possible to see the effect.
    4) position your property sheet on the screen in such a a way that when you
    open the start menu, the start menu will overlap the tree control by maybe
    1/4" or 1/2" or whatever.
    5) open the start menu
    6) now WITHOUT closing the start menu or alt-tabbing etc. click on the tree
    control in such a way that the selected item changes.

    Voila, the start menu will close, the selected item will change, but you
    will be missing everything that was under the start menu! . This is not
    only with the start menu, but pretty much with any window that overlaps the
    tree control.

    If you take off the disabledragdrop style this problem goes away, but that
    is because the item selection no longer changes on WM_LBUTTONDOWN, but
    rather WM_LBUTTONUP. Weird little bug, the property sheet page is painting
    through the tree control. I duplicated this with a stock tree control.

    A side note, it appears the non-client area is getting repainted, just not
    the client area. You can InvalidateRect() in TVN_SELCHANGE til you are blue
    in the face and it wont repaint in this situation . A simple fix was to
    InvalidateRect() in the WM_NCPAINT handler.

    Another sidenote, paint messages are gotten just fine, its just getting
    garbled somewhere along the line.

    > I've looked into this issue a bit further, and all of the points you make
    > about its implementation prove true. It is not clear to me whether the

    thing
    > invalidates and updates its entire parent rect for a reason, but it seems
    > more like just taking the easy way out rather than a thoughtful solution.

    In
    > any case, the result is quite unpleasant. One fly in the ointment that is
    > your sketch of a workaround is that it appears that all of this is done in

    a
    > local helper function (the same one that EM_HIDEBALLOONTIP forwards to),
    > that is called directly as a subroutine. If this is true, then it bypasses
    > your subclass interception completely. I like the relative simplicity of
    > your solution though. One other thing I tried that seems a possible
    > alternative is to give the dialog the WS_CLIPCHILDREN style. This

    eliminates
    > the flicker, but at least two control types -- the groupbox and the
    > CBS_SIMPLE style combobox have documented trouble with it...
    >
    > http://support.microsoft.com/default...Ben-us%3B79982
    > http://support.microsoft.com/default...en-us%3B128110
    >
    > ...and there well may be others. What I did was EnumChildWindows in
    > WM_INITDIALOG, and subclass the groupbox and simple combos (personally, I
    > never seem to use these combos) with a WindowProc that handles

    WM_ERASEBKGND
    > by SelectObject'ing a GetClientRect/hWndParent-sized

    CreateCompatibleBitmap
    > into a CreateCompatibleDC, SendMessage'ing a WM_ERASEBKGND to the parent
    > with this memory dc in the WPARAM, and then BitBlt'ing the control's

    portion
    > of it to the source dc from the control's GetWindowRect/ScreenToClient
    > coords before falling through to the default handler. This of course
    > requires that the parent does all of its painting in response to
    > WM_ERASEBKGND, which is what the WC_DIALOG class does by default. It just
    > sounds more complicated than it really is.
    >
    > --
    > Jeff Partch [VC++ MVP]
    >
    >




  17. Re: how to get position of cursor in EDIT control??

    "Nobody" wrote in message
    news:uurw3lssDHA.2360@TK2MSFTNGP10.phx.gbl...
    > Jeff,
    >
    > Thanks for looking into this...
    >
    > My thoughts on this are is that there is no reason to invalidate anything.
    > The OS will automatically invalidate the correct areas when windows are
    > shown and/or hidden. On the surface, blocking the InvalidateRect caused no
    > side effects, but as a long time GUI developer, I know this things

    sometimes
    > come back to bite you down the line


    Like I say, it's unclear whether this was done for a reason, but I tend to
    agree with you. I do recall some years back having to to invalidate/update
    some part of the parent for some freakish reason, but think I was able to
    y'know -- narrow it down.

    >
    > Let me try to explain my work around a little more:
    >
    > 1) subclass the edit control to MyEditHookProc() (lives in test.exe)
    >
    > 2) in MyEditHookProc()
    >
    > trap EM_SHOWBALLOONTIP message
    > if tooltip is visible, return 1, else pass message to original
    > wndproc


    This handler destroys the current tooltip (if it still exists), Creates the
    new tooltip, subclasses every parent of the edit up to the desktop, and
    starts a timer to dismiss the tooltip.

    >
    > trap EM_HIDEBALLOONTIP message
    > bBlockInvalidateRect = TRUE, pass message to original wndproc


    Discussed at the end.

    >
    > trap WM_KEYDOWN message
    > if tooltip is visible AND key is invalid, return 0, else pass to
    > original
    > wndproc. I had to do the key checking in WM_KEYDOWN too
    > because this is the handler that hides the balloon tip.


    Yep, you're right. This is how the EM_HIDEBALLOONTIP gets routed through the
    WindowProc.

    >
    > 3) Using an API hooking class, I install a hook for InvalidateRect()

    called
    > MyInvalidateRect()
    >
    > if bBlockInvalidateRect == TRUE
    > return TRUE
    > else
    > call original function


    I've never taken to API hooking, but have often felt the need. Can't say
    more.

    >
    > 4) My "IsToolTipVisible" function is kind of a hack, basically, I use
    > EnumWindows to enumerate the top level windows and look for tooltip

    windows.
    > Due to the location of the calls to this function, I am assuming that if
    > there is a visible tooltip control, then it is the balloon tip. I guess
    > there can be a few situations where there are multiple visible tooltips
    > though.


    Yeah, that makes me a bit nervous too. From memory, I think calling
    GetWindowLongPtr/GWL_HWNDPARENT on the tooltip might return the HWND of the
    edit.

    >
    > This all seems to be working...


    That's all that really matters.

    >
    > Are you sure you read the code correctly? it seemed to me that Windows was
    > internally sending an EM_HIDEBALLOONTIP message when ever it hides the tip
    > instead of calling the local helper function directly. Is this not the

    case?
    >
    > I put traces in the EM_HIDEBALLOONTIP handler and it is getting called

    when
    > the tooltip is hidden.


    I thought I was, but overlooked the WM_KEYDOWN thing. Sorry about that.

    >
    > P.S. here is another one for you


    One thing at a time, N! I've archived this one for later exploration.

    --
    Jeff Partch [VC++ MVP]




  18. Re: how to get position of cursor in EDIT control??

    > Like I say, it's unclear whether this was done for a reason, but I tend to
    > agree with you. I do recall some years back having to to
    >invalidate/update
    > some part of the parent for some freakish reason, but think I was able
    >to
    > y'know -- narrow it down.


    I've seen weird things like that, like the tree view thing I mentioned.

    > > Let me try to explain my work around a little more:
    > >
    > > 1) subclass the edit control to MyEditHookProc() (lives in test.exe)
    > >
    > > 2) in MyEditHookProc()
    > >
    > > trap EM_SHOWBALLOONTIP message
    > > if tooltip is visible, return 1, else pass message to original
    > > wndproc

    >
    > This handler destroys the current tooltip (if it still exists), Creates

    the
    > new tooltip, subclasses every parent of the edit up to the desktop, and
    > starts a timer to dismiss the tooltip.


    Thats pretty weird by itself. Why would they subclass every window up to the
    desktop? That seems excessive. There are much nicer ways to tell when to
    dismiss the tip

    > > 3) Using an API hooking class, I install a hook for InvalidateRect()

    > called
    > > MyInvalidateRect()
    > >
    > > if bBlockInvalidateRect == TRUE
    > > return TRUE
    > > else
    > > call original function

    >
    > I've never taken to API hooking, but have often felt the need. Can't say
    > more.


    Yeah, API hooking is pretty dirty, I use it very sparingly. A cleaner way to
    do this would be to subclass the parent or grandparent and block the
    WM_ERASEBKGND message that way.

    I think the reason I chose to do it the API hooking way is that if the edit
    control is on a dialog, the dialog (parent) is invalidated, but if its on a
    property sheet, its the property sheet (grand parent) thats invalidated. The
    API hooking way is generic. I didn't want to have to special case out
    various parent windows and how many levels to go up.

    This is all for work I am doing on a GUI library, so I need to encapsulate
    as much as possible and require as little as possible from the user of the l
    ibrary (like adding special case WM_ERASEBKGND handlers to various places).

    So far, I have been amazingly successful at keeping all my classes and
    custom controls "plug & play" and building on top of native stuff everywhere
    so it doesn't break existing code and/or MFC.

    > >
    > > 4) My "IsToolTipVisible" function is kind of a hack, basically, I use
    > > EnumWindows to enumerate the top level windows and look for tooltip

    > windows.
    > > Due to the location of the calls to this function, I am assuming that if
    > > there is a visible tooltip control, then it is the balloon tip. I guess
    > > there can be a few situations where there are multiple visible tooltips
    > > though.

    >
    > Yeah, that makes me a bit nervous too. From memory, I think calling
    > GetWindowLongPtr/GWL_HWNDPARENT on the tooltip might return the HWND of

    the
    > edit.


    Cool, I'll check that out... if that it is the case, it'll be nicer to just
    enumerate the children of the edit control.

    Is there any exposed way (even if it is undocumented) to check if the
    tooltip is visible? undocumented messages, exported functions, round about
    ways of calling the local function, etc?



  19. Re: how to get position of cursor in EDIT control??

    "Nobody" wrote in message
    news:esW$IutsDHA.1512@TK2MSFTNGP10.phx.gbl...
    > > Yeah, that makes me a bit nervous too. From memory, I think calling
    > > GetWindowLongPtr/GWL_HWNDPARENT on the tooltip might return the HWND of

    > the
    > > edit.

    >
    > Cool, I'll check that out... if that it is the case, it'll be nicer to

    just
    > enumerate the children of the edit control.


    Well, I can't get it to work. It must be some old school concept.

    >
    > Is there any exposed way (even if it is undocumented) to check if the
    > tooltip is visible? undocumented messages, exported functions, round about
    > ways of calling the local function, etc?


    Well, my latest brainstorm is to handle the WM_NOTIFYFORMAT/NF_QUERY in the
    edit subclass. One of the very first things the common controls do when they
    get created is query their parent about this, and they pass their HWND in
    the WPARAM. The edit seem to get this from the balloontip, so it ought to be
    a simple question of is this HWND a TOOLTIPS_CLASS, and if so cache it for
    later IsWindow testing.
    --
    Jeff Partch [VC++ MVP]



  20. Re: how to get position of cursor in EDIT control??

    Upon further thought...

    Tooltips have to be WS_POPUP windows, so there isn't going to be any
    parent/child relationship between the edit control and tooltip.

    The edit control has 4 extra window bytes defined, which I guessed was a
    pointer to an internal struct. Examining the pointer, I found the handle to
    the tooltip control in there:

    LPBYTE lpb = (LPBYTE)GetWindowLong(hWndEdit, 0);
    lpb += 0x11c;

    DWORD* lpdw = (DWORD*)lpb;

    *lpdw will be non zero if the tooltip is visible.

    This is a much cleaner way then the EnumWindows, but a lot less reliable. MS
    is generally pretty good about maintaining backwards compatibility in APIs
    and structs, but since this is an internal thing, it can completely change
    in any patch or service pack or update breaking my code.

    I also put a trace in my wndproc and saw no weird messages coming through.

    "Jeff Partch [MVP]" wrote in message
    news:ObA8dfvsDHA.3436@tk2msftngp13.phx.gbl...
    > "Nobody" wrote in message
    > news:esW$IutsDHA.1512@TK2MSFTNGP10.phx.gbl...
    > > > Yeah, that makes me a bit nervous too. From memory, I think calling
    > > > GetWindowLongPtr/GWL_HWNDPARENT on the tooltip might return the HWND

    of
    > > the
    > > > edit.

    > >
    > > Cool, I'll check that out... if that it is the case, it'll be nicer to

    > just
    > > enumerate the children of the edit control.

    >
    > Well, I can't get it to work. It must be some old school concept.
    >
    > >
    > > Is there any exposed way (even if it is undocumented) to check if the
    > > tooltip is visible? undocumented messages, exported functions, round

    about
    > > ways of calling the local function, etc?

    >
    > Well, my latest brainstorm is to handle the WM_NOTIFYFORMAT/NF_QUERY in

    the
    > edit subclass. One of the very first things the common controls do when

    they
    > get created is query their parent about this, and they pass their HWND in
    > the WPARAM. The edit seem to get this from the balloontip, so it ought to

    be
    > a simple question of is this HWND a TOOLTIPS_CLASS, and if so cache it for
    > later IsWindow testing.
    > --
    > Jeff Partch [VC++ MVP]
    >
    >




+ Reply to Thread
Page 1 of 2 1 2 LastLast