计算机组成原理课程设计-使用高级语言开发出软件扫描键盘的仿真.doc_第1页
计算机组成原理课程设计-使用高级语言开发出软件扫描键盘的仿真.doc_第2页
计算机组成原理课程设计-使用高级语言开发出软件扫描键盘的仿真.doc_第3页
计算机组成原理课程设计-使用高级语言开发出软件扫描键盘的仿真.doc_第4页
计算机组成原理课程设计-使用高级语言开发出软件扫描键盘的仿真.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

计算机科学与工程学院课程设计报告题目全称: 使用高级语言开发出软件扫描键盘的仿真 课程名称: 计算机组成原理 任课教师: 指导老师: 职称: 教授 序号学生姓名学号班号任课教师成绩12345指导老师评语:工作态度(10%)课程设计的成果(70%)文档写作(20%)小组得分(100%)签字: 本小组成员任务分工情况序号姓名学号任务分工完成情况学生签名1编写代码,文档编写及代码调试完成2代码,文档编写及代码调试完成3文档编写及代码调试完成4文档编写及代码调试完成5文档编写及代码调试完成摘 要摘 要计算机键盘通常采用行列扫描法来确定按下键所在的行列位置,通过行列扫描获得键盘扫描码。这种把键盘按键排列成n行m列的n*m行列点阵的方式,把行、列线分别连接到两个并行接口双向传送的连接线上,点阵上的键一旦被按动,该键所在的行列点阵信号就被认为已接通。按键所排列成的矩阵,通过软件的方法轮转顺序地对其 行、列分别进行扫描,以查询和确认是否有键按动。关键词: 行列扫描法 矩阵 键扫描码 接通/断开扫描码ABSTRACT Computer keyboards usually ranks scanning method to determine the ranks of the location where the key is pressed.Keyboard scan code is adopted by row and arrange scanning.The sort of n*m keyboard scan mode,The row and arrange lines are connected to the bidirectional transmission of two parallel interfaces connecting line, the key is pressed once on the matrix, where the row of the key matrix is considered a signal is switched on. The keys are arranged in a matrix, through rotational software method to order its row and arrange respectively. For scanning, to check and confirm where a key is pressed.Keywords: row and arrange scanning keyboard scan code on/off Scan Codes from Keyboard- 22 -目 录目录目录II第一章 绪论31.1 选题背景及意义31.2 国内外研究现状31.3 主要内容与章节安排41.4 本章小结4第二章 课程设计的需求分析52.1 环境需求52.2 功能需求52.3 性能需求52.3 本章小结5第三章 软件键盘扫描的设计63.1 总体设计63.2 功能模块设计63.3 本章小结6第四章 软件键盘扫描的实现74.1 开发环境介绍74.2 主要功能模块的实现74.3 本章小结17第五章 测试及成果展示185.1 测试环境185.2 测试用例和结果185.3 成果展示195.4 本章小结20第六章 总结与展望21参考文献22第二章 课程设计的需求分析第一章 绪论1.1 选题背景及意义本课程设计是在完成了计算机组成原理的教学后进行的,目的在于让学生在掌握了计算机组成原理的基本理论之后,在实验室里老师指导下,自己动手,做出一个简单模拟键盘输入仿真其响应的软件,并运行此段程序,且显示该段程序运行后其结果的正、误,分析其原因。通过该实习,让学生在实际操作中加深对计算机的组成原理和指令在计算机中运行过程的理解。1.2 国内外研究现状键盘是一种方便实用的手动输入设备,从这个意义上而言,键盘在计算机输入设备领域很难被淘汰。键盘是当前计算机输入设备中最主要的输入设备,随着科学技术的进步,可能会发生的是,键盘在未来有可能失去计算机主要输入设备的地位。 从目前的进展来看,出现了声控输入,手写输入和触摸或点击输入等几种非键盘输入方式,国外正在研发更先进的脑电波识别与输入技术。因此,给人一种符合发展规律的思维判断,即将来某一天,键盘这种输入设备会被更先进的输入设备淘汰,其实这种前景是值得商榷的。 由Magic Cube公司设计的“Magic Cube”(魔方)激光键盘,是一款超酷的产品,可以在任何具有表面平整的地方使用。这种非常酷,并且有用的键盘,可搭载应用在几乎任何有蓝牙的Mac、PC、iPhone、iPad、iPod touch,和Android系统的所有设备上使用。相对于现在来说,国内的键盘相关的技术与国外的比较,还是有一定的差距的,国内的发展方向正在向国外靠拢,在国外技术的基础上,来升级键盘的一些其他的功能,开发蕴含在其中的更多的能量,来提高我国在键盘扫描领域的一些技术,向高科技的电子产品迈进。不管是在技术上还是质量上,我们应该追求的是超过国外的技术,让国人相信中国的产品并不比外国的差,而且相比国外的产品不管是在质量上还是产量上,都比外国的好,让中国的研究走上时尚的尖端,让国外的人也买我们中国的产品。1.3 主要内容与章节安排1、绪论2、课程设计的需求分析:根据实验要求分析,得出所需要的环境需求,功能需求和性能需求。3、键盘的设计:根据需求做出对整个项目的总体设计和各个模块的设计4、键盘的实现:代码实现各个功能5、测试及结果展示:程序测试和结果的展示,对run结果的分析报告6、总结与期望:对本次课程设计做出总结及心得体会,程序是否能够做出更好和对以后的期望1.4 本章小结本章主要是给出选题背景和意义及国内外的一些研究现状,并对各个章节做出了一点简要的概括。第二章 课程设计的需求分析2.1 环境需求主要用c# 语言实现的,所以环境需求主要有以下几个方面:硬件环境:PC软件环境:windows7操作系统 、 Visual Studio 2010开发工具:Visual Studio 20102.2 功能需求本课程设计的目的是使用vs开发出软件扫描键盘工作过程的仿真程序。具体而言是用仿真程序以图形/图像的方式呈现PC键盘及其接口的组成粗框图,并将8048单片机执行扫描程序时,各个部件之间的数据流向动态演示出来。因此功能需求主要有以下几点:1、能以图形/图像的方式展示出IBM-PC键盘及其接口的组成图2、在执行扫描程序时,演示出各部件之间数据的动态流向3、实现软件扫描键盘的工作过程2.3 性能需求 本课程设计的目的是开发出软件扫描键盘工作过程的仿真,所以对性能的需求并不高。并不需要高配置的电脑,也不需要太大的容量,速度和时间上也没太大要求,所以只需要在普通的pc机上以图形化的方式展示出键盘和接口的组成图以及单片机在执行扫描程序时各部件之间数据的动态流向。2.3 本章小结 本章主要对本次课程设计的各种需求进行了分析。具体而言涉及了环境、功能和性能三方面的需求。由于本次课程设计的目的是使用vs开发出软件扫描键盘工作过程的仿真程序,所以需求并不是太多。只需要在普通的Pc机,windows系统和vs的环境下实现扫描键盘的功能仿真即可。第三章 软件键盘扫描的设计 第三章 软件键盘扫描的设计3.1 总体设计1、采用c#语言实现软件键盘扫描,制作一个屏幕键盘软件;2、屏幕键盘软件运行后,屏幕键盘可以接收焦点,并激活,能够实现与实际键盘完全同步;3、可以随意拖动到任意位置;3.2 功能模块设计1.需要一个全局的钩子(hook),也就是系统范围的钩子。实现一个屏幕键盘,需要监听所有键盘事件,无论窗体是否被激活。因此需要一个全局的钩子(后面介绍),也就是系统范围的钩子。2.键盘按键排列成n行m列的n*m行列点阵,把行、列线分别连接到两个并行接口双向传送的连接线上。3.实现一个 KeyBoardButton控件用作按钮,用 Visual Studio为屏幕键盘设计 UI,然后在这些 Button 的 Click 事件里面模拟一个按键过程。3.3 本章小结本章主要按照实验要求及日常键盘功能需求,提出总体设计方案和功能设计方案。使完成后的软件能满足实验要求,也能符合日常生活中功能需求。第四章 软件键盘扫描的实现第四章 软件键盘扫描的实现4.1 开发环境介绍硬件环境:PC机软件环境:windows 7操作系统 Visual Studio 2010开发工具:Visual Studio 20104.2 主要功能模块的实现 要实现一个屏幕键盘,需要监听所有键盘事件,无论窗体是否被激活。因此需要一个全局的钩子,也就是系统范围的钩子。钩子(Hook)是Windows提供的一种消息处理机制平台,是指在程序正常运行中接受信息之前预先启动的函数,用来检查和修改传给该程序的信息,(钩子)实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。注意:安装钩子函数将会影响系统的性能。监测“系统范围事件”的系统钩子特别明显。因为系统在处理所有的相关事件时都将调用您的钩子函数,这样您的系统将会明显的减慢。所以应谨慎使用,用完后立即卸载。还有,由于您可以预先截获其它进程的消息,所以一旦钩子函数出了问题的话必将影响其它的进程。介绍我们将要用到的两种类型的钩子。(1) WH_KEYBOARD_LL Hook WH_KEYBOARD_LL Hook监视输入到线程消息队列中的键盘消息。(2) WH_MOUSE_LL Hook WH_MOUSE_LL Hook监视输入到线程消息队列中的鼠标消息。下面的 class 把 API 调用封装起来以便调用。1/ NativeMethods.cs 2using System; 3using System.Runtime.InteropServices; 4using System.Drawing; 5 6namespace CnBlogs.Youzai.ScreenKeyboard 7 StructLayout(LayoutKind.Sequential) 8 internal struct MOUSEINPUT 9 public int dx;10 public int dy;11 public int mouseData;12 public int dwFlags;13 public int time;14 public IntPtr dwExtraInfo;15 1617 StructLayout(LayoutKind.Sequential)18 internal struct KEYBDINPUT 19 public short wVk;20 public short wScan;21 public int dwFlags;22 public int time;23 public IntPtr dwExtraInfo;24 2526 StructLayout(LayoutKind.Explicit)27 internal struct Input 28 FieldOffset(0)29 public int type;30 FieldOffset(4)31 public MOUSEINPUT mi;32 FieldOffset(4)33 public KEYBDINPUT ki;34 FieldOffset(4)35 public HARDWAREINPUT hi;36 3738 StructLayout(LayoutKind.Sequential)39 internal struct HARDWAREINPUT 40 public int uMsg;41 public short wParamL;42 public short wParamH;43 4445 internal class INPUT 46 public const int MOUSE = 0;47 public const int KEYBOARD = 1;48 public const int HARDWARE = 2;49 5051 internal static class NativeMethods 52 DllImport(User32.dll, CharSet = CharSet.Auto, SetLastError = false)53 internal static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex)5455 DllImport(User32.dll, CharSet = CharSet.Auto, SetLastError = false56| internal static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);5758DllImport(User32.dll, EntryPoint = SendInput, CharSet = CharSet.Auto)59 internal static extern UInt32 SendInput(UInt32 nInputs, Input pInputs, Int32 cbSize);6061|DllImport(Kernel32.dll, EntryPoint = GetTickCount, CharSet = CharSet.Auto)62 internal static extern int GetTickCount();6364 DllImport(User32.dll, EntryPoint = GetKeyState, CharSet = CharSet.Auto)65 internal static extern short GetKeyState(int nVirtKey);6667 DllImport(User32.dll, EntryPoint = SendMessage, CharSet = CharSet.Auto)68 internal static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);69 70 安装钩子 使用SetWindowsHookEx函数(API函数),指定一个Hook类型、自己的Hook过程是全局还是局部Hook,同时给出Hook过程的进入点,就可以轻松的安装自己的Hook过程。SetWindowsHookEx总是将你的Hook函数放置在Hook链的顶端。你可以使用CallNextHookEx函数将系统消息传递给Hook链中的下一个函数。 对于某些类型的Hook,系统将向该类的所有Hook函数发送消息,这时, Hook函数中的CallNextHookEx语句将被忽略。全局(远程钩子)Hook函数可以拦截系统中所有线程的某个特定的消息,为了安装一个全局Hook过程,必须在应用程序外建立一个DLL并将该Hook函数封装到其中,应用程序在安装全局Hook过程时必须先得到该DLL模块的句柄。将Dll名传递给LoadLibrary 函数,就会得到该DLL模块的句柄;得到该句柄 后,使用GetProcAddress函数可以得到Hook过程的地址。最后,使用SetWindowsHookEx将 Hook过程的首址嵌入相应的Hook链中,SetWindowsHookEx传递一个模块句柄,它为Hook过程的进入点,线程标识符置为0,该Hook过程同系统中的所有线程关联。如果是安装局部Hook此时该Hook函数可以放置在DLL中,也可以放置在应用程序的模块段。在C#中通过平台调用(前文已经介绍过)来调用API函数。public void Start(bool installMouseHook, bool installKeyboardHook) 2 if (hMouseHook = IntPtr.Zero & installMouseHook) 3 MouseHookProcedure = new HookProc(MouseHookProc); 4 hMouseHook = SetWindowsHookEx( 5 WH_MOUSE_LL, 6 MouseHookProcedure, 7 Marshal.GetHINSTANCE( 8 Assembly.GetExecutingAssembly().GetModules()0), 9 010 );1112 if (hMouseHook = IntPtr.Zero) 13 int errorCode = Marshal.GetLastWin32Error();14 Stop(true, false, false);1516 throw new Win32Exception(errorCode);17 18 1920 if (hKeyboardHook = IntPtr.Zero & installKeyboardHook) 21 KeyboardHookProcedure = new HookProc(KeyboardHookProc);22 /install hook23 hKeyboardHook = SetWindowsHookEx(24 WH_KEYBOARD_LL,25 KeyboardHookProcedure,26 Marshal.GetHINSTANCE(27 Assembly.GetExecutingAssembly().GetModules()0),28 0);29 / If SetWindowsHookEx fails.30 if (hKeyboardHook = IntPtr.Zero) 31 / Returns the error code returned by the last 32 / unmanaged function called using platform invoke 33 / that has the DllImportAttribute.SetLastError flag set. 34 int errorCode = Marshal.GetLastWin32Error();35 /do cleanup36 Stop(false, true, false);37 /Initializes and throws a new instance of the 38 / Win32Exception class with the specified error. 39 throw new Win32Exception(errorCode);40 41 42 使用完钩子后,要进行卸载,这个可以写在析构函数中。 1 public void Stop() 2 3 this.Stop(true, true, true); 4 5 6 public void Stop(bool uninstallMouseHook, bool uninstallKeyboardHook, 7 bool throwExceptions) 8 / if mouse hook set and must be uninstalled 9 if (hMouseHook != IntPtr.Zero & uninstallMouseHook) 10 / uninstall hook11 bool retMouse = UnhookWindowsHookEx(hMouseHook);12 / reset invalid handle13 hMouseHook = IntPtr.Zero;14 / if failed and exception must be thrown15 if (retMouse = false & throwExceptions) 16 / Returns the error code returned by the last unmanaged function 17 / called using platform invoke that has the DllImportAttribute.18 / SetLastError flag set. 19 int errorCode = Marshal.GetLastWin32Error();20 / Initializes and throws a new instance of the Win32Exception class 21 / with the specified error. 22 throw new Win32Exception(errorCode);23 24 2526 / if keyboard hook set and must be uninstalled27 if (hKeyboardHook != IntPtr.Zero & uninstallKeyboardHook) 28 / uninstall hook29 bool retKeyboard = UnhookWindowsHookEx(hKeyboardHook);30 / reset invalid handle31 hKeyboardHook = IntPtr.Zero;32 / if failed and exception must be thrown33 if (retKeyboard = false & throwExceptions) 34 / Returns the error code returned by the last unmanaged function 35 / called using platform invoke that has the DllImportAttribute36 / SetLastError flag set. 37 int errorCode = Marshal.GetLastWin32Error();38 / Initializes and throws a new instance of the Win32Exception class 39 / with the specified error. 40 throw new Win32Exception(errorCode);41 42 43 44将这个文件编译成一个dll,即可在应用程序中调用。通过它提供的事件,便可监听所有的键盘事件。但是,这只能监听键盘事件,没有键盘的情况下,怎么会有键盘事件?其实很简单,通过SendInput,API函数提供虚拟键盘代码的调用即可模拟键盘输入。下面的代码模拟一个 KeyDown 和 KeyUp 过程,把他们连接起来就是一次按键过程。 1 private void SendKeyDown(short key) 2 Input input = new Input1; 3 input0.type = INPUT.KEYBOARD; 4 input0.ki.wVk = key; 5 input0.ki.time = NativeMethods.GetTickCount(); 6 7 if(NativeMethods.SendInput(uint)input.Length,input, Marshal.SizeOf(input0) 8 input.Length) 9 throw new Win32Exception(Marshal.GetLastWin32Error();10 11 1213 private void SendKeyUp(short key) 14 Input input = new Input1;15 input0.type = INPUT.KEYBOARD;16 input0.ki.wVk = key;17 input0.ki.dwFlags = KeyboardConstaint.KEYEVENTF_KEYUP;18 input0.ki.time = NativeMethods.GetTickCount();1920 if (NativeMethods.SendInput(uint)input.Length, input, Marshal.SizeOf(input0)21 input.Length) 22 throw new Win32Exception(Marshal.GetLastWin32Error();23 24 自己实现一个 KeyBoardButton 控件用作按钮,用 Visual Studio 或者 SharpDevelop 为屏幕键盘设计 UI,然后在这些 Button 的 Click 事件里面模拟一个按键过程。 1 2 private void ButtonOnClick(object sender, EventArgs e) 3 KeyboardButton btnKey = sender as KeyboardButton; 4 if (btnKey = null) 5 return; 6 7 8 SendKeyCommand(btnKey); 9 10 11 private void SendKeyCommand(KeyboardButton keyButton) 12 short key = keyButton.VKCode;13 if (combinationVKButtonsMap.ContainsKey(key) 14 if (keyButton.Checked) 15 SendKeyUp(key);16 else 17 SendKeyDown(key);18 19 else 20 SendKeyDown(key);21 SendKeyUp(key);22 23 其中 combinationVKButtonsMap 是一个 IDictionaryshort, IList, key 存储的是VK_SHIFT, VK_CONTROL 等组合键的键盘码。左右两个按钮对应同一个键盘码,因此需要放在一个 List 里。标准键盘上的每一个键都有虚拟键码( VK_CODE)与之对应。还有一些其他的常量,把它写在一个静态 class 里。 1 / KeyboardConstaint.cs 2 internal static class KeyboardConstaint 3 internal static readonly short VK_F1 = 0x70; 4 internal static readonly short VK_F2 = 0x71; 5 internal static readonly short VK_F3 = 0x72; 6 internal static readonly short VK_F4 = 0x73; 7 internal static readonly short VK_F5 = 0x74; 8 internal static readonly short VK_F6 = 0x75; 9 internal static readonly short VK_F7 = 0x76;10 internal static readonly short VK_F8 = 0x77;11 internal static readonly short VK_F9 = 0x78;12 internal static readonly short VK_F10 = 0x79;13 internal static readonly short VK_F11 = 0x7A;14 internal static readonly short VK_F12 = 0x7B;1516 internal static readonly short VK_LEFT = 0x25;17 internal static readonly short VK_UP = 0x26;18 internal static readonly short VK_RIGHT = 0x27;19 internal static readonly short VK_DOWN = 0x28;2021 internal static readonly short VK_NONE = 0x00;22 internal static readonly short VK_ESCAPE = 0x1B;23 internal static readonly short VK_EXECUTE = 0x2B;24 internal static readonly short VK_CANCEL = 0x03;25 internal static readonly short VK_RETURN = 0x0D;26 internal static readonly short VK_ACCEPT = 0x1E;27 internal static readonly short VK_BACK = 0x08;28 internal static readonly short VK_TAB = 0x09;29 internal static readonly short VK_DELETE = 0x2E;30 internal static readonly short VK_CAPITAL = 0x14;31 internal static readonly short VK_NUMLOCK = 0x90;32 internal static readonly short VK_SPACE = 0x20;33 internal static readonly short VK_DECIMAL = 0x6E;34 internal static readonly short VK_SUBTRACT = 0x6D;3536 internal static readonly short VK_ADD = 0x6B;37 internal static readonly short VK_DIVIDE = 0x6F;38 internal static readonly short VK_MULTIPLY = 0x6A;39 internal static readonly short VK_INSERT = 0x2D;4041 internal static readonly short VK_OEM_1 = 0xBA; / ;: for US42 internal static readonly short VK_OEM_PLUS = 0xBB; / + any country4344 internal static readonly short VK_OEM_MINUS = 0xBD; / - any country4546 internal static readonly short VK_OEM_2 = 0xBF; / /? for US47 internal static readonly short VK_OEM_3 = 0xC0; / for US48 internal static readonly short VK_OEM_4 = 0xDB; / for US49 internal static readonly short VK_OEM_5 = 0xDC; / | for US50 internal static readonly short VK_OEM_6 = 0xDD; / for US51 internal static readonly short VK_OEM_7 = 0xDE; / for US52 internal static readonly short VK_OEM_PERIOD = 0xBE; / . any country53 internal static readonly short VK_OEM_COMMA = 0xBC; / , any country54 internal static readonly short VK_SHIFT = 0x10;55 internal static readonly short VK_CONTROL = 0x11;56 internal static readonly short VK_MENU = 0x12;57 internal static readonly short VK_LWIN = 0x5B;58 internal static readonly short VK_RWIN = 0x5C;59 internal static readonly short VK_APPS = 0x5D;6061 internal static readonly short VK_LSHIFT = 0xA0;62 internal static readonly short VK_RSHIFT = 0xA1;63 internal static readonly short VK_LCONTROL = 0xA2;64 internal static readonly short VK_RCONTROL = 0xA3;65 internal static readonly short VK_LMENU = 0xA4;66 internal static readonly short VK_RMENU = 0xA5;6768 internal static readonly short VK_SNAPSHOT = 0x2C;69 internal static readonly short VK_SCROLL = 0x91;70 internal static readonly short VK_PAUSE = 0x13;71 internal static readonly short VK_HOME = 0x24;7273 internal static readonly short VK_NEXT = 0x22;74 internal static readonly short VK_PRIOR = 0x21;75 internal static readonly short VK_END = 0x23;7677 internal static readonly short VK_NUMPAD0 = 0x60;78 internal static readonly short VK_NUMPAD1 = 0x61;79 internal static readonly short VK_NUMPAD2 = 0x62;80 internal static readonly short VK_NUMPAD3 = 0x63;81 internal static rea

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论