WIN32汇编-开发记事本语音阅读工具

WIN32汇编开发记事本语音阅读工具

一、      引言

Windows系统具有风格一致的华丽图形用户界面、丰富的API函数、设备无关性、多任务等特点而广泛流行。

Win32汇编支持32位Windows API函数的调用,拥有很多高级语言的语法和运算符,编译后的程序执行效率高,占微量系统资源,短小精练,因此WIN32汇编语言非常适合记事本语音阅读工具这类软件的开发。

二、设计思路

汇编语言没有类的概念,只能采用传统的结构化方法进行设计。按软件实现的功能分为以下几个模块:

1、       记事本内容读取

2、       语音阅读文本

3、       消息循环处理

4、       程序的启动与退出

程序开发的难点是前两个模块,笔者进行如下设计:

1、           如何获取记事本内容。首先获取记事本的窗口句柄,然后获得记事本的文本子窗口句柄,最后向子窗口发送WM_GETTEXT消息取得记事本所打开的文本内容。

2、       如何实现语音阅读文本。采用微软的TTS语音引擎实现文本转语音功能, TTS基于COM,因此开发需要使用Microsoft SpeechSDK,直接调用SAPI实现语音朗读,Microsoft SpeechSDK没有相应的汇编语言INC头文件,必须将C的头文件翻译成汇编格式,直接写在代码内,另外COM对象函数遵循严格顺序,不能随意调换列表中函数位置。

   该软件人机界面简单,资源文件使用用记事本直接手动编写,读者也可使用VC自带的资源编辑工具编写。

三、代码实现:

(一)程序代码

;程序名:记事本语音阅读工具

;作者:刘兴

;文件名:readtext.asm

;汇编中的注释采用“;”表示,笔者在关健代码上注释其含义。

;汇编中一行代码写不下,用“\”表示续行

;####################################################################

;指定编译选项

     .486

     .model flat, stdcall

     option casemap :none  

 

;####################################################################

;指定使用的头文件

     include windows.inc

     include user32.inc

     include kernel32.inc

     include gdi32.inc

     include masm32.inc

     include ole32.inc

;笔者的MASM32 Version 9.0安装在d盘

     include d:\masm32\com\include\oaidl.inc

;####################################################################

;指定使用的库文件

     includelib user32.lib

     includelib kernel32.lib

     includelib gdi32.lib

     includelib masm32.lib

     includelib ole32.lib

;####################################################################     

;汇编期常量定义

IDC_OK equ 101

IDC_MIN equ 102

IDC_EXIT equ 103

FLAG_PLAY equ 1

FLAG_PAUSE equ 2

FLAG_RESUME equ 3

FLAG_STOP equ 0

SPF_ASYNC equ 1;sapi.h中定义

DIALOG_MAIN equ 1 

;####################################################################      

;定义ISpVoice的虚函数接口表结构

;接口表由sapi.h取得,将ISpVoiceVtbl的定义改成汇编格式

ISpVoice STRUCT DWORD

   QueryInterface comethod3 ?

    AddRefcomethod1 ?

   Release  comethod1 ?

   SetNotifySink comethod2 ?

   SetNotifyWindowMessage  comethod5 ?

   SetNotifyCallbackFunction  comethod4 ?

   SetNotifyCallbackInterface  comethod4 ?

   SetNotifyWin32Event comethod1 ?

   WaitForNotifyEvent comethod1 ?

   GetNotifyEventHandle  comethod1 ?

   SetInterest  comethod3 ?

  GetEvents  comethod4 ?

  GetInfo comethod2 ?

  SetOutput  comethod3 ?

  GetOutputObjectToken comethod2 ?

  GetOutputStream comethod2 ?

  Pause comethod1 ?

  Resume comethod1 ?

  SetVoice comethod2 ?

  GetVoice comethod2 ?

  Speak  comethod4 ?

  SpeakStream comethod4 ?

  GetStatus  comethod3 ?

  Skip comethod4 ?

  SetPriority comethod2 ?

  GetPriority comethod2 ?

  SetAlertBoundary comethod2 ?

  GetAlertBoundary comethod2 ?

  SetRate comethod2 ?

  GetRate comethod2 ?

  SetVolume comethod2 ?

  GetVolume comethod2 ?

  WaitUntilDone comethod2 ?

  SetSyncSpeakTimeout comethod2 ?

  GetSyncSpeakTimeout comethod2 ?

  SpeakCompleteEvent comethod1 ?

  IsUISupported comethod5 ?

  DisplayUI comethod6 ?

