第七章 鼠标(CHECKER2)
CHECKER2程序包含一个键盘接口,内容与CHECKER1完全相同。利用←、→、↑、↓四个方向键可以在25个矩形之间移动鼠标指针。Home键把鼠标指针移动到左上角的矩形;End键使鼠标指针落到右下角的矩形。空格键和回车键都可以切换X形标记。
/*---------------------------------------------
CHECKER2.C -- Mouse Hit-Test Demo Program No.2
(c) Charles Petzold, 1998
---------------------------------------------*/ #include <Windows.h> #define DIVISIONS 5 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain( __in HINSTANCE hInstance
, __in_opt HINSTANCE hPrevInstance
, __in LPSTR lpCmdLine
, __in int nShowCmd )
{
static TCHAR szAppName[] = TEXT("Checker2");
HWND hwnd;
MSG msg;
WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = ;
wndclass.cbWndExtra = ;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("Program requires Windows NT!")
, szAppName, MB_ICONERROR);
return ;
} hwnd = CreateWindow(szAppName, TEXT("Checker2 Mouse Hit-Test Demo")
, WS_OVERLAPPEDWINDOW
, CW_USEDEFAULT, CW_USEDEFAULT
, CW_USEDEFAULT, CW_USEDEFAULT
, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd); while (GetMessage(&msg, NULL, , ))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} return msg.wParam;
} LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static BOOL fState[DIVISIONS][DIVISIONS];
static int cxBlock, cyBlock;
HDC hdc;
int x, y;
PAINTSTRUCT ps;
POINT point;
RECT rect; switch (message)
{
case WM_SIZE:
cxBlock = LOWORD(lParam) / DIVISIONS;
cyBlock = HIWORD(lParam) / DIVISIONS;
return ; case WM_SETFOCUS:
ShowCursor(TRUE);
return ; case WM_KILLFOCUS:
ShowCursor(FALSE);
return ; case WM_KEYDOWN:
GetCursorPos(&point);
ScreenToClient(hwnd, &point); x = max(, min(DIVISIONS - , point.x / cxBlock));
y = max(, min(DIVISIONS - , point.y / cyBlock)); 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 = y = ;
break; case VK_END:
x = y = DIVISIONS - ;
break; case VK_RETURN:
case VK_SPACE:
SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELONG(x * cxBlock, y * cyBlock));
break;
} x = (x + DIVISIONS) % DIVISIONS;
y = (y + DIVISIONS) % DIVISIONS; point.x = x * cxBlock + cxBlock / ;
point.y = y * cyBlock + cyBlock / ; ClientToScreen(hwnd, &point);
SetCursorPos(point.x, point.y);
return ; case WM_LBUTTONDOWN:
x = LOWORD(lParam) / cxBlock;
y = HIWORD(lParam) / cyBlock; if (x < DIVISIONS && y < DIVISIONS)
{
fState[x][y] ^= ; rect.left = x * cxBlock;
rect.top = y * cyBlock;
rect.right = (x + ) * cxBlock;
rect.bottom = (y + ) * cyBlock; InvalidateRect(hwnd, &rect, FALSE);
}
else
MessageBeep();
return ; case WM_PAINT:
hdc = BeginPaint(hwnd, &ps); for (x = ; x < DIVISIONS; ++x)
for (y = ; y < DIVISIONS; ++y)
{
Rectangle(hdc, x * cxBlock, y * cyBlock
, (x + ) * cxBlock, (y + ) * cyBlock); if (fState[x][y])
{
MoveToEx(hdc, x * cxBlock, y * cyBlock, NULL);
LineTo(hdc, (x + ) * cxBlock, (y + ) * cyBlock);
MoveToEx(hdc, x * cxBlock, (y + ) * cyBlock, NULL);
LineTo(hdc, (x + ) * cxBlock, y * cyBlock);
}
} EndPaint(hwnd, &ps);
return ; case WM_DESTROY:
PostQuitMessage();
return ;
} return DefWindowProc(hwnd, message, wParam, lParam);
}
CHECKER2.C
在CHECKER2程序中,处理WM_KEYDOWN时利用GetCursorPos判断指针的位置,并利用ScreenToClient将屏幕坐标转换成客户区坐标,然后将坐标值除以矩形块的宽和高,得到x和y。这些x和y的值表示了矩形在5*5数组中的位置。当按下某个键时,鼠标指针可能在客户区也可能不在客户区内,因此x和y必须包含在min和max的宏处理中,保证它们的范围处于0和4之间。
对于方向键,CHECKER2程序相应的增加或减少x和y的值。若按下回车键或空格键,CHECKER2程序调用SendMessage给自己发送一个WM_LBUTTONDOWN消息。最后,WM_KEYDOWN处理逻辑计算得到指向矩形中心的客户区坐标,并调用ClientToScreen将其转换成屏幕坐标,最后调用SetCursorPos设置指针的位置。
第七章 鼠标(CHECKER2)的更多相关文章
- 第七章 鼠标(CHECKER1)
CHECKER1程序将客户区划分成25个矩形,构成一个5*5的数组.如果在其中一个矩形内单击鼠标,就用X形填充该矩形.再次单击,则X形消失. /*--------------------------- ...
- 第七章 鼠标(CHECKER4)
/*--------------------------------------------- CHECKER4.C -- Mouse Hit-Test Demo Program No.4 (c) C ...
- 第七章 鼠标(CHECKER3)
/*--------------------------------------------- CHECKER3.C -- Mouse Hit-Test Demo Program No.3 (c) C ...
- 第七章 鼠标(CONNECT)
/* CONNECT.C -- Connect-the-Dots Mouse Demo Program (c) Charles Petzold,1998 */ #include <Windows ...
- 第七章 探秘Qt的核心机制-信号与槽
第七章 探秘Qt的核心机制-信号与槽 注:要想使用Qt的核心机制信号与槽,就必须在类的私有数据区声明Q_OBJECT宏,然后会有moc编译器负责读取这个宏进行代码转化,从而使Qt这个特有的机制得到使用 ...
- (转)iOS Wow体验 - 第七章 - 操作图例与触屏人机工学
本文是<iOS Wow Factor:Apps and UX Design Techniques for iPhone and iPad>第七章译文精选,其余章节将陆续放出.上一篇:Wow ...
- 【转】第七章、Linux 文件与目录管理
原文网址:http://vbird.dic.ksu.edu.tw/linux_basic/0220filemanager.php 第七章.Linux 文件与目录管理 最近升级日期:2009/08/26 ...
- 【知识强化】第七章 输入/输出系统 7.1 I/O系统基本概念
那么下面,我们将要进入计算机组成原理的最后一章,也就是我们的第七章,输入输出系统的学习.那么这一部分内容呢,我们之前呢一直在提,但是并没有详细地讲解,那么进入到我们第七章输入输出系统这一部分,我们就要 ...
- 精通Web Analytics 2.0 (9) 第七章:失败更快:爆发测试与实验的能量
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第七章:失败更快:爆发测试与实验的能量 欢迎来到实验和测试这个棒极了的世界! 如果Web拥有一个超越所有其他渠道的巨大优势,它就 ...
随机推荐
- 课程五(Sequence Models),第一 周(Recurrent Neural Networks) —— 0.Practice questions:Recurrent Neural Networks
[解释] It is appropriate when every input should be matched to an output. [解释] in a language model we ...
- Asp.net core 跨域设置
验证环境: dotnet core 2.1/Asp.net core2.1 一.作用域在中间件层 配置的方式是在startup.cs文件Configure(IApplicationBuilder a ...
- iOS开发工具
Xcode插件 几乎所有开发者都知道Alcatraz是一个开源的包管理工具,可以让我们更轻松地管理各种插件.接下来就介绍下我的最推荐的10个插件: 15.FuzzyAutocompletePlugin ...
- AIOps 在腾讯的探索和实践
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由LemonLu发表于云+社区专栏 赵建春 腾讯 技术运营通道主席 腾讯 社交网络运营部助理总经理 AIOps 白皮书核心编写专家 我今 ...
- Spring @Pathvariable
先记录下@PathVariable的用法吧: @RequestMapping("/demo/{id}") @ResponseBody public User getUser(@Pa ...
- MultipartFile 多文件上传的应用
公司的项目很多地方要用到文件上传,以前的上传主要是用apache的fileupload ,使用的感受并不太好.今天试了试spring的MultipartFile,感觉还不错,封装的比较简洁. 当然,中 ...
- 搭建前端监控系统(二)JS错误监控篇
===================================================================== 前端性能监控系统: DEMO地址 GIT代码仓库地址 ...
- [NOI 2017]游戏
Description 题库链接 小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 A.B.C 表示.地图一共 ...
- IDEA配置maven(配置阿里云中央仓库)
前言 idea配置maven后如果不修改中央仓库地址创建maven则出奇的慢,不管你用MyEclipse还是idea都慢的不要不要的,实在不能忍受. 这种条件下发现一个阿里云中央仓库来点福利,有福利了 ...
- MONGODB(四)——DBObject与JavaBean转换
一.DBObject 转为 JavaBean /** * 将实体Bean对象转换成DBObject * */ public static <T> DBObject beanToDBObje ...