Hey guys, I've recently started learning WinAPI and I want to make a Tic Tac Toe game with it but I have a problem
I have a main window ("field") and 9 child windows ("tiles") and I want to make the tiles clickable so that a click calls the Beep() function. I also want to make each tile able to call Beep() only once (just like you can put a cross only once in the tile in tic tac toe). So I have this code:
#include <windows.h>
LPCWSTR FldClass = L"FieldClass";
LPCWSTR TileClass = L"TileClass";
LRESULT CALLBACK MainProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK TileProc(HWND, UINT, WPARAM, LPARAM);
void RegisterTile();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nShowCmd)
{
// Registering the "field" class - the main window
WNDCLASSEX Field;
ZeroMemory(&Field, sizeof(Field));
Field.cbSize = sizeof(Field);
Field.hbrBackground = (HBRUSH)(COLOR_WINDOW);
Field.hCursor = LoadCursor(NULL, IDC_ARROW);
Field.hInstance = hInstance;
Field.lpfnWndProc = MainProc;
Field.lpszClassName = FldClass;
Field.style = CS_VREDRAW | CS_HREDRAW;
RegisterClassEx(&Field);
// Creating the main window
HWND FldWnd = CreateWindowEx(0, FldClass, L"Tic-Tac-Toe!", WS_OVERLAPPEDWINDOW,
150, 150, 400, 420, 0, 0, hInstance, 0);
ShowWindow(FldWnd, nShowCmd);
UpdateWindow(FldWnd);
// Message loop
MSG msg;
while ( GetMessage(&msg, FldWnd, 0, 0) > 0 )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// The Field Procedure
LRESULT CALLBACK MainProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
HWND Tiles[9];
RegisterTile();
//creating the tiles
Tiles[0] = CreateWindowEx(0, TileClass, NULL, WS_CHILD | WS_VISIBLE,
20, 20, 100, 100, hwnd, (HMENU) 1, 0, 0);
Tiles[1] = CreateWindowEx(0, TileClass, NULL, WS_CHILD | WS_VISIBLE,
140, 20, 100, 100, hwnd, (HMENU) 2, 0, 0);
Tiles[2] = CreateWindowEx(0, TileClass, NULL, WS_CHILD | WS_VISIBLE,
260, 20, 100, 100, hwnd, (HMENU) 3, 0, 0);
Tiles[3] = CreateWindowEx(0, TileClass, NULL, WS_CHILD | WS_VISIBLE,
20, 140, 100, 100, hwnd, (HMENU) 4, 0, 0);
Tiles[4] = CreateWindowEx(0, TileClass, NULL, WS_CHILD | WS_VISIBLE,
140, 140, 100, 100, hwnd, (HMENU) 5, 0, 0);
Tiles[5] = CreateWindowEx(0, TileClass, NULL, WS_CHILD | WS_VISIBLE,
260, 140, 100, 100, hwnd, (HMENU) 6, 0, 0);
Tiles[6] = CreateWindowEx(0, TileClass, NULL, WS_CHILD | WS_VISIBLE,
20, 260, 100, 100, hwnd, (HMENU) 7, 0, 0);
Tiles[7] = CreateWindowEx(0, TileClass, NULL, WS_CHILD | WS_VISIBLE,
140, 260, 100, 100, hwnd, (HMENU) 8, 0, 0);
Tiles[8] = CreateWindowEx(0, TileClass, NULL, WS_CHILD | WS_VISIBLE,
260, 260, 100, 100, hwnd, (HMENU) 9, 0, 0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
// Function to register the tile class
void RegisterTile()
{
WNDCLASSEX Tile = {0};
HBRUSH hBrush = CreateSolidBrush( RGB(100, 100, 100) );
Tile.cbSize = sizeof(Tile);
Tile.lpszClassName = TileClass;
Tile.hbrBackground = hBrush;
Tile.lpfnWndProc = TileProc;
Tile.hCursor = LoadCursor(0, IDC_HAND);
RegisterClassEx(&Tile);
}
//The tile procedure
LRESULT CALLBACK TileProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static bool empty = true;
switch(msg)
{
case WM_LBUTTONUP:
{
if (empty)
{
Beep(220, 300);
empty = false;
}
break;
}
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
Unfortunately the 'empty' variable affects all the tiles so after clicking one of them for the first time, none of them work will call Beep() anymore. How do I associate the 'empty' variable and the tile window itself?