Resize child window

Started by
30 comments, last by Decrius 17 years, 11 months ago
***BUMP***
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Advertisement
If any Windows function returns an error, you should use GetLastError() to find out what the problem was.
In this case, I'd put a breakpoint or logging statement in your window message handler for the Classname class of window, and see if the window peocedure is even called. If it is, then the problem is most likely in there (Such as returning non-zero in response to WM_CREATE).

In either case, if CreateWindowEx fails, use GetLastError afterwards to see why it failed.
Okay, thanks, I'll see if everything works.

Its really doing weird, when I give hChild1 (all 4 hChild window have the same size, I just have 4 Child windows, top-left, top-right, bottom-left, bottom-right) the same classname as the main window has, it doesn't appears. But when I resize the screen its flashing, what I see flashing are 3 smaller Child windows where the 1st (top-left) doesn't appears, the same as hChild 1 to 4 but than smaller! And in that missing first Child window, appear 3 others, with again, 1 missing. As you guess: the top-left one is missing.

Sorry, I can't post a picture, because when I press print screen, the flashing stuff doesn't appears.

Very weird :S

Decrius
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
But what is usual way to create custom control? Should the custom control have an own registered class? Or should the control use the class of the main window?

Decrius
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
The custom control should be it's own class - since you need to call RegisterClass() for the sub-window, and specify a WindowProc there. Otherwise, Windows has no way of knowing where to send window messages for that window.

You did register Classname with RegisterClass[Ex](), didn't you?
Yes, I did:

HWND Create_Window_Main(char *Main_Classname, char *Title, int x, int y, int width, int height, BYTE type, DWORD flags){    int         pf;    HDC         hDC;    HWND        hWnd;    WNDCLASSEX  wc;    PIXELFORMATDESCRIPTOR pfd;    static HINSTANCE hInstance = 0;	hInstance        = GetModuleHandle(NULL);	wc.cbSize        = sizeof(WNDCLASSEX);	wc.style         = CS_OWNDC;	wc.lpfnWndProc   = (WNDPROC)WindowProc;	wc.cbClsExtra    = 0;	wc.cbWndExtra    = 0;	wc.hInstance     = hInstance;	wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO);	wc.hCursor       = LoadCursor(NULL, IDC_ARROW);	wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);	wc.lpszMenuName  = MAKEINTRESOURCE(IDM_MENU);	wc.lpszClassName = Main_Classname;	wc.hIconSm		 = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_16_ICON));	if (!RegisterClassEx(&wc)) {	    MessageBox(NULL, "RegisterClassEx() failed:  "		       "Cannot register window class.", "Error", MB_OK);	    return NULL;	}    hWnd = CreateWindowEx(                    NULL,                    Main_Classname,                    Title,                    WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,                    x, y, width, height,                    NULL,                    NULL, hInstance, NULL);                char str[255];                sprintf(str, "hWnd=0x%08X", Main_Classname);                MessageBox(NULL, str, "Message", MB_OK);    if (hWnd == NULL) {	MessageBox(NULL, "CreateWindowEx() failed:  Cannot create a window.",		   "Error", MB_OK);	return NULL;    }    hDC = GetDC(hWnd);    /* there is no guarantee that the contents of the stack that become       the pfd are zeroed, therefore _make sure_ to clear these bits. */    memset(&pfd, 0, sizeof(pfd));    pfd.nSize        = sizeof(pfd);    pfd.nVersion     = 1;    pfd.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;    pfd.iPixelType   = type;    pfd.cColorBits   = 32;    pf = ChoosePixelFormat(hDC, &pfd);    if (pf == 0) {	MessageBox(NULL, "ChoosePixelFormat() failed:  "		   "Cannot find a suitable pixel format.", "Error", MB_OK);	return 0;    }    if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {	MessageBox(NULL, "SetPixelFormat() failed:  "		   "Cannot set format specified.", "Error", MB_OK);	return 0;    }    DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);    ReleaseDC(hWnd, hDC);    hToolbar = Create_Window_Toolbar(hWnd);    hStatusbar = Create_Window_Statusbar(hWnd);    hChild1 = Create_Window_Child1(hWnd, Main_Classname);    hChild2 = Create_Window_Child2(hWnd, Main_Classname);    hChild3 = Create_Window_Child3(hWnd, Main_Classname);    hChild4 = Create_Window_Child4(hWnd, Main_Classname);    return hWnd;}


Sorry, but does the new Child window needs its own WndProc?

