Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ScreenToClient strangeness

108 views
Skip to first unread message

landon

unread,
Oct 20, 2001, 4:58:19 PM10/20/01
to
I'm trying to display a custom floating tooltip window (of
STATIC class) positioned whereever the mouse goes.
However, when I use the tooltip window's ScreenToClient
function, I get two windows that flash like crazy whether
I move the mouse or not.

If I just use the Cpoint sent to OnMouseMove I get one
normal looking window, but positioned in the wrong place.

The tooltip window's ScreenToClient function appears to
generate an extra mousemove with each one that comes in
and then toggles the conversion between each, resulting in
two flashing windows in an eternal loop. This happens
even if I don't move the mouse.

Does anyone know what is going on here and how to fix it?
What am I doing wrong?

void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
ClientToScreen( &point );

m_pFlyvar->ScreenToClient( &point );

m_pFlyvar->SetWindowPos( &wndTop, point.x,
point.y, SIZE_X, SIZE_Y, SWP_NOACTIVATE|SWP_SHOWWINDOW );

// return; this doesn't change anything

CView::OnMouseMove(nFlags, point);
}

Thanks for any help,
landon

Joseph M. Newcomer

unread,
Oct 20, 2001, 7:48:08 PM10/20/01
to
There are several problems here. The most significant is that you are
converting the point to screen coordinates, then you convert those
back to coordinates *in the client coordinates of your flyover
window*, which are fairly useless for almost anything. You actually
want the coordinates of the parent of the flyover window, for example,
I would do

ClientToScreen( &point );
m_pFlyvar->GetParent()->ScreenToClient(&point);
m_pFlyVar->SetWindowPos(&wndTop, point.x, point.y, 0, 0,
SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW );

joe

On Sat, 20 Oct 2001 13:58:19 -0700, "landon" <lan...@aptech.com>
wrote:

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www3.pgh.net/~newcomer
MVP Tips: http://www3.pgh.net/~newcomer/mvp_tips.htm

landon

unread,
Oct 21, 2001, 7:14:05 PM10/21/01
to
Thanks for the reply, Joe. Have you actually tried this?

When I do, I get one flyvar window (thankfully), but it's
still in the wrong place. The ScreenToClient function
simply appears to be converting incorrectly... the output
coordinates are screen coordinates no matter where my view
window OR frame window is located.

If this isn't a bug in windows, then I'm still doing
something wrong. You have any more idea.. I'm getting
desperate.

Thanks again,
landon

>.
>

landon

unread,
Oct 21, 2001, 7:32:42 PM10/21/01
to
Ok, I figured out what I need to do. It's not completley
clear to me why but this parent/child relationship between
windows has always been a mystery. It's getting clearer
through this fairly painful experience though <g>.

I first make the flyvar window a member variable of my
frame window and create it during my CMainFrame's
OnCreate. Then in the CView's OnCreate I make this call
to set the parent of the flyvar window the cview's parent:

m_pMainWnd->m_pFlyvar->SetParent( GetParent() );

After that, no conversion is necessary in my cView's
OnMouseMove. I just do the SetWindowPos using the CPoint
coming into the OnMousove.

Whew, what a round of battles this has been. Thanks for
your help Joe.

landon

>.
>

landon

unread,
Oct 21, 2001, 11:20:47 PM10/21/01
to
Alas, still have problems. When a new View window is
created it's parent becomes the new parent of the flyvar
window. That's fine, until I active a different view.

So, in OnActivate() I set the parent again to ensure the
flyvar window is associated with the correct view:

If ( bActivate )
{


m_pMainWnd->m_pFlyvar->SetParent( GetParent() );
}

But this causes all kinds of weirdness all over again.
The frame and the child view begin taking turns becoming
active all by themselves. The app is basically hung at
this point.

I'm exhausting all efforts trying to make this work. Any
help is greatly appreciated.

landon

>.
>

Joseph M. Newcomer

unread,
Oct 22, 2001, 12:33:51 AM10/22/01
to
You shouldn't be mucking around with SetParent. Create a window in
each view. They're cheap enough that this doesn't cost anything.
Trying to save "a window" like this leads only to ugly problems such
as the ones you are seeing. For one thing, SetParent is a weird and
wondrous call that doesn't really change all the parent relationships.
It is an API call that most programmers learn to avoid. Create a
flyover window within each view, for that view and that view alone.
You aren't saving anything worthwhile doing what you are doing. (In
fact, it would never have occurred to me to do it that way).

I did exactly this a week ago, except the windows also follow the
moving object they are associated with. But (a) I can't post images on
the newsgroup and (b) it isn't clear I have permission to display
anything that I was working on yet. So I know it works.
joe
On Sun, 21 Oct 2001 20:20:47 -0700, "landon" <lan...@aptech.com>
wrote:

landon

unread,
Oct 22, 2001, 12:15:14 PM10/22/01
to
Thanks again Joe, I really appreciate the help here. Ok,
I now create a flyover with each view and perform the
exact calls as you stated in OnMouseMove:

ClientToScreen( pt );
m_WndFlyvar->GetParent()->ScreenToClient( pt );

The flyover now acts correctly within each view as it is
activated. However, the original problem still exists.
That is, though the flyover window is positioned correctly
relative to each view, it's completley ignoring the
position of the main frame window. Thus, when I move the
frame over and then move the mouse, the flyover window
follows the mouse in exactly the same positions as where
the frame was last.

Is it possible that you ran your tests in a maximized
frame window? If so, you would never have seen this
problem.

landon

>.
>

Joseph M. Newcomer

unread,
Oct 22, 2001, 3:46:37 PM10/22/01
to
You need to have your OnMove handler of each view reposition the
flyover window for the view. Since you have probably created the
windows as either WS_OVERLAPPED or WS_POPUP, they have no reason to
follow the window (and a child window would be clipped by the window
boundaries, which would probably be unacceptable).
joe

On Mon, 22 Oct 2001 09:15:14 -0700, "landon" <lan...@aptech.com>
wrote:

landon

unread,
Oct 22, 2001, 4:19:57 PM10/22/01
to
Do you mean keep a member variable around that retains the
top-left corner of the frame at all times (updated with
each OnMove)?

Ah yes, I see now. I was being stubborn in expecting the
View's ScreenToClient to adjust based on both it and the
frame window. (I guess I still think it's resonable but
time will likely help me see clearer).

This works perfectly Joe. Many thanks for not giving up
on me!

landon

>.
>

Joseph M. Newcomer

unread,
Oct 22, 2001, 5:21:25 PM10/22/01
to
Yes, have it keep the position relative to the client area of its
parent. In the OnMove, simply do a SetWindowPos using that same value
and the window should change to be correct. You will probably need to
do the same thing in the OnSize handler, or better still, have your
flyover toolip keep its own information and call its Reposition
method, which you can define. This puts the knowledge where it
belongs, in the object itself.
joe

On Mon, 22 Oct 2001 13:19:57 -0700, "landon" <lan...@aptech.com>
wrote:

0 new messages