首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

Win32 組合語言教程:通用控件完整指南與實作範例

     編輯:組合語言

前言

在 Windows 95 時代,微軟引入了一系列強化的用戶界面控件,統稱為「通用控件」。這些控件包含工具列、狀態列、樹狀檢視、清單檢視、進度條、分頁控件等,極大地豐富了視窗應用程式的互動體驗。本文將系統介紹通用控件的架構、初始化機制、類別名稱對照表,並提供 MASM 組合語言實作範例,示範進度條與狀態列的協同運作。

通用控件總覽

Windows 95 相較於 Windows 3.x,內建了多種現代化界面元件。早期程式設計師需自行繪製這些控件,如今它們已封裝於 comctl32.dll 中,供所有應用程式共享,節省記憶體資源。主要控件如下:

  • Toolbar:工具列
  • Tooltip:提示文字
  • Status bar:狀態列
  • Property sheet / Property page:屬性頁/屬性頁籤
  • Tree view / List view:樹狀/清單檢視
  • Animation / Progress bar / Trackbar / Up-down:動畫、進度條、追蹤條、微調控件
  • Tab / Hot-key / Image list / Header / Drag list:分頁、熱鍵、影像清單、表頭、可拖曳清單

除 Rich Edit 控件(位於 richedxx.dll)外,其餘控件程式碼皆集中於 comctl32.dll,採動態連結方式載入,避免重複佔用記憶體。

初始化機制深度解析

呼叫 InitCommonControls 函式是使用通用控件的前置條件。該函式本體僅有一條 ret 指令,真正目的是在程式的 PE 標頭「匯入表」中註冊 comctl32.dll,使載入器自動映射該 DLL。實際的控件類別註冊工作發生於 DLL 進入點,完成後即可透過 CreateWindowEx 以類別名稱建立控件實例。

Rich Edit 掃描則需額外呼叫 LoadLibrary 動態載入 richedxx.dll,用畢再以 FreeLibrary 釋放。

控件建立方式與類別名稱對照表

幾乎所有通用控件皆可透過 CreateWindowEx 或 CreateWindow 建立,只需傳入正確的類別名稱。部分控件提供封裝函式以簡化操作:

CreateToolbarEx
CreateStatusWindow
CreatePropertySheetPage
PropertySheet
ImageList_Create

以下為標準類別名稱(VC++ 資源編輯器標準,與其他文獻可能不同):

類別名稱對應控件
ToolbarWindow32Toolbar
tooltips_class32Tooltip
msctls_statusbar32Status bar
SysTreeView32Tree view
SysListView32List view
SysAnimate32Animation
SysHeader32Header
msctls_hotkey32Hot-key
msctls_progress32Progress bar
RICHEDITRich edit
msctls_updown32Up-down
SysTabControl32Tab

Property Sheet、Image List 等擁有專屬建立函式;Drag List 實為可伸縮 ListBox,無獨立類別名稱。

通訊機制:WM_NOTIFY

通用控件與父視窗通訊不使用 WM_COMMAND,改以 WM_NOTIFY 傳遞 NMHDR 結構指標,父視窗則發送 TVM_、LVM_ 等專用訊息控制控件行為。控件專有樣式(如 Tree View 的 TVS_XXXX、List View 的 LVS_XXXX)需參考 Win32 API 文件設定。

實作範例:進度條與狀態列協同運作

範例程式建立主視窗,於 WM_CREATE 時建立進度條與狀態列,並啟動計時器每 100ms 遞增進度條,完成時於狀態列顯示「Finished!」並彈出訊息框。

關鍵程式碼片段

; 建立進度條
invoke CreateWindowEx, NULL, ADDR ProgressClass, NULL,
    WS_CHILD+WS_VISIBLE, 100, 200, 300, 20, hWnd, IDC_PROGRESS, hInstance, NULL
mov hwndProgress, eax

; 設定範圍 0-1000,步進 10
mov eax, 1000
mov CurrentStep, eax
shl eax, 16
invoke SendMessage, hwndProgress, PBM_SETRANGE, 0, eax
invoke SendMessage, hwndProgress, PBM_SETSTEP, 10, 0

; 建立狀態列
invoke CreateStatusWindow, WS_CHILD+WS_VISIBLE, NULL, hWnd, IDC_STATUS
mov hwndStatus, eax

; 建立計時器
invoke SetTimer, hWnd, IDC_TIMER, 100, NULL

計時器事件處理

.elseif uMsg==WM_TIMER
    invoke SendMessage, hwndProgress, PBM_STEPIT, 0, 0
    sub CurrentStep, 10
    .if CurrentStep==0
        invoke KillTimer, hWnd, TimerID
        mov TimerID, 0
        invoke SendMessage, hwndStatus, SB_SETTEXT, 0, addr Message
        invoke MessageBox, hWnd, addr Message, addr AppName, MB_OK+MB_ICONINFORMATION
        invoke SendMessage, hwndStatus, SB_SETTEXT, 0, 0
        invoke SendMessage, hwndProgress, PBM_SETPOS, 0, 0
    .endif

範例特意將 InitCommonControls 置於 ExitProcess 之後,證明該函式僅作 PE 匯入表註冊用途,控件仍能正常運作。

總結

掌握通用控件的初始化、類別名稱、建立方式與 WM_NOTIFY 通訊機制,是開發現代化 Windows 介面應用程式的基石。搭配 MASM 組合語言的精確控制,可打造高效能、小體積的視窗程式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved