Thread: Position of child control..?

  1. #1
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217

    Position of child control..?

    This seems such a basic question but i cant find the answer anywhere. How do i get the position of a child control RELATIVE to its parent. GetClientRect does not return its position. It sets the left and top fields to 0 all the time. I want to get the same X and Y that i used when i call CreateWindowEx().

    EDIT: even more helpful would be to tell me how i can get the control in the below screenshot to automatically grow and shrink when the user grows and shrinks the window.

    [img=http://img146.imageshack.us/img146/7359/testoi5.th.jpg]
    Last edited by 39ster; 02-23-2008 at 01:53 AM.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    http://msdn2.microsoft.com/en-us/library/ms632598.aspx
    See the example code in the "Creating, Enumerating, and Sizing Child Windows" section.

    FYI - There is also GetWindowRect() wich can be used to calculate the coordinates used in the CreateWindow() call.

    gg

  3. #3
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    Quote Originally Posted by Codeplug View Post
    http://msdn2.microsoft.com/en-us/library/ms632598.aspx
    See the example code in the "Creating, Enumerating, and Sizing Child Windows" section.

    FYI - There is also GetWindowRect() wich can be used to calculate the coordinates used in the CreateWindow() call.

    gg
    Thanks. I've tried using GetWindowRect() and MoveWindow() to automatically resize a child control in the WM_SIZE event. For some reason the X and Y are way off and instead of not moving the child at all (by making the X and Y in MoveWindow the same values you get from GetWindowRect()) the child control moves south-east until it goes way past the parents boundaries.

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    When you call MoveWindow() on child windows, the coordinate parameters are relative to the parent. So (0, 0) is the top-left point on the parent window.

    GetWindowRect() returns coordinates relative to the screen.

    gg

  5. #5
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    ...So GetWindowRect() cant be used to get the position you used in CreateWindow() ? It only works on the main window, not the children. I even tried this and the child still moves south east each time i resize the main window.

    Code:
    		RECT childRect, parentRect;
    		GetWindowRect(canvas.getHandle(), &childRect);
    		GetWindowRect(GetParent(canvas.getHandle()), &parentRect);
    
    		MoveWindow(canvas.getHandle(), childRect.left - parentRect.left,
                        childRect.top - parentRect.top, 50, 50, true);

  6. #6
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Code:
    MoveWindow(canvas.getHandle(), childRect.left - parentRect.left,
               childRect.top - parentRect.top, 50, 50, TRUE);
    So that code should keep the canvas at the same X,Y and at 50x50.

    So when is this code being executed? During what message, ect...?

    gg

  7. #7
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    Yes the X and Y should stay the same. I put 50x50 there just for the example, it shoudnt really relate to the question as to why the canvas moves south east. I just want to resize the canvas without modifying the position. Its being executed in the WM_SIZE event.

  8. #8
    Registered User
    Join Date
    Dec 2006
    Location
    Scranton, Pa
    Posts
    252
    I don't think you want to use MoveWindow, what you're trying to do is reposition it. I think SetWindowPos( ) would better suit your needs. You'd still use GetWindowRect on both on main and child, then use .right, -top, bottom or whatever it works itself out to successfully do the resize and repositioning of the control.

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    SetWindowPos() also requires client coordinates - either function works equally well.

    If you're using a framework, then there may be a specific "framework-way" of doing this. Here's a simple console app that has no problem resizing a child during WM_SIZE.

    Code:
    #include <windows.h>
    
    #include <iostream>
    using namespace std;
    
    LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
    
    int main()
    {
        const char *className = "WindowsApp";
    
        WNDCLASSA wincl = {0};
        wincl.hInstance = GetModuleHandle(0);
        wincl.lpszClassName = className;
        wincl.lpfnWndProc = WinProc;
        wincl.style = CS_DBLCLKS;    
        wincl.hIcon = LoadIcon(0, IDI_APPLICATION);
        wincl.hCursor = LoadCursor(0, IDC_ARROW);
        wincl.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
    
        if (!RegisterClassA(&wincl))
            return 1;
    
        HWND hwndParent;
        hwndParent = CreateWindowA(className, "Windows App", 
                                   WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                                   CW_USEDEFAULT, CW_USEDEFAULT,
                                   450, 375, HWND_DESKTOP, 0, 
                                   GetModuleHandle(0), 0);
        if (!hwndParent)
            return 1;
    
        RECT parentRect;
        GetWindowRect(hwndParent, &parentRect);
        int parentWidth = parentRect.right - parentRect.left;
        int parentHeight = parentRect.bottom - parentRect.top;
    
        HWND hwndChild;
        hwndChild = CreateWindowA("Button", "Button", WS_CHILD | WS_VISIBLE,
                                  10, 10,  parentWidth / 2, parentHeight / 2,
                                  hwndParent, 0, GetModuleHandle(0), 0);
        if (!hwndChild)
            return 1;
    
        MSG msg;
        BOOL bRet;
        for (;;)
        {
            bRet = GetMessage(&msg, 0, 0, 0);
            if ((bRet == 0) || (bRet == -1))
                break;
    
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }//while
    
        return (int)msg.wParam;
    }//main
    
    
    LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, 
                             WPARAM wParam, LPARAM lParam)
    {
        switch(msg)
        {
            case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            }//case
                
            case WM_SIZE:
            {
                cout << LOWORD(lParam) << ", " 
                     << HIWORD(lParam) << endl;
                
                RECT parentRect;
                GetWindowRect(hwnd, &parentRect);
                
                int parentWidth = parentRect.right - parentRect.left;
                int parentHeight = parentRect.bottom - parentRect.top;
                
                MoveWindow(GetWindow(hwnd, GW_CHILD), 
                           10, 10, parentWidth / 2, parentHeight / 2, 
                           TRUE); 
                return 0;
            }//case
        }//switch
    
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }//WinProc
    gg

  10. #10
    Registered User
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    217
    Ok this is how i decided to do it (btw im not using a framework. Its just a few classes i made to make the event handling easier):

    Code:
        CDlgMain(HWND hWnd): CWindowClass(hWnd)
        {
    
           .....
     	//Create a canvas
            canvas.create(CreateWindowEx(WS_EX_CLIENTEDGE,
                    "PANELCLASS",
                    "",
                    WS_CHILD | WS_VSCROLL | WS_HSCROLL,
                    0,
                    0,
                    0,
                    0,
                    getHandle(),
                    NULL,
                    CApplication::getHandle(),
                    NULL));
            //Create menu tab
            menuTab.create(CreateWindowEx(0, WC_TABCONTROL, "", WS_CHILD | TCS_MULTILINE, 0, 0, 0, 0,
                        getHandle(), NULL, CApplication::getHandle(), NULL));
            //Create map tab
            mapTab.create(CreateWindowEx(0, WC_TABCONTROL, "", WS_CHILD, 0, 0, 0, 0,
                        getHandle(), NULL, CApplication::getHandle(), NULL));
    
            //force the WM_SIZE message to be sent (to adjust the scroll bars on the canvas)
            canvas.sendSizeMessage();
            //force the WM_SIZE message to be sent to main window (to set the shape and position of some of the child windows)
            this->sendSizeMessage();
           .....
    
        }
    
        int onSize(const TSizeEvent& event)
        {
            int canvasWidth = event.width - 210;
            int canvasHeight = event.height - 76;
    
            //Autosize status bar and scroll bar
            statusBar.sendMessage(WM_SIZE, 0, 0);
    	toolBar.sendMessage(WM_SIZE, 0, 0);
    
            //Auto size the other stuff
    	MoveWindow(canvas.getHandle(), 206, 55, canvasWidth, canvasHeight, true);
            MoveWindow(menuTab.getHandle(), 14, 32, 188, event.height - 54, true);
            MoveWindow(mapTab.getHandle(), 206, 32, event.width - 210, 24, true);
    
            //Resize back buffer
            if(canvasWidth > backBuffer->w || canvasHeight > backBuffer->h)
    	{
                SDL_FreeSurface(backBuffer);
                backBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, canvasWidth, canvasHeight, 24, 0x00FF0000, 0x0000FF00, 0x000000FF, 0);
                updateCanvas(true);
    	}
            return 1;
        }
    Now i just dont even bother putting the size and position in CreateWindow

  11. #11
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Ummmm.....

    ClientToScreen() will convert from the controls coods to the parents (given the right input).

    There is also a reverse, ScreenToClient().

    AdjustWindowRect() may also be useful.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  12. #12
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    I probably should have searched the forums.....

    http://cboard.cprogramming.com/showt...php?t=48459&#4

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 10-15-2008, 09:24 AM
  2. process programming
    By St0rM-MaN in forum Linux Programming
    Replies: 2
    Last Post: 09-15-2007, 07:53 AM
  3. Button handler
    By Nephiroth in forum Windows Programming
    Replies: 8
    Last Post: 03-12-2006, 06:23 AM
  4. MFC Dialog :: Slider Control child notification messages?
    By SyntaxBubble in forum Windows Programming
    Replies: 2
    Last Post: 12-16-2003, 12:09 PM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM