首页 > 编程语言 >MASM32编程状态栏显示字符动画,按钮跑马灯

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

时间:2023-09-04 23:32:36浏览次数:47  
标签:word 状态栏 eax 显示字符 mov 跑马灯 按钮 Sb ptr

一、需求分析

由于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

程序运行效果如下:

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

五、改进思路

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

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

六、附记

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

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

标签:word,状态栏,eax,显示字符,mov,跑马灯,按钮,Sb,ptr
From: https://blog.51cto.com/endurer/7365228

相关文章

  • 状态栏消息处理
    代码实现: classSapMessageType(enum.Enum):SUCCESS="S"WARNING="W"ERROR="E"ABORT="A"INFORMATION="I"classSapStatusMessage:def__init__(self,message_as_popup,messag......
  • Ubuntu22隐藏上方的状态栏(hide top bar):安装hide top bar这个GNOME插件
    参考链接:https://techithings.hashnode.dev/ubuntu-how-to-hide-top-bar-and-side-bar具体步骤1.安装extensionmanger这个软件sudoapt-getupdatesudoapt-getinstallgnome-shell-extension-manager-y2.打开软件extension-manager3.点击browse,搜索hidetopbar这个插......
  • 【HarmonyOS】API9沉浸式状态栏
    对于沉浸式状态栏,在之前API8FA模型开发中可以通过在config.json配置主题的方式实现应用的沉浸式体验,在最新的API9Stage模型中系统提供了沉浸式窗口的示例(管理应用窗口(Stage模型)-窗口管理-开发-HarmonyOS应用开发)。通过调用setWindowSystemBarEnable接口,设置导航栏、状态栏不显示,......
  • 跑马灯字幕——旧版标题功能
    新建,文字,旧版标题把文字复制进去选择滚动,就能跑起来了插入图片就可以在滚动的时候加入图片了......
  • 2-3 list2-8 逐个显示字符,再逐个消去
    #include<stdio.h>#include<time.h>#include<string.h>//等待x毫秒intsleep(unsignedlongx){clock_tc1=clock(),c2;do{if((c2=clock())==(clock_t)-1)return0;}while((c2-c1)<x);return1;}int......
  • 工控 上位机 WPF 跑马灯的实现
    工控上位机WPF跑马灯的实现 工业控制软件中,跑马灯是主界面比不可少的组件。本文基于WPF技术,讲解如何实现高效的跑马灯组件。 跑马灯的效果如下图: 在讲解如何实现之前,我们先看一下,跑马灯组件在主界面上是如何使用的,请看如下代码:<BorderGrid.Row=......
  • 直播app开发,页面顶部图片延伸到状态栏
    直播app开发,页面顶部图片延伸到状态栏 if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){     //5.0全透明实现  //getWindow.setStatusBarColor(Color.TRANSPARENT)  Windowwindow=getWindow();  window.clearFlags(WindowManager.Layou......
  • Android App 隐藏标题栏+状态栏+导航栏
    1.隐藏当前Activity标题栏在当前Activity中调用:this.requestWindowFeature(Window.FEATURE_NO_TITLE);2.隐藏当前Activity状态栏(StatusBar)2.1Android4.0andLowerpublicclassMainActivityextendsActivity{@OverrideprotectedvoidonCreate(Bundle......
  • Android实现沉浸式状态栏功能
    Android中实现沉浸式状态栏的功能,供大家参考,具体内容如下1.先上效果图,实现沉浸式状态栏有两种方式,一种是通过写Theme主题的方式,另一种是写代码的方式。若要使多个页面出现沉浸式状态栏,则使用主题的方式更方便,如果只要使单个页面出现,则使用代码方式更好!当然了,看个人喜好而去。......
  • android全屏显示隐藏状态栏
    Android全屏显示隐藏状态栏实现步骤实现Android全屏显示和隐藏状态栏,可以提供更好的用户体验和界面展示。下面是实现这一功能的步骤:步骤操作步骤一设置Activity的主题为全屏主题步骤二隐藏状态栏步骤三显示状态栏步骤四切换状态栏的可见性下面将详细介......