Jump to content

  • Log In with Google      Sign In   
  • Create Account


HWND_TOP works, but HWND_TOPMOST does not


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 RonHiler   Members   -  Reputation: 214

Like
0Likes
Like

Posted 02 September 2013 - 08:27 AM

Hey guys,

 

I have a weird problem I can't figure out:

 

This code is meant to calculate a position of a window and put it there. And it pretty much works just fine, the window appears where it is supposed to be. The only issue with it is I really need the final line to make it a topmost window.

        case WM_NOTIFY:
            {
            if (wParam == MEW_TOOLTIPWINDOW || wParam == EW_TOOLTIPWINDOW)
                {
                if (((NMHDR*)lParam)->code == EN_REQUESTRESIZE)
                    {
                    ReqResize = (REQRESIZE*)lParam;
                    GetWindowRect(EnhancementWindowHandle, &WindowRect);
                    GetCursorPos(&CursorPoint);
                    X = CursorPoint.x - WindowRect.left+10;
                    Y = CursorPoint.y - WindowRect.top+10;
                    //don't fall off the bottom of the main window
                    if (Y + (ReqResize->rc.bottom - ReqResize->rc.top) > (WindowRect.bottom - WindowRect.top))
                        Y = (WindowRect.bottom - WindowRect.top) - (ReqResize->rc.bottom - ReqResize->rc.top);
                    //also, don't go past the right side of the main window
                    if (X + (ReqResize->rc.right - ReqResize->rc.left) > (WindowRect.right - WindowRect.left))
                        X = (CursorPoint.x - WindowRect.left) - (ReqResize->rc.right - ReqResize->rc.left) - 10;
                    //at this point we should be entirely inside the window, unless the text is so large the tooltip is higher than the entire window itself.
                    // TODO: Handle fringe case of too tall a tooltip window...
                    SetWindowPos(ReqResize->nmhdr.hwndFrom, HWND_TOP, X, Y, ReqResize->rc.right - ReqResize->rc.left, ReqResize->rc.bottom - ReqResize->rc.top, SWP_SHOWWINDOW);
                    }
                }
            return 0;
            }

so I changed the final line to such:

  SetWindowPos(ReqResize->nmhdr.hwndFrom, HWND_TOPMOST, X, Y, ReqResize->rc.right - ReqResize->rc.left, ReqResize->rc.bottom - ReqResize->rc.top, SWP_SHOWWINDOW);

That's the only change I made, just changed HWND_TOP to HWND_TOPMOST. And the result is the window no longer resizes or moves. It is in it's default size at parent window 0,0. The return value of the function does not indicate a failure (return is non-zero), it just doesn't do what I expect it to do.

 

I even tried forcing it to move:

  SetWindowPos(ReqResize->nmhdr.hwndFrom, HWND_TOPMOST, 100, 100, 500, 500, SWP_SHOWWINDOW);

Same thing, it is ignoring the x, y, sizex, and sizey parameters when using HWND_TOPMOST

 

Any ideas why? What am I doing wrong?


Creation is an act of sheer will

Sponsor:

#2 Endurion   Crossbones+   -  Reputation: 3329

Like
0Likes
Like

Posted 02 September 2013 - 09:38 AM

Could be a few things:

 

One:

 

