-
big leap
Hello. I am just learning the basics of the win32 API at the moment and I realise that I need to actually create a functioning app before I can get the real gist of it. I have written a simple Tic Tac Toe game in C++ (Console) and I was wondering if anyone has some tips on which cases handle things the best.
My plan is to have 9 child windows populating the top level window and they respond to the user clicking on them. I am just concerned with what to do with all these clicks!
I have a vague idea that the parent will get sent a message from the kids and I need to tell the 'engine' (LOL) everytime parent gets one of these.
I am thinking that the 'engine' will live in the WM_COMMAND case and may send messages to a sub switch of WM_CREATE, for displaying wins and so fourth, but I would like some expert advice on whether I am heading down the right path or not. Any pointers would be much appreciated.
PS I think win32 programming will be great fun!
-
It would be simpler if you drew the tic-tac-toe board on the main window, instead of using nine child windows:
To make the code easier to maintain, break the code into functions.
Code:
#define SQUARE_BLANK 0
#define SQUARE_X 1
#define SQUARE_O 2
void DrawSquare(HDC hdc, int x, int y, int square){
switch(square){
case SQUARE_BLANK:
// draw a blank square
break;
case SQUARE_X:
// draw an X
break;
case SQUARE_O:
// draw an O
break;
}
}
// in the window procedure
// mouse click handler
case WM_LBUTTONDOWN:{
POINT pt;
int x,y;
GetCursorPos(&pt);
x=GetClickedColumn(hwnd,&pt); // app-defined function
y=GetClickedRow(hwnd,&pt); // app-defined function
squares[x][y]=CurrentSquareType;
// app-defined function - returns X, O, or BLANK
CurrentSquareType=GetNextSquare(CurrentSquareType);
break;
}
// drawing handler
case WM_PAINT:{
HDC hdc;
PAINTSTRUCT ps;
int i,j;
hdc=BeginPaint(hwnd,&ps);
for(i=0;i<3;i++){
for(j=0;j<3;j++){
DrawSquare(hdc,i,j,squares[i][j]);
}
}
EndPaint(hwnd,&ps);
break;
}
Something like this to get you started. You shouldn't send or post a WM_CREATE message to the window after its creation.
WM_COMMAND messages are usually processed through notifications by menus and standard Windows controls. Since this program is to be kept as simple as possible, no WM_COMMAND processing is necessary, unless you want to add a menu.
To exit the program, process the WM_CLOSE message by calling PostQuitMessage:
Code:
case WM_CLOSE:
PostQuitMessage(0);
break;
-
As poccil says nine windows is a bit much.
I would use an array of 9 RECT structs for the indvidual squares
Then you can use a loop and the
PtInRect() function with the mouse click coods on a WM_LBUTTONDOWN msg.
Something like this
Code:
case WM_LBUTTONDOWN:
POINTSTOPOINT(ptsClient,MAKEPOINTS(lParam));
CopyMemory(&ptsScreen,&ptsClient,sizeof(POINT));
GetWindowRect(hWnd,&rScreenRect);
ClientToScreen(hWnd,&ptsScreen);
if(!PtInRect(&rScreenRect,ptsScreen))//is not in main window
break;
for(i=0;i<9;i++)
{
if(PtInRect(&rBoardRect[i],ptsClient))
{
//this square was clicked
-
Thanks very much fellas! I think with your advice I can really start playing around with this program. And I think this one incorporates enough to submerge me into the world of win32 and get thinking the right way. Once again thanks.