Click here to Skip to main content
15,886,565 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
INTRODUCTION:

I am creating tab control with child dialog boxes as pages.

I have Visual Styles enabled via #pragma comment. I have also called InitCommonControlsEx and #pragma comment( lib, "comctl32.lib" ) as well.

Initially, when window loads, dialog and its common controls have proper background, please see image[^].

During resizing things are not so consistent -> background starts to mismatches visibly. I will provide screenshot here[^].

You can clearly see that checkbox and static control have improper background, while it seems to me that dialog box ( created to act as a child control ) has proper background.

Edited on November 24th, 2014:

After enclosing controls into group boxes there seems to be no painting problems. My monitor is old CRT ( Samsung SyncMaster 753s ), and I have bad eyesight, but again, it seems that everything paints properly. The window still flickers horribly on resize, but I have tried everything in my power to fix it.

QUESTION:

How can I fix this?

MY EFFORTS TO SOLVE THIS:

I haven't found anything yet but I am still Goggling while typing this question...

RELEVANT INFORMATION:

Here are the instructions for creating demo that illustrates the problem:

1.) Create empty C++ project in Visual Studio;

2.) add header file, name it pomocne_funkcije.h and copy/paste following:
C++
#include <windows.h>
#include <windowsx.h>
#include <comutil.h>
#include <commctrl.h>
#include <stdio.h>
#include <vector>
#include <ole2.h>
#include <string>
#include <stdlib.h>
#include <locale.h>
#include <Uxtheme.h>

#pragma comment( linker, "/manifestdependency:\"type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \
language='*'\"")

#pragma comment( lib, "comctl32.lib")
#pragma comment( lib,"Msimg32.lib")
#pragma comment( lib, "comsuppw.lib")
#pragma comment( lib, "UxTheme.lib")


3.) Create dialog box in resource editor, add checkbox static control.

Set the following for dialog box:

Border : none
Control : true
Control parent : true
Style : child
System menu : false

4.) Here is the code for main.cpp :
C++
#include "pomocne_funkcije.h"

static HINSTANCE hInst;

// dialog procedure for firts tab
INT_PTR CALLBACK Ugovori(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        {
            EnableThemeDialogTexture( hDlg, ETDT_ENABLETAB );
        }
        return (INT_PTR)TRUE;
    }
    return (INT_PTR)FALSE;
}

