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

news2024/11/17 21:43:36

 一、需求分析

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

二、构建测试窗口

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

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; 文 件 名:marquee.asm (GUI程序)
; 功    能: 文字动画
; 开发环境:Win10 PRO + MASM32 v22
; 作    者:PurpleEndurer,广西河池
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.586
.MODEL FLAT,STDCALL
OPTION CASEMAP:NONE

INCLUDE \masm32\include\windows.inc

INCLUDE \masm32\include\kernel32.inc
INCLUDELIB \masm32\lib\kernel32.lib

INCLUDE \masm32\include\user32.inc
INCLUDELIB \masm32\lib\user32.lib

include \MASM32\INCLUDE\shell32.inc
includelib \MASM32\LIB\shell32.lib

include \masm32\include\comctl32.inc
includelib \masm32\lib\comctl32.lib
    

;ssssssssssssssssssssssss
;.const
;ssssssssssssssssssssssss

c_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
;ssssssssssssssssssssssss

WinMain          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, 广西河池", 0

g_szBtnClsName  db "button", 0
g_szScan_btn    db "开始扫描", 0   ;_btn 用于按钮
g_szStop_btn    db "点击停止", 0
g_szLoopTxt_btn db "点击停止", 0

g_szScanning_Sb db "—正在扫描……", 0; _Sb用于状态栏
g_szScanOver_Sb db "扫描完成", 0      ;  
g_dwLoop_Sb     dword 0

g_hInstance  HANDLE ?
g_hwndMain   HANDLE ?
g_hStatusBar HANDLE ?
g_hBtn       HANDLE ?

;ssssssssssssssssssssssss
.CODE
;ssssssssssssssssssssssss
start:
  invoke GetModuleHandle, NULL
  mov    g_hInstance, eax
  invoke WinMain, g_hInstance, NULL, NULL, SW_SHOWDEFAULT
  invoke ExitProcess, eax
  invoke InitCommonControls


;======================================================
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
;======================================================
 LOCAL wc:WNDCLASSEX
 LOCAL msg:MSG
 
 mov    wc.cbSize,SIZEOF WNDCLASSEX
 mov    wc.style, CS_HREDRAW or CS_VREDRAW
 mov    wc.lpfnWndProc, OFFSET WndProc
 mov    wc.cbClsExtra, NULL
 mov    wc.cbWndExtra, NULL
 push   hInst
 pop    wc.hInstance
 mov    wc.hbrBackground, COLOR_WINDOW+1
 mov    wc.lpszMenuName, NULL  ;OFFSET MenuName
 mov    wc.lpszClassName, OFFSET g_szClassName
 invoke LoadIcon,NULL,IDI_APPLICATION   ;invoke LoadIcon, hInst, IDI_ICON
 mov    wc.hIcon, eax
 mov    wc.hIconSm, eax
 invoke LoadCursor, NULL, IDC_ARROW
 mov    wc.hCursor, eax
 invoke RegisterClassEx, addr wc

 INVOKE CreateWindowEx, c_MainWinStyle, ADDR g_szClassName,ADDR g_szAppInfo,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT,500,400,NULL,NULL, hInst,NULL
 mov    g_hwndMain, eax
 INVOKE ShowWindow, g_hwndMain, SW_SHOWNORMAL
 INVOKE UpdateWindow, g_hwndMain
 .WHILE TRUE
        INVOKE GetMessage, ADDR msg,NULL,0,0
        .BREAK .IF (!eax)
        INVOKE TranslateMessage, ADDR msg
        INVOKE DispatchMessage, ADDR msg
 .ENDW
 mov     eax, msg.wParam
 ret
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_statusBarID
    mov    g_hStatusBar, eax

    ;创建按钮
    invoke CreateWindowEx, NULL, ADDR g_szBtnClsName, ADDR g_szScan_btn,\
             c_BtnStyle, 75,70,140,25, hWnd, c_BtnID, g_hInstance, NULL
    mov    g_hBtn, eax

 .ELSEIF eax==WM_COMMAND
   mov eax,wParam
   .if ax==c_BtnID
       shr eax,16
       .IF ax==BN_CLICKED
           ;用户点击按钮
           .if  g_dwLoop_Sb==0
                ;进行扫描状态
                invoke SetTimer, hWnd, c_TimerID, 1000, NULL
		            mov    eax, OFFSET g_szStop_btn
	         .else
		            ;退出扫描状态
                invoke KillTimer, hWnd, c_TimerID 
		            mov    g_dwLoop_Sb, 0
		            invoke SendMessage, g_hStatusBar, SB_SETTEXT, 0, OFFSET g_szScanOver_Sb
		            invoke RedrawWindow, g_hStatusBar, NULL, NULL, RDW_INTERNALPAINT    
		            mov    eax, OFFSET g_szScan_btn				
	         .endif
	         invoke SendMessage, g_hBtn ,WM_SETTEXT, 0, eax
       .ENDIF
    .endif     
 .ELSEIF eax==WM_TIMER
    ;定时调用Marquee函数
    invoke Marquee
 .ELSEIF eax==WM_SIZE
    invoke ResizeMainWnd
 .ELSEIF eax==WM_DESTROY
     invoke PostQuitMessage,NULL
 .ELSE
  invoke DefWindowProc,hWnd,uMsg,wParam,lParam
  ret
 .ENDIF
 xor eax,eax
 ret
