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

I'm working on developing my win32 api test application.
I've done the tool bar menus. Static and button controls.

Every thing is OK, but the problem is that when I want to print a new content, I still have some stuff from the previous content.

So my question, is how to clear the window before printing new content ?


This is my code:

C++
#include <windows.h>
#include <stdint.h>

#define FILE_MENU_NEW   1   // File menu item to be used as window numbered functions
#define FILE_MENU_OPEN  2   // File menu item to be used as window numbered functions
#define FILE_MENU_EXIT  3   // File menu item to be used as window numbered functions


#define HOME_PAGE       4
#define PAGE1           5
#define PAGE2           6

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
void AddMenus(HWND);
void main_page(HWND hWnd);
void page1(HWND hWnd);
void page2(HWND hWnd);


HMENU hMenu;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR args, int nCmdShow){

    WNDCLASSW wc = {0};

    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;    // color of the window
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);   // shape of the cursor
    wc.hInstance = hInstance;                   // pass it windows main system handler
    wc.lpszClassName = L"myWindowClass";        // name of the window class
    wc.lpfnWndProc = WindowProcedure;

    if(!RegisterClassW(&wc)){
        return -1;
    }

    CreateWindowW(L"myWindowClass", L"My Window", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 1920/4, 1080/8, 320, 480,
        NULL,       // Parent window
        NULL,       // Menu
        NULL,       // Instance handle
        NULL        // Additional application data
        );

    MSG msg = {0};

    while(GetMessage(&msg, NULL, (uint64_t)NULL, (uint64_t)NULL)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }


    return 0;
}


LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp){
    switch(msg){

    case WM_COMMAND:
        switch(wp){

        case FILE_MENU_NEW:
            MessageBeep(MB_ICONINFORMATION);
            break;
        case FILE_MENU_OPEN:
            MessageBeep(MB_OK);
            break;
        case FILE_MENU_EXIT:
            break;

        case HOME_PAGE:
            main_page(hWnd);
            break;

        case PAGE1:
            page1(hWnd);
            break;
        case PAGE2:
            page2(hWnd);
            break;

        }

        break;

    case WM_CREATE:
        AddMenus(hWnd);
        main_page(hWnd);

        break;

//    case WM_PAINT:
//        InvalidateRect(hWnd, NULL, TRUE);
//        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    case WM_QUIT:

        break;


    default:
        return DefWindowProcW(hWnd, msg, wp, lp);

    }
    return 0;
}

void AddMenus(HWND hWnd){

    hMenu = CreateMenu();

    HMENU hFileMenu = CreateMenu();

    AppendMenu(hMenu, MF_POPUP, (UINT_PTR)hFileMenu, "File");
    AppendMenu(hMenu, MF_STRING, (uint64_t)NULL, "Help");

    HMENU hSubMenu = CreateMenu();
    AppendMenu(hSubMenu, MF_STRING, (uint64_t)NULL, "New 1");

    AppendMenu(hFileMenu, MF_POPUP, (UINT_PTR)hSubMenu, "New");
    AppendMenu(hFileMenu, MF_SEPARATOR, (uint64_t)NULL, 0);
    AppendMenu(hFileMenu, MF_STRING, FILE_MENU_OPEN, "Open");
    AppendMenu(hFileMenu, MF_SEPARATOR, (uint64_t)NULL, 0);
    AppendMenu(hFileMenu, MF_STRING, FILE_MENU_EXIT, "Exit");

    SetMenu(hWnd, hMenu);
}

void main_page(HWND hWnd){
    CreateWindowW(L"Static", L"main page", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 10, 180, 20, hWnd, NULL, NULL, NULL);

    CreateWindowW(L"Button", L"Page1", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 50, 180, 30, hWnd, (HMENU)PAGE1, NULL, NULL);
    CreateWindowW(L"Button", L"Page2", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 90, 180, 30, hWnd, (HMENU)PAGE2, NULL, NULL);
}

void page1(HWND hWnd){
    CreateWindowW(L"Static", L"Page1", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 10, 180, 20, hWnd, NULL, NULL, NULL);

    CreateWindowW(L"Button", L"P1 - button1", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 50, 180, 30, hWnd, NULL, NULL, NULL);
    CreateWindowW(L"Button", L"P1 - button2", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 90, 180, 30, hWnd, NULL, NULL, NULL);
    CreateWindowW(L"Button", L"P1 - button3", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 130, 180, 30, hWnd, NULL, NULL, NULL);

    CreateWindowW(L"Button", L"Main Page - P1", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 310, 180, 30, hWnd, (HMENU)HOME_PAGE, NULL, NULL);
}

void page2(HWND hWnd){
    CreateWindowW(L"Static", L"Page2", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 10, 180, 20, hWnd, NULL, NULL, NULL);

    CreateWindowW(L"Button", L"P2 - button1", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 50, 180, 30, hWnd, NULL, NULL, NULL);
    CreateWindowW(L"Button", L"P2 - button2", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 90, 180, 30, hWnd, NULL, NULL, NULL);
    CreateWindowW(L"Button", L"P2 - button3", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 130, 180, 30, hWnd, NULL, NULL, NULL);

    CreateWindowW(L"Button", L"Main Page - P2", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER
                  , 65, 310, 180, 30, hWnd, (HMENU)HOME_PAGE, NULL, NULL);
}


What I have tried:

Nothing actually.

I tried to create a new window, but that open a new window to the current one which is not what I want.
Posted
Updated 21-Nov-23 21:10pm
v2
Comments
Andre Oosthuizen 20-Nov-23 13:59pm    
And your code to do this where it error's is thus...
R1S8K 22-Nov-23 3:10am    
I added the code.
Richard MacCutchan 22-Nov-23 3:47am    
It is not clear what that code is supposed to do, apart from create lots of buttons, or what is has to do with your original question.
R1S8K 22-Nov-23 4:01am    
There are 3 pages: main_page, page1 and page2.

I'm simulating any system based on paging. It's like any menu contains a main system list.

Take this youtube video as an example:
https://www.youtube.com/watch?v=9Ms59ofSJIY

There are 3 buttons on the main page: distance, RGB control and a game.

So when I press one of the buttons I should transfer from the main page to the sub-page, and then I should have a button to go back to the main menu. That's my problem in win32 api, which is when I go back to the main_page, there are buttons left from page1 and page2.
Richard MacCutchan 22-Nov-23 4:22am    
Yes, because you are creating all the buttons in the same Window; that is the main window of the application. So you could change this by creating three client windows, and add each set of buttons to a different client. You then make each client visible or not visible as required. But I have to say even doing that, this is a really bad design.

1 solution

It depends where you are storing the data that you dispaly in the Window. The proper sequence of operations is to respond to the WM_PAINT message by displaying all the relevant information in the window, as controlled by any scrollbar positioning. So every time you modify the data to be displayed you should make a call to InvalidateRect function (winuser.h) - Win32 apps | Microsoft Learn[^]. This should clear the Window and post a WM_PAINT message to update the display.

If you have further detasils then please use the Improve question link above, and add them to your question.

[edit]
Here is a fairly basic sample, but it shows how to switch between the different client windows.

C++
#include <windows.h>				// general windows definitions

#pragma comment(lib, "user32")
#pragma comment(lib, "Gdi32")


#define	IDR_MAINFRAME	128
#define	ID_APP_EXIT		130
#define	GO_PAGE_1		150
#define	GO_PAGE_2		151
#define	GO_MAIN			152

HWND	hMainPage;
HWND	hPage_1;
HWND	hPage_2;

///
///
/// 
HWND CreatePage(
	HWND		hWndParent,
	PCSTR		szClassName,
	UINT		uWindowId
)
{
	HWND		hWnd;

	// create the child window
	hWnd = CreateWindowEx(
		0,			// extended window style
		szClassName,				// registered class name
		NULL,						// and window title
		WS_CHILD,		// window style
		0, 0, 0, 0,					// position and size of window
		hWndParent,					// handle to parent or owner window
		(HMENU)uWindowId,	// menu handle or child identifier
		GetModuleHandle(NULL),		// handle to application instance
		NULL						// sent with WM_CREATE message in CREATESTRUCT
	);

	return hWnd;
}


///
/// Handle the <c>WM_CREATE</c> message. Any one-time code or modifications
///
BOOL OnCreate(
	HWND			hWnd,
	LPCREATESTRUCT	pCreateStruct
)
{
	//	Register the child window class
	WNDCLASSEX	wndClassEx;	// class structure
	memset(&wndClassEx, 0, sizeof(wndClassEx));
	wndClassEx.cbSize = sizeof wndClassEx;
	wndClassEx.style = CS_HREDRAW | CS_VREDRAW;
	wndClassEx.lpfnWndProc = (WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
	wndClassEx.hInstance = GetModuleHandle(NULL);
	wndClassEx.hIcon = NULL;
	wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wndClassEx.lpszMenuName = NULL;
	wndClassEx.lpszClassName = "ChildView";
	wndClassEx.hIconSm = NULL;

	if (RegisterClassEx(&wndClassEx))
	{
		hMainPage = CreatePage(hWnd, wndClassEx.lpszClassName, IDR_MAINFRAME + 1);
		CreateWindow("Button", "Main Window", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER,
			65, 50, 180, 30, hMainPage, (HMENU)GO_PAGE_1, NULL, NULL);
		hPage_1 = CreatePage(hWnd, wndClassEx.lpszClassName, IDR_MAINFRAME + 2);
		CreateWindow("Button", "Page 1", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER,
			65, 100, 180, 30, hPage_1, (HMENU)GO_PAGE_2, NULL, NULL);
		hPage_2 = CreatePage(hWnd, wndClassEx.lpszClassName, IDR_MAINFRAME + 3);
		CreateWindow("Button", "Second page", WS_VISIBLE | WS_CHILD | WS_BORDER | SS_CENTER,
			65, 150, 180, 30, hPage_2, (HMENU)GO_MAIN, NULL, NULL);
		DWORD dwStyle = GetWindowLongPtr(hMainPage, GWL_STYLE);
		dwStyle |= WS_VISIBLE;
		SetWindowLongPtr(hMainPage, GWL_STYLE, dwStyle);
	}

	return TRUE;		// done!
}

///
/// handle the WM_SIZE message, to ensure the child window gets resized properly
///
void OnSize(
	HWND		hWnd,
	UINT		uState,
	int			nWidth,
	int			nHeight
)
{
	if (nWidth == 0)
		return;
	// resize the child window(s)
	MoveWindow(hMainPage, 0, 0, nWidth, nHeight, TRUE);
	MoveWindow(hPage_1, 0, 0, nWidth, nHeight, TRUE);
	MoveWindow(hPage_2, 0, 0, nWidth, nHeight, TRUE);
}


/// Handle the <c>WM_COMMAND</c> message.
/// Process user commands, as implemented by this application.
int OnCommand(
	HWND	hWnd,
	int		nCmdId,		// LOWORD(wParam)  Menu_ID,  Accelerator_ID,  Control_ID
	HWND	hWndCtl,	// (HWND)lParam    0         0                HWND of control
	UINT	codeNotify	//  HIWORD(wParam) 0 = Menu, 1 = Accelerator, X = notification code
)
{
	// Take action according to nCmdId
	switch (nCmdId)
	{
	case GO_PAGE_1:
	case GO_PAGE_2:
	case GO_MAIN:
	{
		HWND hWndFrom = nCmdId == GO_PAGE_1 ? hMainPage : nCmdId == GO_PAGE_2 ? hPage_1 : hPage_2;
		HWND hWndTo = nCmdId == GO_PAGE_1 ? hPage_1 : nCmdId == GO_PAGE_2 ? hPage_2 : hMainPage;
		ShowWindow(hWndFrom, SW_HIDE);
		ShowWindow(hWndTo, SW_NORMAL);
	}
		break;

	case ID_APP_EXIT:
		SendMessage(hWnd, WM_CLOSE, 0, 0);
		break;

	default:
		return 1;	// not handled
	}

	return 0;	// we did it
}


/// Dispatcher for the <c>WM_xxx</c> Windows messages.
/// Called to action the messages generated
/// in response to user actions on the main window.
LRESULT CALLBACK WindowProc(
	HWND	hWnd,
	UINT	uMessage,
	WPARAM	wParam,
	LPARAM	lParam
)
{
	switch (uMessage)
	{
	case WM_CREATE:
		return OnCreate(hWnd, (LPCREATESTRUCT)lParam);

	case WM_COMMAND:
		return OnCommand(hWnd, LOWORD(wParam), (HWND)lParam, HIWORD(wParam));

	case WM_SIZE:
		OnSize(hWnd, wParam, LOWORD(lParam), HIWORD(lParam));
		break;

	case WM_DESTROY:
		PostQuitMessage(0);	// application exit code 0
		break;

	default:
		return DefWindowProc(hWnd, uMessage, wParam, lParam);
	}

	return 0;	// the message was handled in the switch block
}


/// <summary>
/// Main function of the windows application.
/// 
int APIENTRY wWinMain(
	_In_		HINSTANCE	hInstance,
	_In_opt_	HINSTANCE	hPrevInstance,
	_In_		LPWSTR		lpCmdLine,
	_In_		int			nShowCmd
)
{
	int			nAppResult = -1;	// just in case something fails at initialisation


	WNDCLASSEX	wndClassEx;	// class structure
	HWND		hWnd = NULL;

	//	Initialise the window class structure
	memset(&wndClassEx, 0, sizeof(wndClassEx));
	wndClassEx.cbSize = sizeof wndClassEx;
	wndClassEx.style = CS_HREDRAW | CS_VREDRAW;
	wndClassEx.lpfnWndProc = WindowProc;
	wndClassEx.cbClsExtra = 0;
	wndClassEx.cbWndExtra = 0;
	wndClassEx.hInstance = hInstance;
	wndClassEx.hIcon = LoadIcon(hInstance, NULL);
	wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wndClassEx.lpszMenuName = NULL;
	wndClassEx.lpszClassName = "SampleApp";
	wndClassEx.hIconSm = NULL;

	if (RegisterClassEx(&wndClassEx))
	{
		// create the main frame window
		hWnd = CreateWindowEx(
			WS_EX_CLIENTEDGE,			// extended window style
			wndClassEx.lpszClassName,	// registered class name
			wndClassEx.lpszClassName,	// and window title
			WS_OVERLAPPEDWINDOW,		// window style
			CW_USEDEFAULT,				// horizontal position of window
			0,							// vertical position of window
			800,						// window width
			500,						// window height
			NULL,						// handle to parent or owner window
			NULL,						// menu handle or child identifier
			hInstance,					// handle to application instance
			NULL						// object pointer sent with WM_CREATE message in CREATESTRUCT
		);
		// display the main frame window
		ShowWindow(hWnd, SW_SHOWNORMAL);	// show the window frame and
		UpdateWindow(hWnd);					// update the client area
		MSG		msg;

		// Main message loop:
		while (GetMessage(&msg, NULL, 0, 0) > 0)
		{
			// returns when a WM_QUIT message appears
			TranslateMessage(&msg);
			DispatchMessage(&msg);	// calls the static WindowProc function
		}
		nAppResult = msg.wParam;
	}

	return nAppResult;
}


[/edit]
 
Share this answer
 
v3
Comments
Maciej Los 20-Nov-23 13:05pm    
5ed!
R1S8K 23-Nov-23 4:08am    
I got these errors:


-------------- Build: Release in code_project_example (compiler: GNU GCC Compiler)---------------

gcc.exe -Wall -O2  -c "D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c" -o obj\Release\main.o
gcc.exe  -o bin\Release\code_project_example.exe obj\Release\main.o  -s  
D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c: In function 'CreatePage':
D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c:32:3: error: 'reinterpret_cast' undeclared (first use in this function)
   reinterpret_cast<hmenu>(uWindowId), // menu handle or child identifier
   ^~~~~~~~~~~~~~~~
D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c:32:3: note: each undeclared identifier is reported only once for each function it appears in
D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c:32:20: error: expected expression before 'HMENU'
   reinterpret_cast<hmenu>(uWindowId), // menu handle or child identifier
                    ^~~~~
In file included from D:/Program_Files/CodeBlocks/MinGW/x86_64-w64-mingw32/include/winnt.h:9,
                 from D:/Program_Files/CodeBlocks/MinGW/x86_64-w64-mingw32/include/minwindef.h:163,
                 from D:/Program_Files/CodeBlocks/MinGW/x86_64-w64-mingw32/include/windef.h:8,
                 from D:/Program_Files/CodeBlocks/MinGW/x86_64-w64-mingw32/include/windows.h:69,
                 from D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c:1:
D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c:25:9: error: too few arguments to function 'CreateWindowExA'
  hWnd = CreateWindowEx(
         ^~~~~~~~~~~~~~
In file included from D:/Program_Files/CodeBlocks/MinGW/x86_64-w64-mingw32/include/windows.h:72,
                 from D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c:1:
D:/Program_Files/CodeBlocks/MinGW/x86_64-w64-mingw32/include/winuser.h:2137:26: note: declared here
   WINUSERAPI HWND WINAPI CreateWindowExA(DWORD dwExStyle,LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam);
                          ^~~~~~~~~~~~~~~
D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c: In function 'OnCreate':
D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c:50:23: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
  WNDCLASSEX wndClassEx{}; // class structure
                       ^
D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c:51:2: error: 'wndClassEx' undeclared (first use in this function); did you mean 'ReadClassStm'?
  wndClassEx.cbSize = sizeof wndClassEx;
  ^~~~~~~~~~
  ReadClassStm
D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c:53:27: error: 'reinterpret_cast' undeclared (first use in this function)
  wndClassEx.lpfnWndProc = reinterpret_cast<wndproc>(GetWindowLongPtr(hWnd, GWLP_WNDPROC));
                           ^~~~~~~~~~~~~~~~
D:\Programming\desktop_programming\C\windows api programming\code_project_example\code_project_example\main.c:53:44: error: expected expression before 'WNDPROC'
  wndClassEx.lpfnWndProc = reinterpret_cast<wndproc>(GetWindowLongPtr(hWnd, GWLP_WNDPROC));
                                            ^~~~~~~
... 
R1S8K 23-Nov-23 4:11am    
OK, I think your code is in C++
R1S8K 23-Nov-23 4:17am    
OK, I ran the code in C++ and changed the wWINMAIN to this one:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR args, int nCmdShow)


and it's working, the example runs smoothly and I got the idea. Now I need just to get the grasp on the example and embed it in my code.
Richard MacCutchan 23-Nov-23 4:38am    
Yes, I convedrted it from C++ and forgot about the cast. My apologies.

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