Win32汇编--通用控件 Progress Bar 的使用

来源:互联网 发布:如何评价那英 知乎 编辑:程序博客网 时间:2024/04/29 20:42

  这几天在学通用控件的时候遇到了一些小问题,经过一段时间的折腾终于把这部分给搞定了~

  网络上对win32汇编中Progress Bar的使用没有什么特别详细的教程或者说明,虽然Progress Bar也是通用控件的一种,而对于通用控件而言使用方法也基本一致,但是对于特定的控件在使用方法上还是有一些细微的差别,于是本文将以Progress Bar为实例详细的介绍其使用方法。

  本文实例实现功能很简单:窗口中有一个进度条,进度条满了之后自动退出窗口。

   

  使用Progress Bar的一般步骤如下:

  1.调用InitCommonControls 函数进行一些初始化工作(调用该函数仅仅是为了在我们程序的可执行文件的PE头中的引入段中放入引用了comctl32.dll的信息),当然还得引入相应的头文件    comctl32.inc 、    comctl32.lib

  2.用常规方式创建父窗口--(RegisterClassEx-->CreateWindowEx-->ShowWindow-->UpdateWindow-->消息循环-->窗口过程)

  3.窗口过程中要实现以下步骤:(1)在消息WM_CREATE中创建通用控件Progress Bar、用SetTimer设置定时器。(2)在消息WM_TIMER中处理定时器发送的消息。(3)在消息WM_CLOSE中退出定时器


下面是源代码:

  .386 .model flat,stdcall option casemap:none  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ; Include 文件定义  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  include         windows.incinclude         gdi32.incincludelib      gdi32.libinclude         user32.incincludelib      user32.libinclude         kernel32.incincludelib      kernel32.libinclude        comctl32.incincludelib     comctl32.lib  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ; 数据段  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   .data?hInstance       dd      ?hWinMain        dd      ?hProgressB   dd ?TimerID  dd ?CurrentStep  dd ?    .constszClassName     db      'MyClass',0progressBClassName db 'msctls_progress32',0ID_TIMER equ 1ID_PROGRESSBAR equ 2;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ; 代码段  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   .code  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  ; 窗口过程  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  _ProcWinMain    proc uses ebx edi esi, hWnd, uMsg, wParam, lParam                  local @stPs:PAINTSTRUCT                local @stRect:RECT                local @hDc                 mov eax,uMsg  ;*************************************************************************                .if eax==WM_CREATE                                      invoke     CreateWindowEx, WS_EX_CLIENTEDGE, \                          offset progressBClassName, NULL, \                        LVS_REPORT or WS_CHILD or WS_VISIBLE or WS_BORDER, \               ;通用窗口必须有WS_CHILD属性                        150, 150, 250, 25, \                        hWnd,  ID_PROGRESSBAR, hInstance, NULL   ;要传hWnd不能传hWinMain                                                mov hProgressB,eax                                                mov eax,100              ; the lParam of PBM_SETRANGE message contains the range                         mov CurrentStep,eax                         shl eax,16                   ; the high range is in the high word                        invoke SendMessage,hProgressB,PBM_SETRANGE,0,eax         ;lParam的高16位才是最大值!!                    ;   invoke SendMessage,hProgressB,PBM_SETRANGE,0,100    ;设置范围  最小值和最大值(这样是错误的!)                                                 invoke SendMessage,hProgressB,PBM_SETSTEP,10,0         ;设置步长,后一个一定要设为0                                              invoke SetTimer, hWnd,0,1000,NULL     ;要用hWnd                        mov TimerID,eax                                                               .elseif    eax==WM_TIMER                                       invoke SendMessage,hProgressB,PBM_STEPIT,0,0   ;两参数都为0 return previous position                       sub CurrentStep,10                                              .if  CurrentStep==0                         invoke PostMessage,hWnd,WM_CLOSE,NULL,NULL                       .endif                                                .elseif     eax == WM_PAINT                          invoke     BeginPaint,hWnd,addr @stPs                        mov     @hDc,eax                           invoke GetClientRect,hWnd,addr @stRect                        invoke    DrawText,@hDc,NULL,-1,                         addr @stRect,                         DT_SINGLELINE or DT_CENTER or DT_VCENTER                        invoke     EndPaint, hWnd, addr @stPs  ;***************************************************************************                  .elseif eax == WM_CLOSE                          invoke     DestroyWindow,hWinMain                        invoke     PostQuitMessage,NULL                        invoke KillTimer,hWnd,TimerID  ;***************************************************************************                  .else                          invoke     DefWindowProc,hWnd,uMsg,wParam,lParam                        ret                  .endif  ;***************************************************************************                  xor     eax,eax                ret  _ProcWinMain    endp  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  _WinMain        proc                  local   @stWndClass:WNDCLASSEX                local   @stMsg:MSG                invoke     GetModuleHandle,NULL                mov     hInstance,eax                invoke     RtlZeroMemory,addr @stWndClass,sizeof @stWndClass  ;**************************************************************************  ; 注册窗口类  ;**************************************************************************                  invoke     LoadCursor,0,IDC_ARROW                mov     @stWndClass.hCursor,eax                push    hInstance                pop     @stWndClass.hInstance                mov     @stWndClass.cbSize, sizeof WNDCLASSEX                mov     @stWndClass.style, CS_HREDRAW or CS_VREDRAW                mov     @stWndClass.lpfnWndProc, offset _ProcWinMain                mov     @stWndClass.hbrBackground,COLOR_WINDOW + 1                mov     @stWndClass.lpszClassName, offset szClassName                invoke     RegisterClassEx, addr @stWndClass  ;***************************************************************************  ; 建立并显示窗口  ;***************************************************************************                  invoke     CreateWindowEx, WS_EX_CLIENTEDGE, \                          offset szClassName, NULL, \                        WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE,\                        ;WS_OVERLAPPEDWINDOW, \                        200, 200, 600, 400, \                        NULL, NULL, hInstance, NULL                  mov     hWinMain,eax                  invoke     ShowWindow,hWinMain,SW_SHOWNORMAL                invoke     UpdateWindow,hWinMain  ;**************************************************************************  ; 消息循环  ;**************************************************************************                  .while TRUE                          invoke     GetMessage, addr @stMsg, NULL, 0, 0                        .break     .if eax == 0                        invoke     TranslateMessage, addr @stMsg                        invoke     DispatchMessage, addr @stMsg                  .endw                ret  _WinMain        endp  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  start:               invoke InitCommonControls                 call    _WinMain                  invoke ExitProcess, NULL  ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  end start

特别要注意的几点:

   1.在用CreateWindowEx创建通用控件的时候要指定WS_CHILD和WS_VISIBLE属性,其父窗口是第一次调用CreateWindowExt时创建的窗口;父窗口的句柄为进入过程时传入的参数hWnd

   2.针对Progress Bar控件的消息主要有3个(1)PBM_SETRANGE  此消息是设置进度条的范围。看以下几句代码:
        mov eax,100  ; the lParam of PBM_SETRANGE message contains the range 
        mov CurrentStep,eax 
        shl eax,16    ; the high range is in the high word 
        invoke SendMessage,hProgressB,PBM_SETRANGE,0,eax         ;lParam的高16位才是最大值!!


      lParam是一个32位的数,其高16位为最大值(默认为100),低16位为最小值(最小为0)、wParam字段必须设置为0
     看MSDN里里对此消息的说明便知:
        
wParam 
   Must be zero. 
lParam 
  The LOWORD specifies the minimum range value, and the HIWORD specifies the maximum range value. The minimum range value must not be negative. By default, the minimum value is zero. The maximum range value must be greater than the minimum range value. By default, the maximum range value is 100


(2)第二个消息是PBM_SETSTEP 此消息是用来设置步长 与上一个消息相反,其lParam字段必须设为0,wParam字段为增加的步长

(3)第三个消息是PBM_STEPIT 此消息用来更新Progress Bar使其前进一个步长 。其lParam和wParam字段都要设置为0

 


原创粉丝点击