SimpleCG程序交互操作

 前言

        之前所有示例程序都是属于展示型的,只是作为展示板输出使用,不涉及键盘和鼠标的输入交互,下面我们开始接触具有交互功能的程序。

        没有交互功能的程序可以满足一定需求,不过大部分的程序是不能脱离交互功能的。程序依据使用者的操作进行相应反应并进行相关输出从而达到互动,将让程序的魅力提高一个层次。一个典型的应用就是游戏,所以学习完本篇内容后将可以进行一些游戏程序的编写。当前SimpleCG库主要支持的输入操作是鼠标和键盘,下面看看具体如何操作吧。

一、消息处理基础

        想要在SimpleCG中处理Windows的交互操作,就是需要定义一个消息处理函数,消息处理函数名字可以随便定义,但形式是固定的。例如鼠标消息固定形式如下所示:

LRESULT OnLButtonDown( HWND hWnd, WPARAM wParam, int nX, int nY )
{
}

名字OnLButtonDown是可以自己定义的,一般也是按消息功能命名。定义完消息函数后,依据想要接收的消息进行注册,所谓注册也就是调用一个设置函数。例如想要接收左键点击消息,按如下方式设置:

SetMouseProcess( enumINMSG_LBUTTONDOWN, OnLButtonDown);

这里要注意的是,设置函数一定要在初始化阶段设置,一般是程序开始处设置。

二、鼠标操作

支持的鼠标消息如下所示:

    enumINMSG_MOUSEMOVE            //鼠标移动, enumINMSG_LBUTTONDOWN        //左键按下, enumINMSG_LBUTTONUP          //左键抬起, enumINMSG_LBUTTONDBLCLK      //左键双击, enumINMSG_RBUTTONDOWN        //右键按下, enumINMSG_RBUTTONUP          //右键抬起, enumINMSG_RBUTTONDBLCLK      //右键双击, enumINMSG_MBUTTONDOWN        //中键按下, enumINMSG_MBUTTONUP          //中键抬起, enumINMSG_MBUTTONDBLCLK      //中键双击, enumINMSG_MOUSEWHEEL         //滚轮消息

当需要处理相应消息时,只要按上面说到的两个步骤定义相应函数即可。下面用一个绘图功能的程序来演示一下鼠标左键消息的处理。

#include "../import/include/CGBoard.h"
#include "math.h"
#ifdef _DEBUG
#pragma comment(lib,"../import/lib/SimpleCG_MDd.lib")
#else
#pragma comment(lib,"../import/lib/SimpleCG_MD.lib")
#endifint g_nWidth = 500;		//画面宽度
int g_nHeight= 400;		//画面高度int g_bIsDrawing = 0;
POINT g_ptLast;
void DrawProcess()
{
}LRESULT OnLButtonDown( HWND hWnd, WPARAM wParam, int nX, int nY )
{g_ptLast.x = nX;g_ptLast.y = nY;g_bIsDrawing = 1;return TRUE;
}
LRESULT OnLButtonUp( HWND hWnd, WPARAM wParam, int nX, int nY )
{if(g_bIsDrawing){line(g_ptLast.x,g_ptLast.y,nX,nY);g_ptLast.x = nX;g_ptLast.y = nY;g_bIsDrawing = 0;}return TRUE;
}
LRESULT OnMouseMove( HWND hWnd, WPARAM wParam, int nX, int nY )
{if(g_bIsDrawing){line(g_ptLast.x,g_ptLast.y,nX,nY);g_ptLast.x = nX;g_ptLast.y = nY;}return TRUE;
}int _tmain(int argc, _TCHAR* argv[])
{//设置消息处理函数SetMouseProcess( enumINMSG_LBUTTONDOWN, OnLButtonDown);SetMouseProcess( enumINMSG_LBUTTONUP,	OnLButtonUp);SetMouseProcess( enumINMSG_MOUSEMOVE,	OnMouseMove);//初始化if( !ShowingBoard(g_nWidth,g_nHeight, DrawProcess))return 1;//关闭图库CloseBoard();return 0;
}

该程序可以用鼠标在窗口点击要绘制的地方,然后移动鼠标绘制出鼠标轨迹,直至左键抬起。

另外函数

LRESULT OnLButtonDown( HWND hWnd, WPARAM wParam, int nX, int nY )
{
}

 中各参数意义如下:

hWnd是窗口句柄,暂时不需要了解

wParam附带有消息产生时的按键信息,可通过如下方法判断。

MK_CONTROL 按下了 CTRL 键。
MK_LBUTTON 按下了鼠标左键。
MK_MBUTTON 按下了鼠标中键。
MK_RBUTTON 按下了鼠标右键。
MK_SHIFT 按下了 SHIFT 键。
MK_XBUTTON1 按下了第一个 X 按钮。
MK_XBUTTON2 按下了第二个 X 按钮。

例如通过代码

if(wParam&MKCONTROL)就可以判断CTRL键是否按下。

nX和nY是鼠标在窗口中的坐标

三、键盘消息

 键盘支持的消息如下:

    enumINMSG_KEYDOWN    //按键按下, enumINMSG_KEYUP    //按键放开

按键消息响应函数如下

//按键消息响应函数
LRESULT OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
}

其中wParam代表当前虚拟键,各个虚拟键值可在此网站查找。

lParam是32位数含义如下:

0-15    当前消息的重复计数。 该值是由于用户按住键而自动重复击键的次数。 
16-23    扫描代码。 该值取决于 OEM。
24    指示键是扩展键,例如在增强型 101 键或 102 键键盘上显示的右侧 Alt 键和 Ctrl 键。 如果是扩展键,则值为 1;否则为 0。
25-28    保留;请勿使用。
29    上下文代码。 对于 WM_KEYDOWN 消息,该值始终为 0。
30    上一个键状态。 如果键在发送消息之前关闭,则值为 1;如果键已打开,则值为 0。
31    转换状态。 对于 WM_KEYDOWN 消息,该值始终为 0。

下面用一个可以用方向键控制移动的小球来演示按键的交互