WndProc endp


;======================================================
ResizeMainWnd proc
;======================================================
    invoke MoveWindow, g_hStatusBar, 0, 0, 0, 0, TRUE
    ret
ResizeMainWnd endp

END 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 > 4
        mov g_dwLoop_Sb, 1 
    .endif

    mov eax, offset g_szScanning_Sb

    .if g_dwLoop_Sb==1
        mov word ptr [eax], 0DCA3h;'\'
    .elseif g_dwLoop_Sb==2
        mov word ptr [eax], 0FCA3h;'|'
    .elseif g_dwLoop_Sb==3
        mov word ptr [eax], 0AFA3h;'/'
    .elseif g_dwLoop_Sb==4
         mov word ptr [eax], 0AAA1h;'—'
    .endif

    invoke SendMessage, g_hStatusBar, SB_SETTEXT, 0, OFFSET g_szScanning_Sb
    invoke RedrawWindow, g_hStatusBar, NULL, NULL, RDW_INTERNALPAINT    

    ret
statusBarMarquee endp

四、按钮跑马灯

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

代码如下:

;======================================================
Marquee proc
;======================================================
    invoke btnMarquee
    invoke 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 eax
    inc eax

    ; 按钮文字前移
    .while byte ptr [eax]!=0
        push word ptr [eax]
        pop  word ptr [eax-2]
        inc  eax
        inc  eax
    .endw

    ;把按钮文本首字放到末尾
    pop word ptr [eax-2] ;mov word ptr [eax-2], bx

    invoke SendMessage, g_hBtn ,WM_SETTEXT, 0, OFFSET g_szLoopTxt_btn
    invoke RedrawWindow, g_hBtn, NULL, NULL, RDW_INTERNALPAINT    

    ret
btnMarquee endp

五、程序运行效果

如下:

六、改进思路

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

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

七、附记

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

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

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

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

相关文章

喜报 | 再度中标南网项目!AR 开启电力远程运维新智慧

近日&#xff0c;中国南方电网官网发布《2023年南方电网数字平台科技 (广东)有限公司物资品控远程协助软件采购项目中标公告》&#xff0c;ALVA Systems 凭借 ALVA Rainbow 创新应用竞得此标。 随着相关技术的逐步成熟&#xff0c;基础问题远程化解决已经在工业领域广泛应用。 …

Python中的装饰器

迷途小书童的 Note 读完需要 5分钟 速读仅需 2 分钟 装饰器是一个非常有用而又常被误解的功能&#xff0c;可以让我们在不修改函数或类的源代码情况下给它们提供扩展功能。本文将通过具体示例带你深入理解 Python 装饰器的用法。 1 装饰器基础 装饰器本质上是一个函数&#xff…

SpringMVC的简介及工作流程

一.简介 Spring MVC是一个基于Java的开发框架&#xff0c;用于构建灵活且功能强大的Web应用程序。它是Spring Framework的一部分&#xff0c;提供了一种模型-视图-控制器&#xff08;Model-View-Controller&#xff0c;MVC&#xff09;的设计模式&#xff0c;用于组织和管理Web…

职责链设计模式

职责链模式又叫命令链、CoR、Chain of Command、Chain of Responsibility。 该模式允许你将请求沿着处理者链进行发送&#xff0c;使多个对象都可以处理请求&#xff0c;每个对象有权决定处理或传递给下个节点。 客户端&#xff1a;用来定义职责链条。 处理者&#xff1a;声明…

基于Vgg-Unet模型自动驾驶场景检测

1.VGG VGG全称是Visual Geometry Group属于牛津大学科学工程系&#xff0c;其发布了一些列以VGG开头的卷积网络模型&#xff0c;可以应用在人脸识别、图像分类等方面,VGG的输入被设置为大小为224x244的RGB图像。为训练集图像上的所有图像计算平均RGB值&#xff0c;然后将该图像…

vscode上搭建go开发环境

前言 Go语言介绍&#xff1a; Go语言适合用于开发各种类型的应用程序&#xff0c;包括网络应用、分布式系统、云计算、大数据处理等。由于Go语言具有高效的并发处理能力和内置的网络库&#xff0c;它特别适合构建高并发、高性能的服务器端应用。以下是一些常见的Go语言应用开发…

静态路由配置出错记录

根据实验手册&#xff0c;配置静态路由&#xff0c;但是怎么也排除不了错误。 最后发现&#xff0c;是自己的默认网关配置错误了。但是使用模拟器抓包看到的&#xff0c;也没有提示网关信息啊。

