在客户区画出6*6的网格,对网格进行点击,网格变色并标记,再次点击则去除标记。
利用键盘的上下左右,可以移动鼠标,回车或者空格模拟鼠标左键点击。
代码实例:
#define _CRT_SECURE_NO_WARNINGS 1 #include#include #include #define NUMBERS 5 #define DIVS 6 //#include"sysmets.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) //主函数 // 四个参数: //hInstance : 程序当前实例的句柄(handle to current instance),以后随时可以用GetModuleHandle(0)来获得 //hPrevInstance : 前一个实例的句柄(handle to previous instance),在Win32中,每一个进程都有一个独立的4G地址空间,从0到2G属于进程私有,对其他进程来说是不可见的。所以,在Win32中,hPrevInstance总是为NULL。 //szCmdLine : 指向以 / 0结尾的命令行,不包括EXE本身的文件名(pointer to command line),以后随时可以用GetCommandLine()来获取完整的命令行。 //iCmdShow : 指明应该以什么方式显示主窗口(show state of window)。 { static TCHAR szAppName[] = TEXT("MyWindows"); HWND hwnd;//句柄 MSG msg;//消息 WNDCLASS wndclass;//定义窗口类结构 HBRUSH hCulorBrush = CreateSolidBrush(RGB(200, 200, 200));//设定背景颜色 //结构成员: wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口类型 wndclass.lpfnWndProc = WndProc; //窗口过程(必须是回调函数) wndclass.cbClsExtra = 0;//预留的额外空间,一般为0 wndclass.cbWndExtra = 0;//预留的额外空间,一般为0 wndclass.hInstance = hInstance;//应用程序的实例句柄 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);//为所有基于该窗口类的窗口设定一个图标 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);//为所有基于该窗口类的窗口设定一个鼠标指针 //wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//指定窗口背景色 wndclass.hbrBackground = hCulorBrush;//指定窗口背景色 wndclass.lpszMenuName = NULL; //指定窗口菜单 wndclass.lpszClassName = szAppName; //指定窗口类名 //注册窗口类 if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("这个程序需要在Windows系统执行!"), szAppName, MB_ICONERROR); return 0; } //实例化创建窗口 hwnd = CreateWindow(szAppName,// 窗口类名称 TEXT("中年人学C语言Windows程序设计"),// 窗口标题 WS_OVERLAPPEDWINDOW | WS_VSCROLL,// 窗口风格,或称窗口格式 CW_USEDEFAULT,// 初始 x 坐标 CW_USEDEFAULT, // 初始 y 坐标 CW_USEDEFAULT,// 初始 x 方向尺寸 CW_USEDEFAULT,// 初始 y 方向尺寸 NULL,// 父窗口句柄 NULL,// 窗口菜单句柄 hInstance,// 程序实例句柄 NULL);// 创建参数 //显示窗口 ShowWindow(hwnd, iCmdShow); //更新窗口 UpdateWindow(hwnd); //消息循环 while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { 回调函数 参数: hwnd : 窗口句柄 message : 消息ID wParam和lParam:消息参数 //int i; //size_t j; static BOOL isState[DIVS][DIVS]; HDC hdc;//定义设备环境句柄 static TCHAR szBuffer[128]; PAINTSTRUCT ps; RECT rect; size_t iStrLength; static int cxBlock, cyBlock, cxClient, cyClient; int x, y; int i, j; HBRUSH hBrush, hOldBrush; POINT pt; switch (message) { case WM_SIZE://窗体大小改变 { hdc = GetDC(hWnd); //GetClientRect(hwnd, &rect); cxClient = LOWORD(lParam);//当前x像素 cyClient = HIWORD(lParam);//当前y像素 cxBlock = cxClient / DIVS; cyBlock = cyClient / DIVS; StringCchPrintf(szBuffer, 128, TEXT("当前客户区的分辨率:%d * %d px"), cxClient, cyClient); StringCchLength(szBuffer, 128, &iStrLength); SetTextAlign(hdc, TA_CENTER | TA_TOP); TextOut(hdc, cxClient / 2, 0, szBuffer, iStrLength); ReleaseDC(hWnd, hdc); return 0; } case WM_PAINT://窗口绘画:点 { //int x, xLast; HDC hdc = BeginPaint(hWnd, &ps);//函数为指定窗口进行绘画作准备,并用将和绘画有关的信息填充到一个 PAINTSTRUCT 结构中。 for (i = 0; i < DIVS; i++)//循环画矩形 { for (j = 0; j < DIVS; j++)//循环画矩形 { Rectangle(hdc, i * cxBlock, j * cyBlock, (i + 1) * cxBlock, (j + 1) * cyBlock);//循环画矩形 //DeleteObject(SelectObject(hdc, hOldBrush)); if (isState[i][j] == TRUE)//如果标识为true 则画×, { hBrush = CreateSolidBrush(RGB(255, 0, 255));//背景设置成紫色 hOldBrush = SelectObject(hdc, hBrush); Rectangle(hdc, i * cxBlock, j * cyBlock, (i + 1) * cxBlock, (j + 1) * cyBlock);//重画矩形 DeleteObject(SelectObject(hdc, hOldBrush)); MoveToEx(hdc, i * cxBlock, j * cyBlock, NULL);//画X LineTo(hdc, (i + 1) * cxBlock, (j + 1) * cyBlock); MoveToEx(hdc, (i + 1) * cxBlock, j * cyBlock, NULL); LineTo(hdc, i * cxBlock, (j + 1) * cyBlock); } } } EndPaint(hWnd, &ps); return 0; } case WM_LBUTTONDOWN: { x = GET_X_LPARAM(lParam) / cxBlock; y = GET_Y_LPARAM(lParam) / cyBlock; if (x < DIVS && y < DIVS) { isState[x][y] ^= 1;//异或操作,也就是点击一下为TRUE,点击两下为FALSE InvalidateRect(hWnd, NULL, FALSE);//重绘整个客户区 } else { MessageBeep(0); } return 0; } case WM_KEYDOWN://通过键盘控制鼠标位置 { GetCursorPos(&pt);//获取当前鼠标坐标 ScreenToClient(hWnd,&pt);//转化为客户区坐标 x = max(0, min(pt.x / cxBlock, DIVS - 1));//计算当前鼠标所在的矩形位置 y = max(0, min(pt.y / cyBlock, DIVS - 1)); switch(wParam) { case VK_UP://按下键盘上键 y--; break; case VK_DOWN: y++; break; case VK_LEFT: x--; break; case VK_RIGHT: x++; break; case VK_HOME: x = 0; y = 0; break; case VK_END: x=y = DIVS - 1; break; case VK_RETURN://空格和回车,模拟点击动作 case VK_SPACE: SendMessage(hWnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(x * cxBlock, y * cyBlock));//对矩形进行绘制 break; } x = (x + DIVS) % DIVS;//对矩形位置进行处理,超出范围可从头循环显示 y = (y + DIVS) % DIVS; pt.x = x * cxBlock+ cxBlock/2;//计算键盘操作后鼠标位置 pt.y = y * cyBlock + cyBlock / 2; ClientToScreen(hWnd, &pt);//客户区坐标转换为屏幕坐标 SetCursorPos(pt.x, pt.y);//设置新的鼠标坐标 return 0; } case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }



