MASM32编程状态栏显示字符动画,按钮跑马灯

 一、需求分析

由于sysInfo扫描的内容比较多,打算为它增加一点动画效果,提醒用户程序正在运行,耐心等待。

二、构建测试窗口

测试窗口上放置有一个按钮,按钮上的初始文字是“开始扫描”;并使用状态栏,状态栏初始状态不显示文字。

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; 文 件 名:marquee.asm (GUI程序)
; 功    能: 文字动画
; 开发环境:Win10 PRO + MASM32 v22
; 作    者:PurpleEndurer,广西河池
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<.586
.MODEL FLAT,STDCALL
OPTION CASEMAP:NONEINCLUDE \masm32\include\windows.incINCLUDE \masm32\include\kernel32.inc
INCLUDELIB \masm32\lib\kernel32.libINCLUDE \masm32\include\user32.inc
INCLUDELIB \masm32\lib\user32.libinclude \MASM32\INCLUDE\shell32.inc
includelib \MASM32\LIB\shell32.libinclude \masm32\include\comctl32.inc
includelib \masm32\lib\comctl32.lib;ssssssssssssssssssssssss
;.const
;ssssssssssssssssssssssssc_MainWinStyle   equ NULL
c_statusBarStyle equ SBARS_SIZEGRIP or WS_CHILD or WS_VISIBLE
c_BtnStyle       equ WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON
c_BtnID          equ 198
c_statusBarID    equ 199
c_TimerID        equ 1000;ssssssssssssssssssssssss
;PROTO
;ssssssssssssssssssssssssWinMain          proto :HINSTANCE, :HINSTANCE, :LPSTR, :DWORD
WndProc          proto :HWND, :UINT, :WPARAM, :LPARAM
ResizeMainWnd    proto
Marquee          proto
statusBarMarquee proto
btnMarquee       proto;ssssssssssssssssssssssss
.DATA
;ssssssssssssssssssssssss
g_szClassName label byte
g_szAppInfo   db "文字动画 作者:PurpleEndurer, 广西河池", 0g_szBtnClsName  db "button", 0
g_szScan_btn    db "开始扫描", 0   ;_btn 用于按钮
g_szStop_btn    db "点击停止", 0
g_szLoopTxt_btn db "点击停止", 0g_szScanning_Sb db "—正在扫描……", 0; _Sb用于状态栏
g_szScanOver_Sb db "扫描完成", 0      ;  
g_dwLoop_Sb     dword 0g_hInstance  HANDLE ?
g_hwndMain   HANDLE ?
g_hStatusBar HANDLE ?
g_hBtn       HANDLE ?;ssssssssssssssssssssssss
.CODE
;ssssssssssssssssssssssss
start:invoke GetModuleHandle, NULLmov    g_hInstance, eaxinvoke WinMain, g_hInstance, NULL, NULL, SW_SHOWDEFAULTinvoke ExitProcess, eaxinvoke InitCommonControls;======================================================
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
;======================================================LOCAL wc:WNDCLASSEXLOCAL msg:MSGmov    wc.cbSize,SIZEOF WNDCLASSEXmov    wc.style, CS_HREDRAW or CS_VREDRAWmov    wc.lpfnWndProc, OFFSET WndProcmov    wc.cbClsExtra, NULLmov    wc.cbWndExtra, NULLpush   hInstpop    wc.hInstancemov    wc.hbrBackground, COLOR_WINDOW+1mov    wc.lpszMenuName, NULL  ;OFFSET MenuNamemov    wc.lpszClassName, OFFSET g_szClassNameinvoke LoadIcon,NULL,IDI_APPLICATION   ;invoke LoadIcon, hInst, IDI_ICONmov    wc.hIcon, eaxmov    wc.hIconSm, eaxinvoke LoadCursor, NULL, IDC_ARROWmov    wc.hCursor, eaxinvoke RegisterClassEx, addr wcINVOKE CreateWindowEx, c_MainWinStyle, ADDR g_szClassName,ADDR g_szAppInfo,\WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,500,400,NULL,NULL, hInst,NULLmov    g_hwndMain, eaxINVOKE ShowWindow, g_hwndMain, SW_SHOWNORMALINVOKE UpdateWindow, g_hwndMain.WHILE TRUEINVOKE GetMessage, ADDR msg,NULL,0,0.BREAK .IF (!eax)INVOKE TranslateMessage, ADDR msgINVOKE DispatchMessage, ADDR msg.ENDWmov     eax, msg.wParamret
WinMain endp;======================================================
WndProc proc uses ebx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
;======================================================mov eax, uMsg.IF eax==WM_CREATE;创建状态栏invoke CreateStatusWindow, c_statusBarStyle, NULL, hWnd, c_statusBarIDmov    g_hStatusBar, eax;创建按钮invoke CreateWindowEx, NULL, ADDR g_szBtnClsName, ADDR g_szScan_btn,\c_BtnStyle, 75,70,140,25, hWnd, c_BtnID, g_hInstance, NULLmov    g_hBtn, eax.ELSEIF eax==WM_COMMANDmov eax,wParam.if ax==c_BtnIDshr eax,16.IF ax==BN_CLICKED;用户点击按钮.if  g_dwLoop_Sb==0;进行扫描状态invoke SetTimer, hWnd, c_TimerID, 1000, NULLmov    eax, OFFSET g_szStop_btn.else;退出扫描状态invoke KillTimer, hWnd, c_TimerID mov    g_dwLoop_Sb, 0invoke SendMessage, g_hStatusBar, SB_SETTEXT, 0, OFFSET g_szScanOver_Sbinvoke RedrawWindow, g_hStatusBar, NULL, NULL, RDW_INTERNALPAINT    mov    eax, OFFSET g_szScan_btn				.endifinvoke SendMessage, g_hBtn ,WM_SETTEXT, 0, eax.ENDIF.endif     .ELSEIF eax==WM_TIMER;定时调用Marquee函数invoke Marquee.ELSEIF eax==WM_SIZEinvoke ResizeMainWnd.ELSEIF eax==WM_DESTROYinvoke PostQuitMessage,NULL.ELSEinvoke DefWindowProc,hWnd,uMsg,wParam,lParamret.ENDIFxor eax,eaxret
WndProc endp;======================================================
ResizeMainWnd proc
;======================================================invoke MoveWindow, g_hStatusBar, 0, 0, 0, 0, TRUEret
ResizeMainWnd endpEND start

三、在状态栏显示字符动画

记得以前DOS时代使用冠群金辰的杀毒软件kill,在扫描时会显示一个扫描形状的字符动画,当时觉得很有意思,映像深刻,这次就把这种效果用在状态栏上。

实现的方法就是当用户点扫描使用定时器定时刷新状态栏的文字。其中的扫描动态效果就是将依次状态栏文字的首字依次更新为—(编码:0AAA1h)、\(编码:0DCA3h)、|(编码:0FCA3h)、/(编码:0AFA3h)。

代码如下:


;======================================================
Marquee proc
;======================================================invoke statusBarMarquee ret
Marquee endp;======================================================
statusBarMarquee proc uses eax
;======================================================inc g_dwLoop_Sb.if g_dwLoop_Sb > 4mov g_dwLoop_Sb, 1 .endifmov eax, offset g_szScanning_Sb.if g_dwLoop_Sb==1mov word ptr [eax], 0DCA3h;'\'.elseif g_dwLoop_Sb==2mov word ptr [eax], 0FCA3h;'|'.elseif g_dwLoop_Sb==3mov word ptr [eax], 0AFA3h;'/'.elseif g_dwLoop_Sb==4mov word ptr [eax], 0AAA1h;'—'.endifinvoke SendMessage, g_hStatusBar, SB_SETTEXT, 0, OFFSET g_szScanning_Sbinvoke RedrawWindow, g_hStatusBar, NULL, NULL, RDW_INTERNALPAINT    ret
statusBarMarquee endp

四、按钮跑马灯

窗口上的按钮初始文字是“开始扫描”,当我们点击按钮进入扫描状态时,我们将按钮文字改成“点击停止”并跑马灯。原理也是使用定时器,定期更新按钮上的文字。

代码如下:

;======================================================
Marquee proc
;======================================================invoke btnMarqueeinvoke statusBarMarquee ret
Marquee endp;======================================================
btnMarquee proc uses eax ;ebx
;======================================================mov eax, offset g_szLoopTxt_btn;保存按钮文本首字push word ptr [eax] ;mov bx, word ptr [eax]inc eaxinc eax; 按钮文字前移.while byte ptr [eax]!=0push word ptr [eax]pop  word ptr [eax-2]inc  eaxinc  eax.endw;把按钮文本首字放到末尾pop word ptr [eax-2] ;mov word ptr [eax-2], bxinvoke SendMessage, g_hBtn ,WM_SETTEXT, 0, OFFSET g_szLoopTxt_btninvoke RedrawWindow, g_hBtn, NULL, NULL, RDW_INTERNALPAINT    ret
btnMarquee endp

