当前位置: 首页 > news >正文

Win32_6Win32的验证码程序

上次利用文本输出规范,我写了一个"程序员求爱程序",今天还是继续玩一下Win32的文本输出,这次我将详细谈一下Win32的文本输出规范。毕竟,这个在Win32编程中还是很重要的,基本上每一个程序都离不开这个玩意儿

ok,先来说一下基础:

Win32中有一个关于文本信息的结构体TEXTMETRIC,它包含很丰富的文本信息,而P先生(Charles Petzold)的书中说道,我日常编程中仅仅用到其中几个,以下就是:

{ 
  LONG tmHeight; 		//每一行文本的高度
  LONG tmAscent; 		//上边沿字符(相对于基线baseline)
  LONG tmDescent; 		//下边沿字符(相对于基线baseline)
  LONG tmInternalLeading; 	//重音符号的高度
  LONG tmExternalLeading; 	//每一行字符的间距
  LONG tmAveCharWidth;    	//字符平均高度
  LONG tmMaxCharWidth;    	//最大字符的宽度
  BYTE tmPitchAndFamily;  	//字体的一些信息(但是就目前而言,这个信息的低8位多数用于大写字符的判断)
}

继续用P先生的一张图来诠释这些玩意儿:

这个东西还是不难看懂,主要是要熟记,这样以后就不用查看api,直接上阵演练

好了,有了这些基础,我们就开始今儿的主题,编写一个简易的验证码程序

先来瞧一眼它的运行效果:

主要功能如下:

(1)验证码显示的位置在一定范围内随机、验证码在0~9随机、验证码颜色随机

(2)鼠标点击验证码可以变换(这个和实际生活中见到的是一样的)

下面来看看试下细节吧:

(1)重要的变量:

static intcxChar, cxCaps, cyChar;//大小写字符的宽度、字符的高度 static RECTrect;//验证码显示的范围 TEXTMETRICtm;//文本信息结构体

//分别表示验证码、坐标xy(为了节省空间 , 用于验证码的坐标和鼠标点击的坐标)、循环变量 intnum, x, y, i; TCHARstr[2];//验证码数组


(2)验证码的实现

实现代码如下:

//先画出验证码的范围 , 矩形(默认是白色的刷子 , 所以矩形的背景是白色)
Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);

//打印验证码
for(i=0; i<4; i++)
{
	SetTextColor(hdc, RGB(rand()%255, rand()%255, rand()%255));//设置随机文本颜色

	//设置随机验证码
	num = rand()%10;
	wsprintf(str, TEXT("%d"), num);

	//设定每一位验证码的坐标
	x = rect.left + 20 + i * (cxChar + cxCaps);
	y = rand()%(31 - cyChar) + 90;

	//显示验证码
	TextOut(hdc, x, y, str, 1);
}


我主要讲一下这一行代码:

y = rand()%(31 - cyChar) + 90;

这里主要是控制验证码在矩形区域的中间一个范围显示,那为什么要见一个cyChar呢?

对于rand()求余运算,就是获得0~(31 - cyChar)之间的随机数,而cyChar是字符的高度

因为显示字符的位置是它左上角的坐标,如果不减去字符的高度,那么仅仅是字符的左上角坐标在我们想要的范围内,字符的显示却会超出这个范围

今儿这个程序很简单,但是重在它能体现文本输出的一些技巧,个人觉得还是比较重要的,希望读者多下点儿功夫吧

源代码下载

相关文章:

  • iOS Xcode, 解决“Could not insert new outlet connection”的问题。
  • Win32_7由浅入深——滚动条
  • 简单实现web服务器负载均衡
  • Android编程之ActivityManager: Segmentation fault
  • C# 网络编程之网页简单下载实现
  • mac 下对 iterm 终端 设置代理
  • 如何理解c和c++的复杂类型声明
  • silverlight中datagrid数据到处excel
  • Android编程之如何取得View的当前位置
  • Android4.0内存Dex数据动态加载技术
  • C# 网络编程之网页自动登录 (一).使用WebBrower控件模仿登录
  • 文章收录1
  • windows服务器应对高并发和DDOS攻击
  • 公开课可下载资源汇总
  • 将solr3.5整合到Tomcat6.x中
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • [笔记] php常见简单功能及函数
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • Consul Config 使用Git做版本控制的实现
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • gops —— Go 程序诊断分析工具
  • java概述
  • Java新版本的开发已正式进入轨道,版本号18.3
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • JS专题之继承
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • Vue小说阅读器(仿追书神器)
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 深入浅出Node.js
  • 什么是Javascript函数节流?
  • 优化 Vue 项目编译文件大小
  • 正则表达式小结
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (2015)JS ES6 必知的十个 特性
  • (C语言)fread与fwrite详解
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (一) springboot详细介绍
  • (一)基于IDEA的JAVA基础1
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)程序员疫苗:代码注入
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 药厂业务系统 CPU爆高分析
  • .Net 中Partitioner static与dynamic的性能对比
  • .NET运行机制
  • [04]Web前端进阶—JS伪数组
  • [2023年]-hadoop面试真题(一)
  • [AIGC] 如何建立和优化你的工作流?
  • [AutoSar]BSW_Com07 CAN报文接收流程的函数调用
  • [bzoj2957]楼房重建
  • [C++] 多线程编程-thread::yield()-sleep_for()