ISpVoice ENDS

;####################################################################

;未初始化数据段

.data?

      hWinMain DWORD ?

      CommandLine DWORD ?

      hInstance DWORD ?

      showrect RECT <>

      ppVoice  DWORD ?

;####################################################################

;已初始化数据段

.data

      sznoteclass db "Notepad",0

      szplay  db "开始",0

      szresume  db "继续",0

      szpause   db"暂停",0        

      szbuffer dw 2000 dup(?)

      szmscap db "错误",0

      dwflag dd FLAG_STOP;当前的工作状态:停止、开始、暂停、继续

     ;SpVoice对象的CLSIDT和IID定义,在SDK的相关头文件可以找到

  CLSID_SpVoiceGUID<96749377H,3391H,11D2H,\

<9EH,0E3H,00H,0C0H,4FH,79H,73H,96H>>

  IID_ISpVoice  GUID<6C44DF74H,72B9H,4992H,\

<0A1H,0ECH,0EFH,99H,6EH,04H,22H,0D4H>>

       szerrtext db "错误号:"

       szerrtextno db 20 dup(?),0

;####################################################################

;函数声明

_speaktext proto :DWORD,:DWORD

;####################################################################

;下面是代码段

  .code

;#############################################################

;读取并语音朗读记事本内容函数

;函数主要参数说明  @dwflag:标志参数

_readtext proc @dwflag:DWORD

   local  hwnd:DWORD

    invokeFindWindow,addr sznoteclass,NULL

    movhwnd,eax;得到记事本窗口句柄

    invokeGetWindow,hwnd,GW_CHILD

    movhwnd,eax;得到文本子窗口句柄

;获取文本内容

invoke SendMessage,hwnd,WM_GETTEXT,2000,addr szbuffer

   ;调用子函数实现文本转语音

invoke _speaktext,addr szbuffer,@dwflag 

    ret

_readtext endp

;###################################################################

;取得COM接口错误号函数

;根据错误号在SDK的winerror.h中查出错误类型

_geterrno proc szerrhex:DWORD,pszerrtext:DWORD

   push eax

   invokedw2hex,szerrhex,pszerrtext

   pop eax

   ret

_geterrno endp

;####################################################################

;窗口过程处理函数

_ProcMain proc uses ebx edx hWnd,uMsg,wParam,lParam

   .if uMsg==WM_COMMAND

       moveax,wParam

       movzxeax,ax    

     .if eax==IDC_EXIT ;程序退出,释放ppVoice对象

           mov eax,ppVoice

           movedx,[eax]

           invoke(ISpVoice PTR[edx]).Release,ppVoice

           callCoUninitialize

          invoke EndDialog,hWnd,NULL

.elseif eax==IDC_OK

       ;通过dwflag变量变化实现开始、停止、暂停功能

;转换,调用SetDlgItemText实现按钮文字的更新

            .if dwflag==FLAG_STOP

                mov dwflag,FLAG_PLAY

                invoke SetDlgItemText,hWnd,IDC_OK,addrszpause               .elseif dwflag==FLAG_PAUSE

                 mov dwflag,FLAG_RESUME

                 invoke SetDlgItemText,hWnd,IDC_OK,addr szpause

             .elseif dwflag==FLAG_RESUME||dwflag==FLAG_PLAY

                 mov dwflag,FLAG_PAUSE 

                 invoke SetDlgItemText,hWnd,IDC_OK,addrszresume                .endif

             invoke _readtext,dwflag;调用读取并朗读记事本子函数

     .elseif eax==IDC_MIN

         invoke ShowWindow,hWnd,SW_MINIMIZE;最小化窗口

     .endif

    .elseif uMsg==WM_INITDIALOG

         ;初始化pVoice对象

       invoke CoInitialize,NULL

         invoke CoCreateInstance,addr CLSID_SpVoice,NULL,CLSCTX_ALL,\

addr IID_ISpVoice,addr ppVoice

        .IF_FAILED;如果失败,取得错误号并释放资源

               invoke_geterrno,eax,addr szerrtextno

               invokeMessageBox,NULL,addr szerrtext,\

addr szmscap,MB_ICONERROR

              call CoUninitialize

        .endif

         ;设置语音库为默认语音

         mov eax,ppVoice

         movedx,[eax]

         invoke (ISpVoice PTR[edx]).SetVoice,ppVoice,NULL

         ;设置语速

         mov eax,ppVoice

          movedx,[eax]

         invoke(ISpVoice PTR[edx]).SetRate,ppVoice,3

         .IF_FAILED

            invoke _geterrno,eax,addr szerrtextno

            invoke MessageBox,NULL,addr szerrtext,addr szmscap,\

MB_ICONERROR

         .endif

   .else 

          mov eax,FALSE

          ret

   .endif

     mov  eax,TRUE

     ret

_ProcMain endp

;####################################################################

;文本转语音子函数

;函数主要参数说明:pszspeakansi:文本地址,@dwflag:标志参数

_speaktext proc uses edx ebxpszspeakansi:DWORD,@dwflag:DWORD

.data

        szspeaktextdw 2000 dup(?);要朗读的文本

     .code 

;将文本转换成宽字符型,一个字符用16位表示,因为可能存在中文字符

       invoke lstrlen,pszspeakansi

       mov ebx,eax

   invokeMultiByteToWideChar,CP_ACP,MB_PRECOMPOSED,\

pszspeakansi,-1,addr szspeaktext,ebx

      mov eax,ppVoice

       mov edx,[eax]

      .if@dwflag==FLAG_PLAY  ;播放         

          invoke (ISpVoice PTR[edx]).Speak,ppVoice,\

addr szspeaktext,SPF_ASYNC,NULL

     .elseif@dwflag==FLAG_PAUSE   ;暂停

           invoke (ISpVoicePTR[edx]).Pause,ppVoice           

      .elseif @dwflag==FLAG_RESUME  ;继续

           invoke (ISpVoicePTR[edx]).Resume,ppVoice                     .endif

     .IF_FAILED

         invoke _geterrno,eax,addr szerrtextno

         invoke MessageBox,NULL,addr szerrtext,\

addr szmscap,MB_ICONERROR

     .endif

    ret

_speaktext endp

;####################################################################

;主窗口消息循环

_WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD

     ;显示模态对话框

     invoke DialogBoxParam,hInst,DIALOG_MAIN,\

NULL,addr _ProcMain,NULL

     ret

_WinMain endp

;####################################################################

start:

;程序的入口,控制程序的启动与退出

       invoke GetModuleHandle, NULL

       mov hInstance, eax

       invoke GetCommandLine

       mov CommandLine, eax

       invoke _WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT

       invoke ExitProcess,eax;退出程序

;####################################################################      

;指定入口地址

end start

(二)资源文件

//文件名:readtext.rc

#include <resource.h>

#define IDC_OK 101

#define IDC_MIN 102

#define IDC_EXIT 103

#define DIALOG_MAIN 1

///////////////////////////////////////////////////////////////////////定义图标文件

IDR_MAINFRAME        ICON   DISCARDABLE    "readtext.ico"

/////////////////////////////////////////////////////////////////////

//定义对话框

DIALOG_MAIN DIALOG 0, 0, 320, 50

STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION

CAPTION "记事本语音阅读器(程序:刘兴)"

FONT 9, "宋体"

//定义子窗口控件

BEGIN

//子窗口总共三个按钮

   PUSHBUTTON     "开始",IDC_OK,10,20,50,14

   PUSHBUTTON     "最小化",IDC_MIN,110,20,50,14

   PUSHBUTTON     "退出",IDC_EXIT,210,20,50,14

 END

 

四、编译生成可执行文件

笔者使用MASM32 Version 9.0做为开发和编译工具,此工具可以在http://www.movsd.com/下载。

编译命令:

ml /c /coff readtext.asm

rc readtext.rc

link /subsystem:windows readtext.obj readtext.res

 

 

五、程序运行环境要求

   该程序要求WINDOWS操作系统安装了Microsoft Speech SDK,并将中文语音设为默认语音库。

汇编语言的建立、写、读文件 用汇编语言编写一个程序,新建一个文件abc.txt,从键盘输入abc.txt文件的内容(不超过100个字符),然后新建另外一个文件def.txt,将abc.txt文件的前10个字符复制到def.txt。 阅读详情

相关推荐

Windows10下搭建汇编语言开发环境(利用DOSBOX和MASM32)

学一门语言,最好的方法便是在实践中学习。对于不少初学者来说,首先要面临的是如何搭建开发平台/环境的问题。由于汇编语言的特殊性,不少初学者会担心自己直接对寄存器进行操作会不会导致系统崩溃或者系统硬件损坏,再加上现如今高级程序设计语言大行其道,真正需要写汇编语言的情境已经不那么多了,所以不少初学汇编语言的同学都还停留在纸上谈兵的状态。 本人初次学习汇编语言已经是五年前,但一直都未亲自实践过,最近工作上需要用到反汇编二进制可执行文件,因此计划重新拾起曾经学过的汇编语言,以便能够顺利完成手头上的项目。以下是搭

Windness的技术生活 15万+

用WIN汇编开发桌面报时工具

用WIN汇编开发桌面报时工具 用WIN32汇编语言开发出来的WINDOWS程序具有执行效率高、占用空间小等特点。 一、  软件简介及相应开发工具 桌面报时工具主要完成以下两个功能: 1、     F12热键语音报时、语音整点报时。 2、  在屏幕中上方直接显示时间,并不被任何窗口挡住。 3、  程序运行后最小化为任务栏图标。 笔者以WIN汇编为开发语言,以MASM32为开发工具,因为...

深未来技术 488

用汇编进行简单的文件读写

##前言一周前开始为了应付学校的汇编程序设计大赛,一直在学习汇编,在程序设计的过程中,关于汇编读写文件这块感触颇深,特此总结一下。##环境准备由于使用linxu开发环境,而MASMx86微处理器家族汇编开发环境需要在dos环境下运行,故下载DOSBOX模拟dos环境以便于开发。##读文件在此放上读取文件数据的指令: mov ah,3fH mov bx,handle mov cx,size...

yiranblade的博客 1万+

masm32

第一课 基本概念   翻译:Lxx,校对:LuoYunBins Win32 ASM Pagehttp://asm.yeah.net 我们先假设您已知道了如何使用MASM。如果您还不知道的话,请下载 win32asm.exe ,并请仔细研读其中所附带的文档资料。好

cg2680139的专栏 2119

计算技术【10】

采用微软的TTS语音引擎实现文本转语音功能, TTS基于COM,因此开发需要使用Microsoft SpeechSDK,直接调用SAPI实现语音朗读,Microsoft SpeechSDK没有相应的汇编语言INC头文件,必须将C的头文件翻译成汇编格式,直接写在代码内,另外COM对象函数遵循严格顺序,不能随意调换列表中函数位置。首先获取记事本的窗口句柄,然后获得记事本的文本子窗口句柄,最后向子窗口发送WM_GETTEXT消息取得记事本所打开的文本内容。汇编语言没有类的概念,只能采用传统的结构化方法进行设计。

逻辑君的日常 125

win32汇编写的记事本

