CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Apr 2009
    Posts
    1,355

    [RESOLVED] win32 - how center a control depending on it's parent position and size?

    i have these code for center a control depending on it's parent position and size:

    Code:
    void ScreenToClient(HWND WindowDestination, RECT *WindowRectangle)
    {
        MapWindowPoints(NULL, WindowDestination, LPPOINT(WindowRectangle), 2);
    }
    
    
    
    void Center()
            {
                //getting the controls positions\size
                RECT frm,frmparent;
    
                //getting the parent coordenates
                //depending if is a form or the desktop\screen
                if(GetParent(hwnd)!=NULL)
                {
                    GetWindowRect(GetParent(hwnd), &frmparent);
                    ScreenToClient(GetParent(hwnd),&frmparent);
                }
                else
                {
                    GetWindowRect(GetDesktopWindow(), &frmparent);
                    ScreenToClient(GetDesktopWindow(),&frmparent);
                }
    
                //getting the control coordenates
                //i have a 2nd ScreenToClient() api function for accept the RECT
                GetWindowRect(hwnd, &frm);
                if(GetParent(hwnd)!=NULL)
                {
                    ScreenToClient(GetParent(hwnd),&frm);
                }
                else
    
                {
                    ScreenToClient(GetDesktopWindow(),&frm);
                }
    
                //calculate the center
                LONG x=(frmparent.right-frmparent.left)/2 - (frm.right-frm.left)/2;
                LONG y=(frmparent.bottom-frmparent.top)/2 - (frm.bottom-frm.top)/2;
    
                //position the control
                SetWindowPos(hwnd,0,x ,y,0,0, SWP_NOSIZE |  SWP_NOZORDER);
            }
    the control seems been on center of screen instead been center of it's parent
    both controls are forms and none are WS_CHILD.
    when i create a form:

    Code:
    form(string caption = "", HWND parent=HWND_DESKTOP)
            {
                ++FormCount;
                if(caption=="")
                    strCaption = strCaption + to_string(FormCount);
                else
                    strCaption=caption;
                setParent(parent);
            }
    
    
    void setParent(HWND parent=GetDesktopWindow())
            {
                if (hwnd==NULL)
                {
    
                    WNDCLASSEX FormClass;
                    char classname[20]="Form";
                    sprintf(classname,"%s",strCaption.c_str());
                    HINSTANCE mod = (HINSTANCE)GetModuleHandle(NULL);
    
                    FormClass.cbSize        = sizeof(WNDCLASSEX);
                    FormClass.style         = CS_DBLCLKS;
                    FormClass.lpfnWndProc   = WndProcForm;
                    FormClass.cbClsExtra    = 0;
                    FormClass.cbWndExtra    = 0;
                    FormClass.hInstance     = mod;
                    FormClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
                    FormClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
                    FormClass.hbrBackground = (HBRUSH)GetSysColor(COLOR_BACKGROUND);
                    FormClass.lpszMenuName  = NULL;
                    FormClass.lpszClassName = classname;
                    FormClass.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    
                    // register the new window class
                    RegisterClassEx(&FormClass);
    
                    hwnd = CreateWindowEx(0,classname, strCaption.c_str(),WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN ,
                                      CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, parent, NULL, mod, this);
    
                    SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA);
                    if (hwnd == NULL)
                        MessageBox(NULL, "Can't create the control", "error", MB_OK);
                }
                else
                {
                    SetParent(hwnd,parent);
                }
    
                ShowWindow(hwnd, SW_NORMAL);
                InvalidateRect(hwnd,NULL,TRUE);//i add these line for fix that
                UpdateWindow(hwnd);
                clrBackColor =GetDCBrushColor(GetDC(hwnd));
                clrTextColor = GetTextColor(GetDC(hwnd));
            }

  2. #2
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: win32 - how center a control depending on it's parent position and size?

    Best regards,
    Igor

  3. #3
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: win32 - how center a control depending on it's parent position and size?

    Code:
    void CenterInsideParent(HWND hWnd)
    {
        /* start calculating in parent's coordinates */
        HWND hParent = GetParent(hWnd);
        RECT rcp, rcc;
        GetClientRect(hParent, &rcp);
        GetWindowRect(hWnd, &rcc);
    
        /* offset child rect to top left */
        rcc.bottom -= rcc.top; /* height */
        rcc.right -= rcc.left; /* width */
        rcc.left = rcc.top = 0;
    
        /* get top-left anchor */
        rcc.left = (rcp.right - rcc.right)/2;
        rcc.top = (rcp.bottom - rcc.bottom)/2;
    
        /* non-child to be centered in screen coordinates, not in parent's ones */
        if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD))
        {
            /* adjust anchor position */
            MapWindowPoints(hParent, GetDesktopWindow(), (LPPOINT)&rcc, 1);
        }
    
        //MoveWindow(hWnd, rcc.left, rcc.top, rcc.right /*width*/, rcc.bottom /*height*/, TRUE);
        SetWindowPos(hWnd, NULL, rcc.left, rcc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    }
    Last edited by Igor Vartanov; July 28th, 2015 at 03:40 AM.
    Best regards,
    Igor

  4. #4
    Join Date
    Apr 2009
    Posts
    1,355

    Re: win32 - how center a control depending on it's parent position and size?

    Quote Originally Posted by Igor Vartanov View Post
    Code:
    void CenterInsideParent(HWND hWnd)
    {
        /* start calculating in parent's coordinates */
        HWND hParent = GetParent(hWnd);
        RECT rcp, rcc;
        GetClientRect(hParent, &rcp);
        GetWindowRect(hWnd, &rcc);
    
        /* offset child rect to top left */
        rcc.bottom -= rcc.top; /* height */
        rcc.right -= rcc.left; /* width */
        rcc.left = rcc.top = 0;
    
        /* get top-left anchor */
        rcc.left = (rcp.right - rcc.right)/2;
        rcc.top = (rcp.bottom - rcc.bottom)/2;
    
        /* non-child to be centered in screen coordinates, not in parent's ones */
        if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD))
        {
            /* adjust anchor position */
            MapWindowPoints(hParent, GetDesktopWindow(), (LPPOINT)&rcc, 1);
        }
    
        //MoveWindow(hWnd, rcc.left, rcc.top, rcc.right /*width*/, rcc.bottom /*height*/, TRUE);
        SetWindowPos(hWnd, NULL, rcc.left, rcc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    }

    i can't see the form inside the screen
    anotherthing: in these case i don't care if is WS_CHILD or not. the position, always, will depend on it's parent(of course if is DeskTop, then will be on screen center)

  5. #5
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: win32 - how center a control depending on it's parent position and size?

    Quote Originally Posted by Cambalinho View Post
    i can't see the form inside the screen
    Did you build and play with my sample? It creates a popup dialog that can be centered over its parent.
    Best regards,
    Igor

  6. #6
    Join Date
    Apr 2009
    Posts
    1,355

    Re: win32 - how center a control depending on it's parent position and size?

    Quote Originally Posted by Igor Vartanov View Post
    Did you build and play with my sample? It creates a popup dialog that can be centered over its parent.
    i'm playing with the function. and the child control it's on center. but not a control without a WS_CHILD style
    i must test more the function

  7. #7
    Join Date
    Apr 2009
    Posts
    1,355

    Re: win32 - how center a control depending on it's parent position and size?

    please see the setParent() function. i belive here is a problem. 2 diferent controls(both forms), 1 is parent of other. but when i do:
    Code:
    GetParent(hWnd)
    i get NULL. so heres there a problem. thats why i will always get it on center of screen, instead it's parent

  8. #8
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: win32 - how center a control depending on it's parent position and size?

    Quote Originally Posted by Cambalinho View Post
    please see the setParent() function. i belive here is a problem. 2 diferent controls(both forms), 1 is parent of other. but when i do:
    Code:
    GetParent(hWnd)
    i get NULL. so heres there a problem. thats why i will always get it on center of screen, instead it's parent
    You are not allowed to explicitly set pop-up or overlapped window's owner. Window ownership is set only during CreateWindow or CreateDialog execution (see my sample). Once set, owner cannot be changed.

    SetParent in its turn works only with windows having WS_CHILD style. That's why you get NULL parent.
    Last edited by Igor Vartanov; July 28th, 2015 at 07:59 AM.
    Best regards,
    Igor

  9. #9
    Join Date
    Apr 2009
    Posts
    1,355

    Re: win32 - how center a control depending on it's parent position and size?

    Quote Originally Posted by Igor Vartanov View Post
    You are not allowed to explicitly set pop-up or overlapped window's owner. Window ownership is set only during CreateWindow or CreateDialog execution (see my sample). Once set, owner cannot be changed.

    SetParent in its turn works only with windows having WS_CHILD style. That's why you get NULL parent.
    but see the funcion in these way:
    Code:
    const UINT CenterCenter=0;
    
    void CenterInsideParent(HWND hWnd, HWND parent=GetDesktopWindow(), UINT ControlPosition=CenterCenter)
    {
        //getting the controls positions\size
        RECT frm,frmparent;
    
        //getting the parent coordenates
        //depending if is a form or the desktop\screen
        GetWindowRect(parent, &frmparent);
        //ScreenToClient(GetParent(hWnd),&frmparent);
    
    
        //getting the control coordenates
        //i have a 2nd ScreenToClient() api function for accept the RECT
        GetWindowRect(hWnd, &frm);
    
        //calculate the center
        LONG x=(frmparent.right-frmparent.left)/2 - (frm.right-frm.left)/2;
        LONG y=(frmparent.bottom-frmparent.top)/2 - (frm.bottom-frm.top)/2;
    
    
        ScreenToClient(parent,&frm);
    
    
        //position the control
        SetWindowPos(hWnd,0,x ,y,0,0, SWP_NOSIZE |  SWP_NOZORDER);
    }
    how i use it:
    Code:
     CenterInsideParent(InputBox,a);
    InputBox its the form that need to be re-positioned;
    a its the form where InputBox is centered.
    so why my function can't put the InputBox on center of the a?

  10. #10
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: win32 - how center a control depending on it's parent position and size?

    Quote Originally Posted by Cambalinho View Post
    so why my function can't put the InputBox on center of the a?
    Debugger will answer.

    Besides, as I wrote in my comments, non-child window (i.e. pop-up or overlapped one) must be repositioned in screen coordinates, not parent's client coordinates.
    Last edited by Igor Vartanov; July 28th, 2015 at 08:32 AM.
    Best regards,
    Igor

  11. #11
    Join Date
    Apr 2009
    Posts
    1,355

    Re: win32 - how center a control depending on it's parent position and size?

    Quote Originally Posted by Igor Vartanov View Post
    Debugger will answer.

    Besides, as I wrote in my comments, non-child window (i.e. pop-up or overlapped one) must be repositioned in screen coordinates, not parent's client coordinates.
    after some work i put it to work:
    Code:
    const UINT CenterCenter=0;
    
    void CenterInsideParent(HWND hWnd, HWND parent=GetDesktopWindow(), UINT ControlPosition=CenterCenter)
    {
        //getting the controls positions\size
        RECT frm,frmparent;
    
        //getting the parent coordenates
        //depending if is a form or the desktop\screen
        GetWindowRect(parent, &frmparent);
        //ScreenToClient(GetParent(hWnd),&frmparent);
    
    
        //getting the control coordenates
        //i have a 2nd ScreenToClient() api function for accept the RECT
        GetWindowRect(hWnd, &frm);
    
        //calculate the center
        LONG x;
        LONG y;
        if(parent!=GetDesktopWindow())
        {
            x=(frmparent.left+((frmparent.right-frmparent.left)/2)) - ((frm.right-frm.left)/2);
            y=(frmparent.top+((frmparent.bottom-frmparent.top)/2)) - ((frm.bottom-frm.top)/2);
        }
        else //center of screen
        {
            x=(((frmparent.right-frmparent.left)/2)) - ((frm.right-frm.left)/2);
            y=(((frmparent.bottom-frmparent.top)/2)) - ((frm.bottom-frm.top)/2);
        }
    
    
        if ((GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD))
        {
            POINT a={x,y};
            ScreenToClient(parent,&a);
            x=a.x;
            y=a.y;
        }
    
    
        //position the control
        SetWindowPos(hWnd,0,x ,y,0,0, SWP_NOSIZE |  SWP_NOZORDER);
    }
    and yes... i can center on screen too
    thanks for all

  12. #12
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [RESOLVED] win32 - how center a control depending on it's parent position and siz

    these calculation isn't prepared for border(the caption or arround the window), can anyone advice me?

  13. #13
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: [RESOLVED] win32 - how center a control depending on it's parent position and siz

    Quote Originally Posted by Cambalinho View Post
    these calculation isn't prepared for border(the caption or arround the window), can anyone advice me?
    Do you want to NOT count caption and border of the parent window? Then use GetClientRect() instead of GetWindowRect().
    Please note: client rectangle is always in client's coordinates.

    Also please note that
    frmparent.left+((frmparent.right-frmparent.left)/2)
    is the same as
    (frmparent.left+frmparent.right)/2
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  14. #14
    Join Date
    Apr 2009
    Posts
    1,355

    Re: [RESOLVED] win32 - how center a control depending on it's parent position and siz

    Quote Originally Posted by VladimirF View Post
    Do you want to NOT count caption and border of the parent window? Then use GetClientRect() instead of GetWindowRect().
    Please note: client rectangle is always in client's coordinates.

    Also please note that
    frmparent.left+((frmparent.right-frmparent.left)/2)
    is the same as
    (frmparent.left+frmparent.right)/2
    for child controls now works fine:
    Code:
    void CenterInsideParent(HWND hWnd, ControlPositions ControlPosition=CenterCenter)
    {
        //getting the parent
        HWND parent=GetDesktopWindow();
        if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) && parent==GetDesktopWindow())
        {
            if(GetProp(hWnd, "parent")!=NULL)
                parent=(HWND)GetProp(hWnd, "parent");
        }
        else
            parent=GetParent(hWnd);
    
        //getting the controls positions\size
        //depending if is a child or not
        RECT frm,frmparent;
    
        if ((GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD))
        {
            GetClientRect(parent, &frmparent);
            GetWindowRect(hWnd, &frm);
            ScreenToClient(parent,&frm);
        }
        else
        {
            GetWindowRect(parent, &frmparent);
            GetWindowRect(hWnd, &frm);
        }
    
        //calculate the position choosed
        LONG x;
        LONG y;
        if (parent!=GetDesktopWindow())
        {
            if(ControlPosition==0)
            {
                x=(frmparent.left+((frmparent.right-frmparent.left)/2)) - ((frm.right-frm.left)/2);
                y=(frmparent.top+((frmparent.bottom-frmparent.top)/2)) - ((frm.bottom-frm.top)/2);
            }
            else if (ControlPosition==1)
            {
                x=frmparent.left;
                y=(frmparent.top+((frmparent.bottom-frmparent.top)/2)) - ((frm.bottom-frm.top)/2);
            }
    
        }
        else //center of screen
        {
            if(ControlPosition==0)
            {
                x=(((frmparent.right-frmparent.left)/2)) - ((frm.right-frm.left)/2);
                y=(((frmparent.bottom-frmparent.top)/2)) - ((frm.bottom-frm.top)/2);
            }
            else if (ControlPosition==1)
            {
                x=0;
                y=(((frmparent.bottom-frmparent.top)/2)) - ((frm.bottom-frm.top)/2)+3;
            }
        }
    
        //position the control
        SetWindowPos(hWnd,0,x ,y,0,0, SWP_NOSIZE |  SWP_NOZORDER);
    }
    see when is 1:
    Code:
    if (parent!=GetDesktopWindow())
        {
            if(ControlPosition==0)
            {
                x=(frmparent.left+((frmparent.right-frmparent.left)/2)) - ((frm.right-frm.left)/2);
                y=(frmparent.top+((frmparent.bottom-frmparent.top)/2)) - ((frm.bottom-frm.top)/2);
            }
            else if (ControlPosition==1)
            {
                x=frmparent.left;
                y=(frmparent.top+((frmparent.bottom-frmparent.top)/2)) - ((frm.bottom-frm.top)/2);
            }
    strange the frmparent.left been less some pixles

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured