exebook
exebook

Reputation: 33950

WinAPI ZOrder woes

I have two windows, one smaller on top of other bigger. The window created first will always be on top. Neither BringWindowToTop(hWnd) nor SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); do nothing! I also have been trying HWND_TOPMOST and HWND_BOTTOM.

It seems the only way to make one window on top of other is a correct creation order. But this is not what I need, I need to change the order on the fly. Anyone knows what could cause this? Those are just old plain CreateWindow() instances both have the same parent. Any search on internet yields nothing. Need some expert help!

#include <windows.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

HWND make_child(HWND Parent, int x, int y, int color) {
    HINSTANCE hInstance = 0;
    MSG msg          = {0};
    WNDCLASS wc      = {0}; 
    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.hbrBackground = CreateSolidBrush(color);//(HBRUSH)(COLOR_WINDOWFRAME);
    wc.lpszClassName = (LPCSTR)L"mychildwin";
    RegisterClass(&wc);
    return CreateWindow("edit",(LPCSTR)"child", WS_BORDER|WS_CHILD|WS_VISIBLE, x,y,100,100,Parent,0,hInstance,NULL);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
    MSG msg          = {0};
    WNDCLASS wc      = {0}; 
    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.hbrBackground = CreateSolidBrush(0xff8080);
    wc.lpszClassName = (LPCSTR)L"minwindowsapp";
    if (!RegisterClass(&wc))  return 1;
    HWND W = CreateWindow(wc.lpszClassName,(LPCSTR)L"Minimal Windows Application", WS_OVERLAPPEDWINDOW|WS_VISIBLE, 0,0,640,480,0,0,hInstance,NULL);
    HWND A = make_child(W, 10, 10, 0x88ff00);
    HWND B = make_child(W, 70, 70, 0x8888ff);
    BringWindowToTop(B);
    SetWindowPos(B, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

    //REAL PROBLEM WAS HERE: A second call to SetWindowPos
     SetWindowPos(handle, 0, 0, 0, new_width, new_height,
      SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
    // adding SWP_NOZORDER fixed it..

    while(GetMessage(&msg, NULL, 0, 0) > 0) DispatchMessage(&msg);
    return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch(message) {
        case WM_CLOSE: PostQuitMessage(0); break;
        default: return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}  

Upvotes: 0

Views: 1992

Answers (2)

exebook
exebook

Reputation: 33950

Ok, maybe someone will find it really useful. Because real problem was that SetWindowPos and BringWindowToTo both worked fine, but afterwards in my real app I was calling SetWindowPos again to move the component a little, and it was screwing the ZOrder again!

So I added SWP_NOZORDER to that second call to SetWindowPos.

Upvotes: 1

bash.d
bash.d

Reputation: 13207

According to the MSDN-documentation, there is also the possibility to pass a window-handle to the window you want your window to be inserted after.

BOOL WINAPI SetWindowPos(
  _In_      HWND hWnd,
  _In_opt_  HWND hWndInsertAfter,
  _In_      int X,
  _In_      int Y,
  _In_      int cx,
  _In_      int cy,
  _In_      UINT uFlags
);

where hWndInsertAfter is the handle of the window your window shall be positioned AFTER. Have you tried this one?

Upvotes: 2

Related Questions