win32汇编写的记事本,与windows自带的记事本类似,注释详细,在masm32下汇编运行。 用richedit控件实现,支持右键菜单,拖放功能,状态栏显示提示信息等功能

汇编代码查看工具

分析内存布局的神器。

Lce的专栏 1382

数科阅读器(OFD阅读器)

数科阅读器是一款简单的阅读软件,可以帮助用户在电脑上打开文档阅读,大家都知道文档的格式有很多,例如doc文档一般是在Word软件上打开的,xls文档一般是在Excel软件上查看的,而ofd、sfd两种格式的文档不常见,很多阅读软件都是不兼容这种格式的,对于这样的情况,您需要下载专属的阅读器

emu8086汇编语言操作文件指令详解

总结emu8085汇编语言对文件进行打开、关闭、读入和写入,并附有代码示例

qq_70311979的博客 5920

汇编语言磁盘文件操作

关于汇编语言中,对文件的相关操作,包括建文件,读写文件等等

超牛!WIN32汇编写的记事本

内容索引:VC/C++源码,其它分类,汇编,记事本  WIN32汇编拟Windows XP自带记事本,界面和功能都仿的比较像,未能实现打印功能,拖放文件功能也有待完善。 richEdit控件未实现右键菜单。基本实现所有功能,添加了工具栏和状态栏,增加颜色功能,使用 nmake 进行编译和链接,界面如上所示,仅供汇编的朋友参考学习。

汇编程序设计:磁盘文件的读写

infile(文件的读取) ;数据段 data segment file db 'c:\1.txt' , 0 ;文件名,dosbox 设置的c盘下的路径 buf db 256 dup(0) ;文件内容暂存区 error_message db 0ah , 'error !' , '$...

hairi1234的博客 4370

DDR核心机制解析:从Burst到Prefetch的性能跃迁

本文深入解析了DDR内存性能跃迁的核心机制,重点阐述了Burst(突发传输)与Prefetch(预取)技术的协同工作原理。Burst机制通过连续传输数据减少访问延迟,而Prefetch则通过内部预取数据提升吞吐量,两者结合完美匹配现代CPU缓存行需求,是DDR3等内存实现高效带宽的关键。

weixin_29232121的博客 135

新版WIN32汇编开发环境介绍及RadAsm简明教程

写在前面的话: 在准备做教程的时候去查资料,关于WIN32下汇编方面的,本来想找些现成的拿到教程里用下,但发现貌似只有一篇,是2005年时jhkdiy写的,而且翻来翻去发现所有图片也都失效了。所以准备自己写一个算了,一劳永逸,还是拿jhkdiy前辈的作品为基础,大量的内容都是抄用原文的,只是把已经丢失的部分都补上,毕竟大家看那个内容应该已经习惯了。 正文: 现在很多朋友都在学习汇编语言,

codemanrock 4789

通过 CoovaChilli 和 FreeRADIUS 搭建一个公共 Wi-Fi 的认证系统,实现用户连接到 Wi-Fi 后通过 Captive Portal(强制登录页面)进行认证

要实现固定设备连接的功能,你可以通过MAC 地址认证来限制哪些设备可以通过 FreeRADIUS 进行身份验证和连接。你可以在 FreeRADIUS 的users文件中直接配置允许的设备的 MAC 地址,也可以通过数据库存储和查询设备信息,进一步提高管理效率。通过这些方法,你可以灵活地控制哪些设备能够访问你的 Wi-Fi 网络。

m0_69943017的博客 2650

Difftest踩坑笔记(一)

Difftest是差分测试框架,有什么用呢?高性能CPU的设计需要做复杂的测试,传统的测试方法运行较慢,而且出了问题很难定位,Difftest就是为了解决这两个问题。

http://www.icfgblog.com/ 4196
上一篇: COCO/R的一个例子(生成中间语言)
下一篇: Eclipse3.5 +tomcatPluginV321配置web环境(转)
deepfuture
博客等级 码龄17年 210粉丝 1287原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值