五、程序运行效果

如下:

六、改进思路

文字动画在DOS的CGI时代还是颇具吸引力的,放到GUI时代复古一下也是一种怀念。

如果我们追求GUI的效果,可以对状态栏进行子类化,为它创建一个进度条。对按钮子类化,显示gif图片。

七、附记

进入Windows时代,Kill就像UCDOS一样淡出视野了。刚才为了确认无误,bing查了一下,冠群金辰的网站还在,只是内容很久没更新了。

不经意间顺带看到一篇关于火绒的文章,才知道火绒的几位创始人都出自瑞星……

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

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

相关文章

视频垂直镜像播放,为您的影片带来新鲜感

大家好&#xff01;在制作视频时&#xff0c;我们常常希望能够给观众带来一些新鲜感和独特的视觉效果。而垂直镜像播放是一个能够让您的影片与众不同的技巧。然而&#xff0c;传统的视频剪辑软件往往无法直接实现视频的垂直镜像播放&#xff0c;给我们带来了一些困扰。现在&…

Jtti:Web Service中session和cookie如何使用

在 Web 服务中&#xff0c;会话(session)和 Cookie 是用于跟踪用户状态和维护持久性数据的两个常用机制。它们通常用于不同的用途&#xff0c;但也可以结合使用以实现更复杂的功能。以下是关于如何在 Web 服务中使用会话和 Cookie 的一些基本信息&#xff1a; 使用会话&#xf…

基于Python的IOS自动化测试环境搭建

文章目录 一、测试架构介绍1.1 WebDriverAgent原理分析1.2 tidevice原理分析二、环境安装2.1 iOS 设备安装 WebDriverAgent2.2 安装iTunes2.3 安装tidevice2.4 安装facebook-wda自动化三、操作流程四、Weditor的安装和使用一、测试架构介绍 以下为测试架构原理图 手机端的WDA…

QT C++ 基于TCP通信的网络聊天室

一、基本原理及流程 1&#xff09;知识回顾&#xff08;C语言中的TCP流程&#xff09; 2&#xff09;QT中的服务器端/客户端的操作流程 二、代码实现 1&#xff09;服务器 .ui .pro 在pro文件中添加network库 .h #ifndef WIDGET_H #define WIDGET_H#include <QWidget>…

危险边缘:揭示 Python 编程中易被忽视的四个安全陷阱

今天我们将要谈论一个非常重要的话题&#xff1a;Python 编程中的安全问题。作为一门广受欢迎的编程语言&#xff0c;Python 已经成为了许多开发者、计算机专业学生以及打工人的必备技能。 原文链接食用更佳 危险边缘&#xff1a;揭示 Python 编程中易被忽视的四个安全问题 然…

配电柜监控的真正标准,只有一个!

在现代社会中&#xff0c;电力是我们生活和工作不可或缺的一部分。大楼宾馆作为城市中繁忙生活的一部分&#xff0c;依赖于可靠的电力供应来支持各种设施和服务&#xff0c;从客房照明到电梯运行&#xff0c;无一不离电。然而&#xff0c;大楼宾馆电力分配系统的稳定性和安全性…

【javascript】禁止浏览器调试前端页面

目录 为啥要禁止&#xff1f;无限 debugger基础禁止调试解决对策 为啥要禁止&#xff1f; 由于前端页面会调用很多接口&#xff0c;有些接口会被别人爬虫分析&#xff0c;破解后获取数据&#xff0c;为了杜绝这种情况&#xff0c;最简单的方法就是禁止人家调试自己的前端代码 …

深入理解联邦学习——联邦学习概念的产生

分类目录&#xff1a;《深入理解联邦学习》总目录 从1955年达特茅斯会议开始&#xff0c;人工智能经过两起两落的发展&#xff0c;迎来了第三个高峰期。第一个高峰期的出现是因为人们看到了AI的希望&#xff0c;也就是自动化算法对提高效率的希望&#xff0c;但是受算法能力的限…

ffmpeg批量转码

新建.bat文件 echo offfor %%s in (*.mp4) do ( echo %%s ffmpeg -i %%s -b 7M %%~ns7m.mp4 ) pause如果你的电脑有显卡&#xff0c;也可以使用硬件转码。转码程序链接

【微服务部署】二、Jenkins一键打包部署SpringBoot应用步骤详解

本文介绍使用Jenkins一键将SpringBoot应用打包并上传到生产环境服务器运行,这里使用的是直接在服务器上运行FagJar的方式,首先确保服务器环境配置好,安装必须的JDK运行时环境,运行目录,日志存放目录等。 一、服务器环境配置 关于JDK的选择,自1.8版本收费之后,我们大多数…

docker 笔记10:Docker轻量级可视化工具Portainer

1. 是什么 Portainer 是一款轻量级的应用&#xff0c;它提供了图形化界面&#xff0c;用于方便地管理Docker环境&#xff0c;包括单机环境和集群环境。 2.安装 https://docs.portainer.io/v/ce-2.9/start/install/server/docker/linux 步骤 docker命令安装 docker run -d …

生成12位短id,自增且不连续,永不重复,不依赖数据库

基本思路&#xff1a; 设计模式&#xff1a;单例模式 是否加锁&#xff1a;是 synchronized 获取最后一次生成的时间戳值T0 限定初始时间为2023-08-01 00:00:00,获取当前时间时间戳T1,T1与初始时间的毫秒差值T2,转为16进制&#xff0c;转为字符串为r1,获取该字符串的长度L1…

攻防世界-Hear-with-your-Eyes

原题 解题思路 是一个没有后缀的文件&#xff0c;题目提示要用眼睛看这段音频&#xff0c;notepad打开文件&#xff0c;没什么东西。 加后缀zip再解压看看。 使用Audacity打开音频文件

Mysql高阶语句(二)

一、设置别名&#xff08;alias ——>as&#xff09; 在 MySQL 查询时&#xff0c;当表的名字比较长或者表内某些字段比较长时&#xff0c;为了方便书写或者 多次使用相同的表&#xff0c;可以给字段列或表设置别名。使用的时候直接使用别名&#xff0c;简洁明了&#xff0…

面试被问到:测试计划和测试方案有什么区别?你会回答吗~

面试的时候&#xff0c;很多小伙伴都被面试官问过这个问题 “测试计划和测试方案有什么区别”&#xff1f; 到底有什么区别呢&#xff1f;我们先好好了解下这两个文档。 一、测试计划 1、测试计划是什么 测试计划是组织管理层面的文件&#xff0c;从组织管理的角度对一次测…

【已解决】oracle获取最近2学年的数据

已解决 &#xff1a;oracle获取最近2学年的数据 SELECT * FROM (SELECT * FROM xx.JWXT_XSKB WHERE AND xn IN (‘2023-2024’,‘2022-2023’)); 问题 某某系统课表数据过大&#xff0c;要求只获取最近2学年的数据&#xff0c;不能写死。 思路 mysql 在子查询的WHERE子句中…

存量时代的面经

spring-series,感谢这个项目的作者,还有springboot_learn 这个项目 Spring, 说来惭愧,接触spring 已经接近十年了 通过这个项目,我把spring重写的学习了一遍 1,早上先debug 的一个项目的源码是 springboot_security 在这里插入代码片/****: Creating filter chain:org…

大规模场景下对Istio的性能优化

简介 当前istio下发xDS使用的是全量下发策略&#xff0c;也就是网格里的所有sidecar(envoy)&#xff0c;内存里都会有整个网格内所有的服务发现数据。这样的结果是&#xff0c;每个sidecar内存都会随着网格规模增长而增长。 Aeraki-mesh aeraki-mesh项目下有一个子项目专门用来…

【数据结构初阶】一. 复杂度讲解

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 学C的第三十四天【程序环境和预处理】_高高的胖子的博客-CSDN博客 1 . 算法效率 &#xff08;1&#xff09;. 什么是数据结构&#xff1a; 数据结构(Data Structure)是计算机存储、…

STM32G030F6 (SOP-20)Cortex ® -M0+, 32KB Flash, 8KB RAM, 17 GPIOs

淘宝淘了一批 STM32G030F6P6 SOP20&#xff0e;先备注一下, 还没想到能干嘛用&#xff0e; 手上的 STM32F103C6T6还剩一些&#xff0e; 一堆 “淘宝原厂STM32F103C8T6”, 还烫着手. 理解信息: ( 逐步补充 ) System Clock GPIOs GPIOs 17 PA[7:0] : 8bits USART Timer ADC I2…