#include "../import/include/CGBoard.h"
#include "math.h"
#ifdef _DEBUG
#pragma comment(lib,"../import/lib/SimpleCG_MDd.lib")
#else
#pragma comment(lib,"../import/lib/SimpleCG_MD.lib")
#endifint g_nWidth = 500;		//画面宽度
int g_nHeight= 400;		//画面高度int g_nXCircle = 100;
int g_nYCircle = 100;
void DrawProcess()
{setfillcolor(RGB(0xAA,0xAA,0xFF));fillcircle(g_nXCircle, g_nYCircle, 10 );
}//按键消息响应函数
LRESULT OnKeyDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
{int nStepX = 0;int nStepY = 0;switch( wParam ){case VK_DOWN:nStepY = 1;break;case VK_UP:nStepY = -1;break;case VK_LEFT:nStepX = -1;break;case VK_RIGHT:nStepX = 1;break;}_clearcircle(g_nXCircle, g_nYCircle, 12 );g_nXCircle += nStepX;g_nYCircle += nStepY;fillcircle(g_nXCircle, g_nYCircle, 10 );return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{//设置消息处理函数SetKeyboardProcess( enumINMSG_KEYDOWN,	OnKeyDown );//初始化if( !ShowingBoard(g_nWidth,g_nHeight, DrawProcess))return 1;//关闭图库CloseBoard();return 0;
}

有兴趣的同学可以试着运行看看效果。

四、接管所有消息处理

        当对Windows编程有了更深入了解后,需要处理除了以上消息之外的消息时,可以设置一个所有消息的处理函数。方法如下:

首先定义消息处理函数

LRESULT OnMessage( HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam )
{//此处输入消息处理过程return 0;
}

然后使用SetInputProcess进行设置

SetInputProcess( OnMessage );

此处需要注意的是使用了SetInputProcess( OnMessage );函数后,就要自己处理所有交互消息,所以SetMouseProcess和SetKeyboardProcess都将失效。

下面我们运用自定义消息处理函数对窗口关闭操作进行拦截的演示。代码如下:

// DemoMessage.cpp : 定义控制台应用程序的入口点。
//
#include "../import/include/CGBoard.h"
#include "math.h"
#ifdef _DEBUG
#pragma comment(lib,"../import/lib/SimpleCG_MDd.lib")
#else
#pragma comment(lib,"../import/lib/SimpleCG_MD.lib")
#endifint g_nWidth = 500;		//画面宽度
int g_nHeight= 400;		//画面高度int g_bIsDrawing = 0;
POINT g_ptLast;
int g_nLineWidth = 1;int g_nXCircle = 100;
int g_nYCircle = 100;
void DrawProcess()
{setfillcolor(RGB(0xAA,0xAA,0xFF));fillcircle(g_nXCircle, g_nYCircle, 10 );
}LRESULT OnMessage( HWND hWnd, UINT nMessage, WPARAM wParam, LPARAM lParam )
{if( nMessage == WM_CLOSE ){if(MessageBox(NULL,_T("是否退出"),_T("提示"),MB_YESNO) == IDYES )return 0;return 1;}return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{//设置消息处理函数SetInputProcess( OnMessage );//初始化if( !ShowingBoard(g_nWidth,g_nHeight, DrawProcess))return 1;//关闭图库CloseBoard();return 0;
}

五、结语

        通过掌握以上介绍的内容,就可以编写出大部分可交互程序。不过要完全操控窗口,还需要熟练掌握更多的消息及参数。对于游戏编写,后面会给出一个简单框架。

SimpleCG库安装 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/131944.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PbootCMS在搭建网站

1、打开网站 https://www.pbootcms.com/ 2、点击 “本站” 下载最新的网站代码 3、在本地laragon/www下创建目录(hejuwuye),并将代码放进去 4、创建本地数据库,数据库名称为: hejuwuye,然后将static/bac…

第三方软件测试机构有哪些测试服务软件测试报告收费标准是怎样的?

软件验收机构 一、什么是第三方软件测试机构? 第三方软件测试机构是区别于软件开发公司以及软件需求方的第三方机构,软件企业将软件测试外包给第三方软件测试机构已经成为了行业发展趋势。既省心省力,又降低企业成本,得出的软件测试结果以…

《机器学习核心算法》分类算法 - 朴素贝叶斯 MultinomialNB

「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:小白零基础《Python入门到精通》 朴素贝叶斯 1、朴素贝叶斯API2、朴素贝叶斯算法实际应用2.1、获取数据集2.2、划分…

EasyPHP-Devserver-17安装和配置mantisBT

文章目录 1、准备工作2、安装easyphp2.1 http://127.0.0.1 无法访问 3、安装mantisBT和phpMyAdmin3.1 配置浏览器的访问url和端口号(配置局域网内可访问)3.2 安装mantis 4、Administrator 注册新用户时设置登录密码5、附件上传6、邮件配置 文章参考自&am…

前端开发工具:助力创造精彩Web体验

💂 个人网站:【工具大全】【游戏大全】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 寻找学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 当涉及到前端开发工具时…

Spring Boot配置文件(YAML Properties)总结

文章目录 配置文件的作用YAML配置文件Properties配置文件配置文件的加载顺序激活不同的配置文件配置文件的占位符自定义配置属性加密敏感信息配置文件的最佳实践结论 🎉欢迎来到架构设计专栏~Spring Boot配置文件(YAML & Properties)总结…

C#控制台程序中使用log4.net来输出日志

Apache log4net 库是一个帮助程序员将日志语句输出到各种输出目标的工具。log4net 是优秀的 Apache log4j™ 框架到 Microsoft .NE​​T 运行时的端口。 我喜欢他可以自定义输出,区分等级等特点。 导入库 我们在工程里添加NuGet的包。输入名称log4net &#xff0…

【每日一题】852. 山脉数组的峰顶索引

852. 山脉数组的峰顶索引 - 力扣&#xff08;LeetCode&#xff09; 符合下列属性的数组 arr 称为 山脉数组 &#xff1a; arr.length > 3存在 i&#xff08;0 < i < arr.length - 1&#xff09;使得&#xff1a; arr[0] < arr[1] < ... arr[i-1] < arr[i] ar…

SpringMVC 的三种异常处理方式详解

目录 1. 什么是异常 2. 为什么要全局异常处理 3. SpringMVC异常分类 4. 异常处理思路 5. 三种异常处理方式示例 ① 配置 SimpleMappingExceptionResolver 处理器 ② 实现 HandlerExceptionResolver 接口 ③ 使用ControllerAdviceExceptionHandler实现全局异常 6. 响应…

如何在windows环境下编译T

一&#xff0c; 安装MYSYS2 1. 去https://www.msys2.org下载 msys2-x86_64-xxxxx.exe; 2. 按照msys2.org主页提示的步骤安装; 3.安装完默认起来的是 UCRT的&#xff0c; 可以根据环境的需要选择&#xff0c; 我选择的 MSYS2 MINGW64 4. 搭建编译环境&#xff0c; 安装对应的软…

18. 线性代数 - 线性变换

文章目录 线性空间线性变换线性变换的几何意义特征值与特征向量NumPy的矩阵操作Hi, 你好。我是茶桁。 经历了几节线性代数课程之后,终于咱们到了最后一节课了。本节课的内容说多不多,说少也不少。 我们先是要理解一下线性空间和线性变换,并且探讨一下线性变换的几何意义。…

目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)

目标分类 一、目标分类介绍1.1 二分类和多分类的区别1.2 单标签和多标签输出的区别 二、代码获取三、数据集准备四、环境搭建4.1 环境测试 五、模型训练六、模型测试6.1 多标签训练-单标签输出结果6.2 多标签训练-多标签输出结果 一、目标分类介绍 目标分类是一种监督学习任务…

如何利用AirDroid远程访问安卓设备屏幕?

屏幕镜像也叫屏幕截图或投屏&#xff0c;是AirDroid 个人版的一个免费功能&#xff0c;局域网或非局域网条件下都可以使用。 利用AirDroid的屏幕镜像功能&#xff0c;你可以将自己的安卓设备投屏到电脑进行直播或开会演示&#xff1b;也可以将安卓设备的屏幕共享到另一台手机或…

【Docker】Docker简介

Docker简介 &#x1f4cb;导航 1. Docker简介1.1 什么是Docker&#xff1f;1.2 什么是容器&#xff1f;1.3 容器的优势&#xff1f;1.4 Docker的优势&#xff1f;1.5 虚拟技术与容器技术Docker的区别&#xff1f;1.6 为什么学习Docker? 2. 安装Docker3. Docker架构4. Docker命…

碎片笔记 | 大模型攻防简报

前言&#xff1a;与传统的AI攻防&#xff08;后门攻击、对抗样本、投毒攻击等&#xff09;不同&#xff0c;如今的大模型攻防涉及以下多个方面的内容&#xff1a; 目录 一、大模型的可信问题1.1 虚假内容生成1.2 隐私泄露 二、大模型的模型安全问题&#xff08;传统AI攻防&…

Apache Doris 2.0 如何实现导入性能提升 2-8 倍

数据导入吞吐是 OLAP 系统性能的重要衡量标准之一&#xff0c;高效的数据导入能力能够加速数据实时处理和分析的效率。随着 Apache Doris 用户规模的不断扩大&#xff0c; 越来越多用户对数据导入提出更高的要求&#xff0c;这也为 Apache Doris 的数据导入能力带来了更大的挑战…

Unity ProBuilder(自己创建斜面、拐角)

目录 基础操作 下载 打开面板 新增对象 材质保存 1.斜面实例 2.拐角实例 3.切割实例 4.单独面赋值 基础操作 下载 打开面板 新增对象 选中想创建的块体后&#xff0c;在编辑器见面拉出块体 材质保存 打开材质编辑器后&#xff0c;将材质赋值&#xff0c;之后&am…

简单记录一下Splunk ES 升级

1: 背景: 现在有些app 产品对splunk ES (enterprise security) 的版本有要求,这个就要求splunk ES 随着Splunk enterprise 也一起升级,下面先列一下各个版本的兼容: Splunk products version compatibility matrix - Splunk Documentation 下面列出的8.2.11 的版本: 2:…

2023/9/13 -- C++/QT

作业&#xff1a; 1> 将之前定义的栈类和队列类都实现成模板类 栈&#xff1a; #include <iostream> #define MAX 40 using namespace std;template <typename T> class Stack{ private:T *data;int top; public:Stack();~Stack();Stack(const Stack &ot…

时序数据库 TimescaleDB 安装与使用

TimescaleDB 是一个时间序列数据库&#xff0c;建立在 PostgreSQL 之上。然而&#xff0c;不仅如此&#xff0c;它还是时间序列的关系数据库。使用 TimescaleDB 的开发人员将受益于专门构建的时间序列数据库以及经典的关系数据库 (PostgreSQL)&#xff0c;所有这些都具有完整的…