HWND_TOP works, but HWND_TOPMOST does not

Started by
9 comments, last by Endurion 10 years, 7 months ago

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
Advertisement

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?

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

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);

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

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.

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

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.

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>

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.

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

This topic is closed to new replies.

Advertisement