If neither the SWP_NOACTIVATE nor SWP_NOZORDER flag is specified (that is, when the application requests that a window be simultaneously activated and its position in the Z order changed), the value specified in hWndInsertAfter is used only in the following circumstances.

  • Neither the HWND_TOPMOST nor HWND_NOTOPMOST flag is specified in hWndInsertAfter (doesn't apply)
  • The window identified by hWnd is not the active window.

 

Two:

 

If an application is not in the foreground, and should be in the foreground, it must call the SetForegroundWindow function.

 

 

 

Also, weirdly, I never had to mess with the TOPMOST style of a tool tip. Did you do something else with it beforehand?


Edited by Endurion, 02 September 2013 - 09:47 AM.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

#3 Cosmic314   Members   -  Reputation: 1146

Like
0Likes
Like

Posted 02 September 2013 - 09:42 AM

I'm not sure why your window moves and resizes.  You could force it to be top most without the move and resize as follows:

  SetWindowPos(ReqResize->nmhdr.hwndFrom, HWND_TOPMOST, 0, 0, 0, 0, 
               SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);



#4 RonHiler   Members   -  Reputation: 214

Like
0Likes
Like

Posted 02 September 2013 - 10:21 AM

Could be a few things:

 

One:

 

If neither the SWP_NOACTIVATE nor SWP_NOZORDER flag is specified (that is, when the application requests that a window be simultaneously activated and its position in the Z order changed), the value specified in hWndInsertAfter is used only in the following circumstances.

  • Neither the HWND_TOPMOST nor HWND_NOTOPMOST flag is specified in hWndInsertAfter (doesn't apply)
  • The window identified by hWnd is not the active window.

 

Two:

 

If an application is not in the foreground, and should be in the foreground, it must call the SetForegroundWindow function.

 

 

 

Also, weirdly, I never had to mess with the TOPMOST style of a tool tip. Did you do something else with it beforehand?

 

The application is in the foreground (it is the acive application).

 

The hwnd is the active window. But just to be sure, I modified the code:

    SetActiveWindow(ReqResize->nmhdr.hwndFrom);
    SetWindowPos(ReqResize->nmhdr.hwndFrom, HWND_TOPMOST, X, Y, ReqResize->rc.right - ReqResize->rc.left, ReqResize->rc.bottom - ReqResize->rc.top, SWP_SHOWWINDOW);

Sadly, no difference.

 

I gave this a try in place of SetWindowPos(), and it works just like HWND_TOP (even though I created the window with a WS_EX_TOPMOST flag, it's not acting as such).

MoveWindow(ReqResize->nmhdr.hwndFrom, X, Y, ReqResize->rc.right - ReqResize->rc.left, ReqResize->rc.bottom - ReqResize->rc.top, true);

 

 

I'm not sure why your window moves and resizes.  You could force it to be top most without the move and resize as follows:

  SetWindowPos(ReqResize->nmhdr.hwndFrom, HWND_TOPMOST, 0, 0, 0, 0, 
               SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);

Uh, the window is moved and resized because the purpose of the routine is to move and resize the window. I think you are misunderstanding the purpose.


Creation is an act of sheer will

#5 Cosmic314   Members   -  Reputation: 1146

Like
0Likes
Like

Posted 02 September 2013 - 10:53 AM

 

 

I'm not sure why your window moves and resizes.  You could force it to be top most without the move and resize as follows:

  SetWindowPos(ReqResize->nmhdr.hwndFrom, HWND_TOPMOST, 0, 0, 0, 0, 
               SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);

Uh, the window is moved and resized because the purpose of the routine is to move and resize the window. I think you are misunderstanding the purpose.

 

 

Sorry, I thought you called it twice.  Let me amend it.  First call with the actual size and position.  Then make a second call with the above parameters.



#6 RonHiler   Members   -  Reputation: 214

Like
0Likes
Like

Posted 02 September 2013 - 11:14 AM

Ah, gotcha.

 

It was a great idea, but still no go. With two separate calls, the window again moves and resizes, but still won't stay above other windows (one window in particular). It's the weirdest thing. The window drawing on top of it is definitely not a TopMost window. I wonder if I have an issue with painting or something. Grrrr.


Creation is an act of sheer will

#7 Cosmic314   Members   -  Reputation: 1146

Like
0Likes
Like

Posted 02 September 2013 - 11:27 AM

Another idea.  Your WM_NOTIFY will return 0 if conditions are met for your tooltip and what you're trying to do here.  However, if you receive a WM_NOTIFY that doesn't meet these conditions it will fall through to whatever code you have after the message.  That could certainly be a nasty bug.

 

Maybe you have a 'break' that you didn't post.

 

Edit: Nevermind.  I misaligned your enclosing brackets.

 

Edit edit:  Actually, this still may be a problem.  If your WM_NOTIFY receives wParam == MEW_TOOLTIPWINDOW || wParam == EW_TOOLTIPWINDOW) but does not receive:  (((NMHDR*)lParam)->code == EN_REQUESTRESIZE)

 

If those conditions are met the message never gets processed by anything because return 0 will skip the DefProcWindow call, unless you have it after your switch.


Edited by Cosmic314, 02 September 2013 - 11:37 AM.


#8 Endurion   Crossbones+   -  Reputation: 3329

Like
0Likes
Like

Posted 02 September 2013 - 11:33 PM

Is the window that's drawing over yours from your app as well?

 

Did you check with Spy++ that it does not have the wrong style set? In the end it might be two windows fighting for top-most.


Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

#9 tonemgub   Members   -  Reputation: 617

Like
2Likes
Like

Posted 03 September 2013 - 12:34 AM

If you're receiving WM_NOTIFY from the window you're trying to modify, then that's probably a child window. Child windows cannot be TOPMOST windows.

#10 RonHiler   Members   -  Reputation: 214

Like
0Likes
Like

Posted 03 September 2013 - 02:29 PM

If you're receiving WM_NOTIFY from the window you're trying to modify, then that's probably a child window. Child windows cannot be TOPMOST windows.

 

Ahhh, there it is. It's a child window alright. I didn't know they couldn't be TOPMOST.

 

Huh. Now I have to figure out a way to get it to draw where I want. Drat it.


Creation is an act of sheer will

#11 Endurion   Crossbones+   -  Reputation: 3329

Like
0Likes
Like

Posted 04 September 2013 - 12:03 AM


Huh. Now I have to figure out a way to get it to draw where I want. Drat it.

That's a case for ClientToScreen or ScreenToClient.


Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS