Im teaching myself the Win32 API, so im messing around learning functions and what not. So how do I change the text on the button if it is clicked? I cant figure it out. Thanks

#include <windows.h>

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

const int ID_TIMER = 1;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	WNDCLASS win;
	MSG message;

	HWND main;

	HWND button1;

	win.cbClsExtra = 0;
	win.cbWndExtra = 0;
	win.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	win.hCursor = LoadCursor(NULL, IDC_ARROW);
	win.hIcon = NULL;
	win.hInstance = hInstance;
	win.lpfnWndProc = WndProc;
	win.lpszClassName = TEXT("MAIN");
	win.lpszMenuName = 0;
	win.style = CS_HREDRAW | CS_VREDRAW;

	RegisterClass(&win);

	main = CreateWindow(TEXT("MAIN"), TEXT("BitMap"), WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);
	button1 = CreateWindow(TEXT("BUTTON"), TEXT("Button"), WS_CHILD | WS_VISIBLE, 10, 10, 50, 50, main, NULL, hInstance, NULL);

	ShowWindow(main, nShowCmd);

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

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
		case WM_CREATE:

			UINT timer;
			
			timer = SetTimer(hwnd, ID_TIMER, 1000, NULL);

			break;

		
		case WM_TIMER:

			SendMessage(hwnd, WM_SETTEXT, 0,(LPARAM)TEXT("Testing Timer"));

			break;

		case WM_COMMAND:

			break;

		case WM_DESTROY:

			PostQuitMessage(0);
			break;

	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}

That's really easy. A button, as is just about everything else in Windows, is a 'window'; no pun intended. To change the text associated with many windows you use the SetWindowText() Api function, i.e.,

SetWindowText(hCtl, "Some New Text");

Of course, if you want to change it in response to a click of that specific button, you need to catch the click in your Window Procedure, then change it in the button click handler.

I can post code tomorrow if you don't figure it out in the meantime.

Edited 6 Years Ago by Frederick2: n/a

That's really easy. A button, as is just about everything else in Windows, is a 'window'; no pun intended. To change the text associated with many windows you use the SetWindowText() Api function, i.e.,

SetWindowText(hCtl, "Some New Text");

Of course, if you want to change it in response to a click of that specific button, you need to catch the click in your Window Procedure, then change it in the button click handler.

I can post code tomorrow if you don't figure it out in the meantime.

Ya, I had figured out the SetWindowText function, using it under the WM_COMMAND message, but I cant figure out how to make it specific. AKA if I have more then one button, it will change the text of the button handle no matter which of the buttons I click. And I cant switch the wParam under the WM_COMMAND message because I only have handles and no way to ID the buttons.

Ya, I had figured out the SetWindowText function, using it under the WM_COMMAND message, but I cant figure out how to make it specific. AKA if I have more then one button, it will change the text of the button handle no matter which of the buttons I click. And I cant switch the wParam under the WM_COMMAND message because I only have handles and no way to ID the buttons.

When you create a button window you should be using equates/defines to save your Ctrl Ids of the child windows ( the HMENU parameter in the CreateWindow() call). I never, never make unique HWND variables for child windows. The equates/defines serve as proxies, so to speak, for the HWNDs because if you know the parent which contains the child window, i.e., in your case a button, you can get the HWND with a call to GetDlgItem() like so...

hButton=GetDlgItem(hParent, IDC_SOME_BUTTON_CONTROL);

Having obtained the hButton you want to change the text on, then just do a SetWindowText() call.

You know, the HWND contained in the HIWORD of wParam I think will also give you this.

Edited 6 Years Ago by Frederick2: n/a

Is this what you mean?

HWND button1;

button1 = GetDlgItem(main, but1);

main being the parent, and but1 being a #define statement?

If i do this, ShowWindow doesnt work so how do I display it now?

Edit: Sorry for not understanding =(

Im also trying this, which it will compile and run, but once I click a button it crashes.

button1 = CreateWindow(TEXT("BUTTON"), TEXT("Button"), WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 10, 10, 50, 50, main, (HMENU)but1,	(HINSTANCE)GetWindowLong(main, GWL_HINSTANCE), NULL);
	
button2 = CreateWindow(TEXT("BUTTON"), TEXT("Button2"), WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 60, 60, 50, 50, main, (HMENU)but2, (HINSTANCE)GetWindowLong(main, GWL_HINSTANCE), NULL);

////in the wnd proc

	case WM_COMMAND:

			switch(LOWORD(wParam))
			{
			case but1:
				break;

			case but2:
				break;
			}

but1 and but2 are defined using #define above winmain.

Edit (again...) Ok, so I just needed another break statement, it was hitting my PostQuitMessage because it was falling through. So cool, but can you still explain what you were trying to tell me so I can understand whats going on? Thanks

Edited 6 Years Ago by LevyDee: n/a

Ok cool, so I have everything set up. What ive been trying to do is set up my GUI for a Tic tac toe game. I have already made a console version and want to "port" it to a GUI. So my next question would be some general thoughts or opinions on how to do this. My original tic tac toe console game has a header file which includes my class declaration to hold any data or functions needed. A source that defines the class data, and my main which calls the game loop.

So I guess, does my GetMessage loop replace my main game loop now? And anything else you guys want to add will help! Thanks!

This is my GUI setup.

//My handles and defines are declared in my resource header

#include <windows.h>
#include "resource.h"


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	WNDCLASS board;
	
	board.cbClsExtra = 0;
	board.cbWndExtra = 0;
	board.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	board.hCursor = LoadCursor(NULL, IDC_ARROW);
	board.hIcon = NULL;
	board.hInstance = hInstance;
	board.lpfnWndProc = WndProc;
	board.lpszClassName = TEXT("T3");
	board.lpszMenuName = NULL;
	board.style = CS_VREDRAW | CS_HREDRAW;

	RegisterClass(&board);

	main = CreateWindowEx(NULL, TEXT("T3"), TEXT("Tic-Tac-Toe"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, 600, 350, 300, 300, NULL, NULL, hInstance, NULL);

	button1 = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT(" "), WS_CHILD | WS_VISIBLE, 10, 10, 50, 50, main, (HMENU)but1, hInstance, NULL);

	button2 = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT(" "), WS_CHILD | WS_VISIBLE, 70, 10, 50, 50, main, (HMENU)but2, hInstance, NULL);

	button3 = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT(" "), WS_CHILD | WS_VISIBLE, 130, 10, 50, 50, main, (HMENU)but3, hInstance, NULL);

	button4 = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT(" "), WS_CHILD | WS_VISIBLE, 10, 70, 50, 50, main, (HMENU)but4, hInstance, NULL);

	button5 = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT(" "), WS_CHILD | WS_VISIBLE, 70, 70, 50, 50, main, (HMENU)but5, hInstance, NULL);

	button6 = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT(" "), WS_CHILD | WS_VISIBLE, 130, 70, 50, 50, main, (HMENU)but6, hInstance, NULL);

	button7 = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT(" "), WS_CHILD | WS_VISIBLE, 10, 130, 50, 50, main, (HMENU)but7, hInstance, NULL);

	button8 = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT(" "), WS_CHILD | WS_VISIBLE, 70, 130, 50, 50, main, (HMENU)but8, hInstance, NULL);

	button9 = CreateWindowEx(NULL, TEXT("BUTTON"), TEXT(" "), WS_CHILD | WS_VISIBLE, 130, 130, 50, 50, main, (HMENU)but9, hInstance, NULL);

	playerTurn = CreateWindowEx(NULL, TEXT("STATIC"), TEXT(" tst"), WS_CHILD | WS_VISIBLE, 10, 200, 50, 50, main, (HMENU)player, hInstance, NULL);
	
		
	MSG message;

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

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
		case WM_COMMAND:

			switch(LOWORD(wParam))
			{
				case but1:

					SetWindowText(button1, TEXT(" 1")); // The text will point to a string based on what player turn it is I assume? etc... and so on
			                break;              

				case but2:

					SetWindowText(button2, TEXT(" 2"));
					break;

				case but3:

					SetWindowText(button3, TEXT(" 3"));
					break;

				case but4:

					SetWindowText(button4, TEXT(" 4"));
					break;

				case but5:

					SetWindowText(button5, TEXT(" 5"));
					break;

				case but6:

					SetWindowText(button6, TEXT(" 6"));
					break;

				case but7:

					SetWindowText(button7, TEXT(" 7"));
					break;

				case but8:

					SetWindowText(button8, TEXT(" 8"));
					break;

				case but9:
					
					SetWindowText(button9, TEXT(" 9"));
					break;
			}

			break;			

		case WM_DESTROY:

			PostQuitMessage(0);
			break;
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}

Edited 6 Years Ago by LevyDee: n/a

This article has been dead for over six months. Start a new discussion instead.