Home > front end >  Win32 API child window flicker
Win32 API child window flicker

Time:10-05

I'm new to the Win32 API and can't understand why all of my child windows are flickering so much whenever I input something into them. Does anyone know why it is flickering? Below is what I coded; it doesn't seem to work as intended. Even though I'm sure I handled all of my handles correctly and used the pointers properly throughout the code.

#include <windows.h>
#include <string.h>
#include <stdlib.h>
#define CONVERT_TAX 1
LRESULT CALLBACK WindowProcedure(HWND,UINT,WPARAM,LPARAM);
void AddMenus(HWND hWnd);
void AddControls(HWND hWnd);
int TaxConversion(int TaxRate);
HWND hOut;
HWND hTax;
int main(HINSTANCE hInst, HINSTANCE vPrevInst,LPSTR args, int ncmdshow){
    WNDCLASSW wc ={};
    wc.hIcon=LoadIcon(NULL, IDI_APPLICATION); //The icon handle for the window class. LoadIcon(NULL, IDI_APPLICATION) loads the default application icon.
    wc.cbWndExtra=0; //The number of extra bytes to allocate for each individual window. Do not confuse this with cbClsExtra, which is common to all instances. This is often 0.
    wc.cbClsExtra=0; //The number of extra bytes to allocate for the window class. For most situations, this member is 0.
    wc.style=0; // 
    wc.hbrBackground=(HBRUSH)COLOR_WINDOW; //A handle to the background brush. GetStockObject (WHITE_BRUSH) gives a handle to a white brush. The return value must be cast because GetStockObject returns a generic object.
    wc.hCursor=LoadCursor(NULL,IDC_ARROW); //The cursor handle for the window class. LoadCursor(NULL, IDC_ARROW) loads the default cursor.
    wc.hInstance=hInst; //The instance handle. Just assign the hInst argument in WinMain to this field.
    wc.lpszClassName=L"myWindowClass"; //The class name that identifies this window class structure. In this example, the CLSNAME global variable stores the window class name.
    wc.lpfnWndProc=WindowProcedure; //Stores the address of the window procedure, a function that handles events for all windows that are instances of this window class.
    if(!RegisterClassW(&wc))
        return -1;
    CreateWindowW(L"myWindowClass",L"My Window",WS_OVERLAPPEDWINDOW|WS_VISIBLE,500,500,500,500,NULL,NULL,NULL,NULL); 
    MSG msg = {0};
    while(GetMessage(&msg,NULL,0,0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}
LRESULT CALLBACK WindowProcedure(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp){ //Procedures for Events
    switch(msg){
    case WM_COMMAND:
        switch(wp){
            case CONVERT_TAX:
            char Tax[100];
            GetWindowText(hTax,Tax,100);
            SetWindowText(hOut,Tax);
            break;
        }
    case WM_CREATE:
        AddControls(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProcW(hWnd,msg,wp,lp);
    }
    return 0; 
}
void AddControls(HWND hWnd){
    CreateWindowW(L"Static",L"Enter Tax Rate",WS_CHILD|WS_VISIBLE,1,1,90,90,hWnd,0,0,0);
    hTax=CreateWindowW(L"Edit",L"",WS_CHILD|WS_BORDER|WS_VISIBLE,1,92,90,90,hWnd,0,0,0);
    CreateWindowW(L"Button",L"Find Amount",WS_CHILD|WS_BORDER|WS_VISIBLE,1,183,90,90,hWnd,(HMENU)CONVERT_TAX,0,0);
    hOut=CreateWindowW(L"Edit",L"",WS_CHILD|WS_BORDER|WS_VISIBLE,1,267,90,90,hWnd,0,0,0);
}

CodePudding user response:

I see two mistakes in your code:

  • when setting wc.hbrBackground, you must add 1 to the color value, per the documentation:

    https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-wndclassw

    hbrBackground

    Type: HBRUSH

    A handle to the class background brush. This member can be a handle to the physical brush to be used for painting the background, or it can be a color value. A color value must be one of the following standard system colors (the value 1 must be added to the chosen color)...

    wc.hbrBackground=(HBRUSH)(COLOR_WINDOW 1); // <-- add  1
    
  • your WM_COMMAND handler is missing a break after the switch block, so every command message received will fall through into your WM_CREATE handler, thus creating more and more child controls.

    case WM_COMMAND:
        switch(wp){
          case CONVERT_TAX:
              char Tax[100];
              GetWindowText(hTax,Tax,100);
              SetWindowText(hOut,Tax);
              break;
        }
        break; // <-- add this
    
  • Related