Win32 平坦記憶體模型賦予每程式 4GB 獨立位址空間,消除 near/far 指標困擾。本文系統說明全域/區域記憶體 API、GMEM_FIXED 簡化用法、檔案 I/O 基礎流程,並以編輯器範例展開:通用對話框開啟/儲存檔案、編輯控件顯示/編輯、記憶體區塊讀寫協調。
GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, size) → 返回控制碼GlobalLock(hMem) → 返回指標,鎖定記憶體防止移動GlobalUnlock(hMem) → 解鎖,指標失效GlobalFree(hMem) → 釋放LocalAlloc/Lock/Unlock/Free 行為相同(Win32 統一實作)。
GlobalAlloc(GMEM_FIXED, size) 直接返回指標,無需 Lock/Unlock,釋放時直接 GlobalFree(ptr)。但傳統模式相容性較佳,範例採傳統寫法。
CreateFile:開啟/建立檔案、裝置、管道等,返回檔案控制碼SetFilePointer:移動檔案指標ReadFile / WriteFile:實際資料傳輸,自動處理記憶體緩衝CloseHandle:關閉控制碼| 參數 | 常用值 | 說明 |
|---|---|---|
| dwDesiredAccess | GENERIC_READ / GENERIC_WRITE / 兩者 OR | 存取權限 |
| dwShareMode | FILE_SHARE_READ / FILE_SHARE_WRITE / 0 | 共享模式,0=獨佔 |
| dwCreationDisposition | CREATE_NEW / CREATE_ALWAYS / OPEN_EXISTING / OPEN_ALWAYS / TRUNCATE_EXISTING | 檔案存在/不存在時行為 |
| dwFlagsAndAttributes | FILE_ATTRIBUTE_ARCHIVE / NORMAL / HIDDEN / READONLY / SYSTEM / COMPRESSED | 檔案屬性 |
主視窗客戶區填滿編輯控件(ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL),選單提供 Open/Save,使用 GetOpenFileName/GetSaveFileName 通用對話框。
.IF uMsg==WM_CREATE
invoke CreateWindowEx, NULL, ADDR EditClass, NULL,
WS_VISIBLE|WS_CHILD|ES_LEFT|ES_MULTILINE|ES_AUTOHSCROLL|ES_AUTOVSCROLL,
0,0,0,0, hWnd, EditID, hInstance, NULL
mov hwndEdit, eax
invoke SetFocus, hwndEdit
; OPENFILENAME 共用欄位初始化
mov ofn.lStructSize, SIZEOF ofn
push hWnd; pop ofn.hwndOwner
push hInstance; pop ofn.hInstance
mov ofn.lpstrFilter, OFFSET FilterString
mov ofn.lpstrFile, OFFSET buffer
mov ofn.nMaxFile, MAXSIZE
.ELSEIF uMsg==WM_SIZE
mov eax, lParam
mov edx, eax
shr edx, 16 ; 高字 = 高度
and eax, 0FFFFh ; 低字 = 寬度
invoke MoveWindow, hwndEdit, 0, 0, eax, edx, TRUE
.if ax==IDM_OPEN
mov ofn.Flags, OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_LONGNAMES|OFN_EXPLORER|OFN_HIDEREADONLY
invoke GetOpenFileName, ADDR ofn
.if eax==TRUE
invoke CreateFile, ADDR buffer, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL
mov hFile, eax
invoke GlobalAlloc, GMEM_MOVEABLE|GMEM_ZEROINIT, MEMSIZE
mov hMemory, eax
invoke GlobalLock, hMemory
mov pMemory, eax
invoke ReadFile, hFile, pMemory, MEMSIZE-1, ADDR SizeReadWrite, NULL
invoke SendMessage, hwndEdit, WM_SETTEXT, NULL, pMemory
invoke CloseHandle, hFile
invoke GlobalUnlock, pMemory
invoke GlobalFree, hMemory
.endif
invoke SetFocus, hwndEdit
.elseif ax==IDM_SAVE
mov ofn.Flags, OFN_LONGNAMES|OFN_EXPLORER|OFN_HIDEREADONLY
invoke GetSaveFileName, ADDR ofn
.if eax==TRUE
invoke CreateFile, ADDR buffer, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_ARCHIVE, NULL
mov hFile, eax
invoke GlobalAlloc, GMEM_MOVEABLE|GMEM_ZEROINIT, MEMSIZE
mov hMemory, eax
invoke GlobalLock, hMemory
mov pMemory, eax
invoke SendMessage, hwndEdit, WM_GETTEXT, MEMSIZE-1, pMemory
invoke WriteFile, hFile, pMemory, eax, ADDR SizeReadWrite, NULL
invoke CloseHandle, hFile
invoke GlobalUnlock, pMemory
invoke GlobalFree, hMemory
.endif
invoke SetFocus, hwndEdit
WM_CREATE 先建立,WM_SIZE 再用 MoveWindow 精確鋪滿客戶區。WM_CREATE 初始化共用欄位,命令處理只更新 Flags 與呼叫對話框。MEMSIZE=65535),大檔案需分段讀寫或改用記憶體對應檔案(下一課主題)。SetFocus 回編輯控件,否則鍵盤輸入失效。Win32 記憶體管理與檔案 I/O API 設計一致、邏輯清晰。掌握 GlobalAlloc/Lock/Unlock/Free 生命週期、CreateFile 豐富參數組合、通用對話框整合、編輯控件訊息操作(WM_SETTEXT/WM_GETTEXT),即可構建功能完整的檔案處理應用程式。