Whole source about the control:
char *Main_Classname = "mainwindowclass";char *Title = "title";HWND hToolbar;HWND hStatusbar;HWND hChild1, hChild2, hChild3, hChild4;HWND Create_Window_Toolbar(HWND hParent);HWND Create_Window_Statusbar(HWND hParent);HWND Create_Window_Child1(HWND hParent, char *Main_Classname);... Child2 to 4...Create_Window_Main(... shown in the source above...);HWND Create_Window_Child1(HWND hParent, char *Classname){    return CreateWindowEx(                 WS_EX_CLIENTEDGE, // give it a standard border                 Classname,                 NULL,                 WS_VISIBLE | WS_CHILD,                 0, 0, 0, 0,                 hParent,                 NULL, GetModuleHandle(0), NULL               );...LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){    static PAINTSTRUCT ps;    switch(uMsg)    {        case WM_PAINT:        {            //display();            BeginPaint(hWnd, &ps);            EndPaint(hWnd, &ps);            return 0;        }        case WM_SIZE:        {            glViewport(1, 28, ((LOWORD(lParam)-6)/2), ((HIWORD(lParam)-53)/2));            PostMessage(hWnd, WM_PAINT, 0, 0);            SendMessage(hToolbar,uMsg,wParam,lParam);		    SendMessage(hStatusbar,uMsg,wParam,lParam);		    /*//To check if the child window hasn't any errors:		    bool bRet;		    bRet = SetWindowPos();            if(bRet == 0)            {                char str[255];                sprintf(str, "hChild1=0x%08X, hWnd=0x%08X", hChild1, hWnd);                MessageBox(NULL, str, "Message", MB_OK);            }*/            //If window size is 512x512, than the insize child window will need a size of 502x413, starting at x=1 and y=28; (1, 28, 502, 413)		    SetWindowPos(hChild1, NULL, 1, 28, ((LOWORD(lParam)-6)/2), ((HIWORD(lParam)-53)/2), SWP_NOZORDER);            SetWindowPos(hChild2, NULL, 1, 32+((HIWORD(lParam)-53)/2), ((LOWORD(lParam)-6)/2), ((HIWORD(lParam)-53)/2), SWP_NOZORDER);            SetWindowPos(hChild3, NULL, 5+((LOWORD(lParam)-6)/2), 28, ((LOWORD(lParam)-6)/2), ((HIWORD(lParam)-53)/2), SWP_NOZORDER);            SetWindowPos(hChild4, NULL, 5+((LOWORD(lParam)-6)/2), 32+((HIWORD(lParam)-53)/2), ((LOWORD(lParam)-6)/2), ((HIWORD(lParam)-53)/2), SWP_NOZORDER);            return 0;        }    }    return DefWindowProc(hWnd, uMsg, wParam, lParam);}


Hope anyone can find out what I'm doing wrong...

Decrius
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Ah ha. If your custom control uses the same window proc as your main window, then this happens:
  • You get a WM_SIZE sent to the main windows window proc
  • Your window proc calls SetWindowPos() on child 1, which posts a WM_SIZE for the child window's window proc
  • You get a WM_SIZE in your child windows window proc
  • Your window proc calls SetWindowPos() on child 1, which posts a WM_SIZE for the child window's window proc
  • You get a WM_SIZE in your child windows window proc
  • Your window proc calls SetWindowPos() on child 1, which posts a WM_SIZE for the child window's window proc
  • Etc.

    Result: You're constantly calling SetWindowPos(), which results in the window flickering. Your message queue will be filling up like crazy too.

    You don't need a new window proc for each child window, but if you are going to use the same window proc, you'll need to account for the fact that you'll be getting messages destined for the main window and the child windows.
  • Ah, yes I see why, thanks! :D

    To make a new WndProc for the Child windows, I'll need to register a new class to define the new WndProc?

    Decrius

    [Edited by - Decrius on April 26, 2006 5:12:29 AM]
    [size="2"]SignatureShuffle: [size="2"]Random signature images on fora
    I registered a new class and made a new WndProc, but its still not displaying...any tutorials about this?

    Decrius
    [size="2"]SignatureShuffle: [size="2"]Random signature images on fora
    You could also just use the main window proc and have if statements in the WM_SIZE checking for the messages HWND against the 5 windows you have.

    Something like:

    case WM_SIZE{    if (hWnd == hChild1)    {        // Handle Child Window 1 size messages here...    } else if (hWnd == hChild2)    {       // Handle Child Window 2 size messages here...    } if (hWnd == //... etc}


    It's truely up to you.

    "Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

    This topic is closed to new replies.

    Advertisement