Thread: win32 - how can i put a child control always on top?

  1. #1
    Registered User
    Join Date
    Aug 2013
    Posts
    451

    win32 - how can i put a child control always on top?

    how can i put a child control always on top?
    i did tryied with SetWindowPos() with HWND_TOPMOST. but i continue losing the Z-Order
    is there any message that tell me when the Z-Order was changed?

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    Did you try using the HWND_TOP value instead of HWND_TOPMOST? I use HWND_TOP and it seems to work fine.

    Also there is a window message - WM_WINDOWPOSCHANGED, which I believe is sent whenever the Z order changes.

    You can also examine the window at the top and the next in order with GetTopWindow and GetNextWindow.

    -

  3. #3
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by megafiddle View Post
    Did you try using the HWND_TOP value instead of HWND_TOPMOST? I use HWND_TOP and it seems to work fine.

    Also there is a window message - WM_WINDOWPOSCHANGED, which I believe is sent whenever the Z order changes.

    You can also examine the window at the top and the next in order with GetTopWindow and GetNextWindow.

    -
    like you see i'm doing that:
    Code:
    //tooltip class:
    const char tooltippropname[] = "propertytooltip";
    const char tooltipclassprop[] = "classtooltip";
    
    class tooltip
    {
    private:
        HWND hwnd=NULL;
        string strCaption="";
        boolean blnvisible=false;
    
        static LRESULT CALLBACK WndProcToolTip(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
        {
            WNDPROC oldproc = (WNDPROC)GetProp(GetParent(hwnd), tooltippropname);
            if (oldproc == NULL)
                MessageBox(NULL, "Can't find old procedure", "error", MB_OK | MB_ICONEXCLAMATION);
    
            //add the instance class to inst pointer
            tooltip *inst = (tooltip*)GetProp(hwnd, tooltipclassprop);
            if (inst == NULL || msg == WM_NCCREATE)
            {
                inst = (tooltip*)(((LPCREATESTRUCT)lParam)->lpCreateParams);
                SetProp(hwnd, tooltipclassprop, (HANDLE)inst);
    
            }
            if (inst == NULL)
                MessageBox(NULL, "Can't find the instance pointer", "error", MB_OK);
    
            switch(msg)
            {
                case WM_WINDOWPOSCHANGED:
                {
                    if(IsWindowVisible(inst->hwnd)==true)
                    {
                        SetWindowPos(inst->hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
                        SetFocus(inst->hwnd);
                    }
    
                }
                break;
    
                case WM_ERASEBKGND:
                {
                    return TRUE;
                }
                break;
    
                case WM_PAINT:
                {
                    PAINTSTRUCT  ps;
                    BeginPaint(inst->hwnd, &ps);
                    HTHEME hTheme = OpenThemeData(inst->hwnd, L"TOOLTIP");
                    image imgtooltip(ps.rcPaint.right-ps.rcPaint.left,ps.rcPaint.bottom-ps.rcPaint.top);
                    DrawThemeBackground(hTheme,imgtooltip,    TTP_STANDARD , TTSS_NORMAL,&ps.rcPaint, &ps.rcPaint);
                    RECT a=ps.rcPaint;
                    a.left=a.left+3;
                    DrawThemeText(hTheme, imgtooltip, TTP_STANDARD , TTSS_NORMAL, towstring(inst->strCaption).c_str(),-1,DT_LEFT|DT_HIDEPREFIX,0,&a);
                    CloseThemeData(hTheme);
                    region n(imgtooltip, GetPixel(imgtooltip,0,0));
                    SetWindowRgn(inst->hwnd,NULL,TRUE);
                    SetWindowRgn(inst->hwnd,n,TRUE);
                    //BitBlt(ps.hdc,0,0,ps.rcPaint.right-ps.rcPaint.left,ps.rcPaint.bottom-ps.rcPaint.top,imgtooltip,0,0,SRCCOPY);
                    TransparentBlt(ps.hdc,0,0,ps.rcPaint.right-ps.rcPaint.left,ps.rcPaint.bottom-ps.rcPaint.top,imgtooltip,0,0,ps.rcPaint.right-ps.rcPaint.left,ps.rcPaint.bottom-ps.rcPaint.top, GetPixel(imgtooltip,0,0));
                    EndPaint(inst->hwnd, &ps);
                }
                break;
    
                case WM_RBUTTONUP:
                {
                    ShowWindow(inst->hwnd, FALSE);
                    RECT b;
                    GetWindowRect(GetParent(inst->hwnd),&b);
                    InvalidateRect(GetParent(inst->hwnd),&b,TRUE);
                }
                break;
            }
            return DefWindowProc(hwnd, msg, wParam, lParam);
        }
    
        void setParent(HWND parent=WindowMain)
        {
            if (hwnd==NULL)
            {
                WNDCLASS tooltipclass;
                HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);
    
                ZeroMemory(&tooltipclass, sizeof(WNDCLASS));
                GetClassInfo(mod, TEXT("BUTTON"), &tooltipclass);
    
                tooltipclass.hInstance = mod;
                tooltipclass.lpszClassName = TEXT("tooltip");
                tooltipclass.style=CS_DBLCLKS | CS_DROPSHADOW;
    
    
                // store the old WNDPROC of the button window class
                SetProp(parent, tooltippropname, (HANDLE)tooltipclass.lpfnWndProc);
                // replace it with local WNDPROC
    
                tooltipclass.lpfnWndProc = WndProcToolTip;
                tooltipclass.hbrBackground = (HBRUSH) GetStockBrush(NULL_BRUSH);
    
                // register the new window class"
                RegisterClass(&tooltipclass);
    
                hwnd = CreateWindowEx(
                    WS_EX_TOPMOST,
                    TEXT("tooltip"),//these must be the same of  ButtonClass.lpszClassName.. registed class
                    strCaption.c_str(),
                    BS_OWNERDRAW |WS_TABSTOP| BS_NOTIFY | WS_CHILD, //onerdraw for add images
                    CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
                    parent,
                    0,
                    mod,
                    this);
    
                if (hwnd == NULL)
                    MessageBox(NULL, "Can't create the control", "error", MB_OK);
    
                if (SetProp(hwnd, tooltipclassprop, (HANDLE)this) == 0)
                    MessageBox(NULL, "can't set the class property", "error", MB_OK);
                RECT textrect={0};
                HDC txthdc=GetDC(hwnd);
                DrawText (txthdc,strCaption.c_str(),-1,&textrect,DT_CALCRECT);
                SetWindowPos(hwnd, HWND_TOP, 0, 0, textrect.right-textrect.left, textrect.bottom, SWP_NOMOVE | SWP_FRAMECHANGED | SWP_HIDEWINDOW);
                RECT d;
                GetClientRect(hwnd,&d);
                InvalidateRect(hwnd,&d,TRUE);
            }
            else
            {
                SetParent(hwnd,parent);
            }
        }
    
    public:
        ~tooltip()
        {
            DestroyWindow(hwnd);
        }
    
        tooltip(string text="")
        {
            strCaption=text;
            setParent();
            if(hwnd==NULL)
                MessageBox(NULL,"error","error", MB_OK);
        }
    
        property<boolean> visible
        {
            Get(boolean)
            {
                return blnvisible;
            },
            Set(boolean blnVisible)
            {
                blnvisible=blnVisible;
                if (blnvisible==true)
                {
                    ShowWindow(hwnd,TRUE);
                    RECT d;
                    GetClientRect(hwnd,&d);
                    InvalidateRect(hwnd,&d,TRUE);
                }
                else
                {
                    ShowWindow(hwnd,FALSE);
                    RECT b;
                    GetWindowRect(GetParent(hwnd),&b);
                    InvalidateRect(GetParent(hwnd),&b,TRUE);
                }
            }
    
        };
    
        void show(int posx, int posy)
        {
            blnvisible=true;
            RECT textrect={0};
            HDC txthdc=GetDC(hwnd);
            DrawText (txthdc,strCaption.c_str(),-1,&textrect,DT_CALCRECT);
            SetWindowPos(hwnd, HWND_TOP, posx, posy, textrect.right, textrect.bottom, SWP_NOMOVE | SWP_FRAMECHANGED);
            RECT d;
            GetClientRect(hwnd,&d);
            InvalidateRect(hwnd,&d,TRUE);
        }
    
        void show()
        {
            //Getting mouse cursor coordenates
            POINT a;
            GetCursorPos(&a);
            ScreenToClient(GetParent(hwnd),&a);
    
    
            //Getting mouse cursor size
            ICONINFO ii;
            GetIconInfo(GetCursor(), &ii);
            BITMAP bm;
            GetObject( ii.hbmColor, sizeof( bm ), &bm );
            //bm.bmHeight = ii.hbmColor ? bm.bmHeight : bm.bmHeight / 2;
            //Show the ToolTip
            blnvisible=true;
            RECT textrect={0};
            HDC txthdc=GetDC(hwnd);
            DrawText (txthdc,strCaption.c_str(),-1,&textrect,DT_CALCRECT);
            SetWindowPos(hwnd, HWND_TOP, a.x , a.y + bm.bmHeight/2 + 3, textrect.right, textrect.bottom, SWP_SHOWWINDOW| SWP_FRAMECHANGED | SWP_DRAWFRAME);
            RECT d;
            GetClientRect(hwnd,&d);
            InvalidateRect(hwnd,&d,TRUE);
        }
    
        property<string> caption
        {
            Get(string)
            {
                return strCaption;
            },
            Set(string strtext)
            {
                strCaption=strtext;
                RECT textrect={0};
                HDC txthdc=GetDC(hwnd);
                DrawText (txthdc,strCaption.c_str(),-1,&textrect,DT_CALCRECT);
                SetWindowPos(hwnd, HWND_TOP, 0, 0, textrect.right-textrect.left, textrect.bottom, SWP_NOMOVE | SWP_FRAMECHANGED);
                RECT b;
                GetWindowRect(hwnd,&b);
                InvalidateRect(hwnd,&b,TRUE);
            }
        };
    };
    the 1st time, the control is showed on top. but when the back control is drawed(wM_PAINT), i lose the top most

  4. #4
    Registered User
    Join Date
    Mar 2011
    Posts
    596
    Code:
    case WM_WINDOWPOSCHANGED:
                {
                    if(IsWindowVisible(inst->hwnd)==true)
                    {
                        SetWindowPos(inst->hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
                        SetFocus(inst->hwnd);
                    }
    
                }
                break;
    The IsWindowVisible function only tests to see if the WS_VISIBLE bit was set. If WS_VISIBLE wasn't specified, the if statement will never be true.

    -

  5. #5
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by megafiddle View Post
    Code:
    case WM_WINDOWPOSCHANGED:
                {
                    if(IsWindowVisible(inst->hwnd)==true)
                    {
                        SetWindowPos(inst->hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
                        SetFocus(inst->hwnd);
                    }
    
                }
                break;
    The IsWindowVisible function only tests to see if the WS_VISIBLE bit was set. If WS_VISIBLE wasn't specified, the if statement will never be true.

    -
    sorry but i only get lucky with these function:
    Code:
    void SetTopMost( HWND hWnd)
    {
        if(IsWindowVisible(hWnd)==TRUE)
        {
            ShowWindow(hWnd,SW_HIDE);
            ShowWindow(hWnd,SW_SHOW);
        }
    }
    and called after paint it on WM_PAINT.
    isn't a 100% because it can 'flicker' sometimes. but it's great

  6. #6
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    i resolved in diferent way :P
    i add the WS_CLIPSIBLINGS flag, when i create the control. and now i can change the Z-Order without drawing problems.
    (the WS_CLIPSIBLINGS flag is for child controls and the WS_CLIPCHILDREN flag is for parent control)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. [win32] - how can use regions with child controls?
    By joaquim in forum Windows Programming
    Replies: 0
    Last Post: 07-23-2014, 12:00 PM
  2. [Win32] - why the child control don't accept '\t' text format?
    By joaquim in forum Windows Programming
    Replies: 1
    Last Post: 05-29-2014, 02:33 PM
  3. Position of child control..?
    By 39ster in forum Windows Programming
    Replies: 11
    Last Post: 02-28-2008, 07:35 PM
  4. Unknown child control
    By Snip in forum Windows Programming
    Replies: 1
    Last Post: 12-27-2005, 09:27 AM
  5. child windows with win32 API
    By hiya in forum C++ Programming
    Replies: 3
    Last Post: 04-30-2005, 03:08 AM