// main window procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static HWND hDlgFirstTab;  // handle to the first page dialog box
    switch(msg)
    {
    case WM_CREATE:
        {
            RECT rcClient = {0};
            ::GetClientRect( hwnd, &rcClient );

            HWND hwndTab = CreateWindowEx( 0, WC_TABCONTROL, 
                L"Ugovori", WS_CHILD | WS_VISIBLE, 
                10, 10, rcClient.right - rcClient.left - 20,
                rcClient.bottom - rcClient.top - 63, 
                hwnd, (HMENU)3000, 
                ((LPCREATESTRUCT)lParam)->hInstance, 0 );

            TCITEM tci = {0};

            tci.mask = TCIF_TEXT;
            tci.pszText = L"Основни подаци";
            TabCtrl_InsertItem( hwndTab, 0, &tci );

            // set font so cyrilic symbols can be properly displayed instead of ???
            SendMessage( hwnd, WM_SETFONT, 
                (WPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT),
                (LPARAM)TRUE );

            SendMessage( hwndTab, WM_SETFONT, 
                (WPARAM)(HFONT)GetStockObject(DEFAULT_GUI_FONT),
                (LPARAM)TRUE );

            // create page ( dialog box )
            hDlgFirstTab = CreateDialog( ((LPCREATESTRUCT)lParam)->hInstance,
                MAKEINTRESOURCE(IDD_DIALOG1), 
                hwnd, 
                (DLGPROC)Ugovori );  // dialog procedure 

            ShowWindow( hDlgFirstTab, SW_SHOW );

        }
        return 0L;
    case WM_MOVE:
    case WM_MOVING:
    case WM_SIZING:
    case WM_SIZE:
        {
            RECT rcClient = {0};
            GetClientRect( hwnd, &rcClient );

            SetWindowPos( GetDlgItem( hwnd, 3000 ), NULL, 
                rcClient.left + 10, // move it away from window edge by 10 pixels
                rcClient.top + 10,  // move it away from window edge by 10 pixels
                rcClient.right - rcClient.left - 20,  
                // - 63 was the size of the button, 
                // but I have deleted that button here to preserve space
                rcClient.bottom - rcClient.top - 63, 
                SWP_NOZORDER | SWP_NOCOPYBITS );

            // get tab control's client rectangle
            GetClientRect( GetDlgItem( hwnd, 3000 ), &rcTab );

            //============= place dialog box into tab's client area
            MapWindowPoints( GetDlgItem( hwnd, 3000 ), hwnd, 
                (LPPOINT)(&rcTab), 2 );
            // get tab's display area
            TabCtrl_AdjustRect( GetDlgItem( hwnd, 3000 ), 
                FALSE, &rcTab );
            // move dialog box
            SetWindowPos(hDlgFirstTab, NULL, 
                rcTab.left, rcTab.top,
                rcTab.right - rcTab.left, 
                rcTab.bottom - rcTab.top, 
                SWP_NOZORDER);

            //========================= done
            // repaint window
            InvalidateRect( hwnd, NULL, FALSE );
        }
        return 0L;
    case WM_ERASEBKGND:
        return 1L;
    case WM_PAINT:
        {
            PAINTSTRUCT ps = {0};
            HDC hdc = BeginPaint( hwnd, &ps );
            SendMessage( hwnd, WM_PRINTCLIENT, (WPARAM)hdc, 0 );
            EndPaint( hwnd, &ps );
        }
        return 0L;
    case WM_PRINTCLIENT:
        {
            RECT rcClient = {0};
            GetClientRect( hwnd, &rcClient );

            FillRect( (HDC)wParam, &rcClient, 
                (HBRUSH)GetStockObject(WHITE_BRUSH) );
        }
        return 0L;
    case WM_CLOSE:
        ::DestroyWindow(hwnd);
        return 0L;
    case WM_DESTROY:
        ::PostQuitMessage(0);
        return 0L;
    default:
        return ::DefWindowProc( hwnd, msg, wParam, lParam );
    }
    return 0;
}

// WinMain

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, 
                   int nCmdShow)
{
    // store hInstance in global variable for later use

    hInst = hInstance;

    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;

    // initialize common controls

    INITCOMMONCONTROLSEX iccex;
    iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    iccex.dwICC = ICC_LISTVIEW_CLASSES | ICC_UPDOWN_CLASS | 
       ICC_STANDARD_CLASSES | ICC_TAB_CLASSES;
    InitCommonControlsEx(&iccex);

    // register main window class

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
    wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wc.lpszMenuName = NULL;
    wc.lpszClassName = L"Main_Window";
    wc.hIconSm = LoadIcon( hInstance, IDI_APPLICATION );

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, 
            L"Window Registration Failed!", L"Error!", 
            MB_ICONEXCLAMATION | MB_OK);

        return 0;
    }

    // create main window

    hwnd = CreateWindowEx( 0, L"Main_Window", 
        L"Contract manager", 
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 
        CW_USEDEFAULT, 
        CW_USEDEFAULT, 
        CW_USEDEFAULT, 
        CW_USEDEFAULT, 
        NULL, NULL, hInstance, 0 );

    if(hwnd == NULL)
    {
        MessageBox(NULL, L"Nemogu da napravim prozor!", L"Greska!",
            MB_ICONEXCLAMATION | MB_OK);

        return 0; 
    }

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }

    return Msg.wParam;
}

I am working in Visual Studio 2008 on Windows XP using C++ and WinAPI.
Posted
Updated 23-Nov-14 15:00pm
v2
Comments
KarstenK 24-Nov-14 4:09am    
you can post a WM_PAINT to all controls to redraw after the resizing.

1 solution

C++
InvalidateRect( hwnd, NULL, FALSE );

You should use TRUE in the bErase (third) parameter, to ensure the background is erased and completely repainted.
 
Share this answer
 
Comments
AlwaysLearningNewStuff 24-Nov-14 12:36pm    
Thanks for answering. I have changed my code per your instructions but get the same effect...
Richard MacCutchan 24-Nov-14 13:14pm    
Sorry, but I don't have any otrher suggestions, apart from saying you need to remove all the items from your tabs and then add them back one at a time to see where the error occures.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900