docker desktop如何一键进入容器内部

对着对应的容器 点击 view files

电压互感器倍频感应耐压试验注意事项

注意事项 被试 PT 在三倍频耐压时呈容性&#xff0c; 对于 110kV、 220kV 互感器进行感应耐压试验时&#xff0c;应在开口 a D x D 端子间励磁&#xff0c; 可在 PT 二次绕组 ax 上接补偿电感&#xff0c; 对于 35kV 电压互感器励磁电压一般加至二次 a—x 间&#xff1b;三倍频…

测开之 Python 自动化全栈工程师 + 性能专项

功能测试基础 接口测试基础 接口的通信原理与本质 cookie、session、token 详解 接口测试的意义与测试方法 接口测试用例的设计 app 测试 app 流程测试 app 兼容性测试 app 稳定性测试 app 性能专项测试 app 抓包 UI 功能测试基础 常见功能测试方法&#xff1a;等价类&…

JVM | 垃圾回收器(GC)- Java内存管理的守护者

引言 在编程世界中&#xff0c;有效的内存管理是至关重要的。这不仅确保了应用程序的稳定运行&#xff0c;还可以大大提高性能和响应速度。作为世界上最受欢迎的编程语言之一&#xff0c;通过Java虚拟机内部的垃圾回收器组件来自动管理内存&#xff0c;是成为之一的其中一项必…

极米RS Pro 3投影参数是多少?极米投影仪RS Pro 3好用吗?

近年来&#xff0c;随着投影技术的快速发展&#xff0c;越来越多的用户开始选择投影产品来打造家庭影院&#xff0c;为生活带来新的观影体验。但要想打造一个家庭影院&#xff0c;选到一台合适的投影仪却并不是一件容易的事&#xff0c;因为家庭影院对画面的亮度、色彩和观影舒…

(18)线程的实例认识:线程的控制,暂停,继续,停止,线程相互控制,协作

一、老方式 1、这是一个老的实现方式&#xff0c;基本不推荐&#xff0c;背后控制的原理需要了解。 界面&#xff1a;三个button一个textbox 代码&#xff1a; private volatile bool isPause false;//fprivate void BtnStart_Click(object…

力扣|两数相加

先放题目&#xff1a; 给你两个非空的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c…

敏捷开发方法:快速响应需求变化的开发流程

在快速变化的技术和市场环境下&#xff0c;传统的软件开发方法可能显得笨重和不灵活。敏捷开发方法应运而生&#xff0c;以其快速响应需求变化、持续交付和团队协作的特点&#xff0c;成为现代软件开发的重要方法之一。本文将深入探讨敏捷开发方法的概念、原则、流程以及在实际…

《王道24数据结构》课后应用题——第三章 栈和队列

第三章 【3.1】 03、 假设以I和O分别表示入栈和出操作。栈的初态和终态均为空&#xff0c;入栈和出栈的操作序列可表示为仅由I和O组成的序列&#xff0c;可以操作的序列称为合法序列&#xff0c;否则称为非法序列。 如IOIIOIOO 和IIIOOIOO是合法的&#xff0c;而IOOIOIIO和II…

maven基础学习

什么是maven 构建 依赖 maven核心概念坐标 在黑窗口使用maven命令生成maven工程 pom.xml 想导入哪个jar包把它的坐标放到dependency里就可以 maven核心概念POM maven核心概念约定的目录结构 执行maven的构建命令 清理操作&#xff0c;clean 编译操作 compile 测试操作 test 打包…

ElasticSearch进阶

一、 search检索文档 ES支持两种基本方式检索&#xff1b; 通过REST request uri 发送搜索参数 &#xff08;uri 检索参数&#xff09;&#xff1b;通过REST request body 来发送它们&#xff08;uri请求体&#xff09;&#xff1b; 1、信息检索 API&#xff1a; https://w…

Mybatis的关联关系配置一对一,一对多,多对多的映射关系

目录 关联关系映射 一对一关联&#xff1a; 一对多关联&#xff1a; 多对多关联&#xff1a; 导入数据库表 一对多 一对一 多对多 关联关系映射 关联关系映射在Mybatis中主要通过三种方式实现&#xff1a;一对一关联和一对多关联及多对多关联。 一对一关联&#xff1a;…

算法 数据结构 双向环形链表 手撸环形链表 环形链表实现容器 环形链表添加修改删除获取大小 环形链表实现自定义容器 手撸容器 双向环形哨兵链表 算法(六)

1. 环形链表&#xff1a; 2. 建议先不要看我写得自己先实现下&#xff0c;只将Node内部类复制自己命名得容器内&#xff0c; 实现方法&#xff1a; a. add方法&#xff08;添加到头部&#xff0c;尾部添加&#xff0c;指定位置添加&#xff09; b. get方法&#xff08;获取首部…