⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 012.txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
第十二课 内存管理和文件输入/输出


--------------------------------------------------------------------------------
本课中我们将学习基本的内存管理和文件输入/输出操作方面的知识。另外我们还将用上课学的通用对话框作为我们的显示“设备”。 
理论: 

从用户的角度来看,WIN32的内存管理是非常简单和明了的。每一个应用程序都有自己独立的4G地址空间,这种内存模式叫做“平坦”型地址模式,所有的段寄存器或描述符都指向同样的起始地址,所有的地址偏移都是32位的长度,这样一个应用程序无须变换选择符就可以存取自己的多达4G的地址空间。这种内存管理模式是非常简洁而便于管理的,而且我们再不用和那些令人讨厌的“near”和“far”指针打交道了。
在W16下有两种主要类型的API:全局和局部。“全局”的API 分配在其他的段中,这样从内存角度来看他们是一些“far”(远)函数或者叫远过程调用,“局部”API只要和进程的堆打交道,所以把它们叫做“near”(近)函数或者近过程调用。而在WIN32中,这两种内存模式是相同的,无论您调用GlobalAlloc还是LocalAlloc,结果都是一样。
至于分配和使用内存的过程都是一样的: 

调用GlobalAlloc函数分配一块内存,该函数会返回分配的内存句柄。 
调用GlobalLock函数锁定内存块,该函数接受一个内存句柄作为参数,然后返回一个指向被锁定的内存块的指针。 
您可以用该指针来读写内存。 
调用GlobalUnlock函数来解锁先前被锁定的内存,该函数使得指向内存块的指针无效。 
调用GlobalFree函数来释放内存块。您必须传给该函数一个内存句柄。 
在WIN32中您也可以用“Local”替代内存分配API函数带有“Global”字样的函数中的“Global”,也即用LocalAlloc、LocalLock等。
在调用函数GlobalAlloc时使用GMEM_FIXED标志位可以更进一步简化操作。使用了该标志后,Global/LocalAlloc返回的是指向已分配内存的指针而不是句柄,这样也就不用调用Global/LocalLock来锁定内存了,释放内存时只要直接调用Global/LocalFree就可以了。不过在本课中我们只使用传统的方法,因为其它地方有许多的源代码是用这种方法写的。

WIN32的文件输入/输出API和DOS下的从外表上看几乎一样(译者注:也许不管内部实现多么不同,可以想象所有的文件系统暴露给应用程序编写者的接口的功能应该基本相同),不同的只是把DOS下的中断方式处理文件输入/输出变成了对API函数的调用。以下是基本的步骤: 
  

调用CreateFile函数生成一个文件,该函数可以应用在多方面,除了磁盘文件外,我们还可以用来打开通讯端口、管道、驱动程序或控制台。如果成功的话,会返回指向文件或设备的句柄。然后可以使用该句柄去完成对文件或设备操作。
调用SetFilePointer来把文件指针移到想读写的地方。. 
然后调用ReadFile 或 WriteFile来完成实际的读写。这些函数会自己处理文件和内存之间的数据传送,这样免得您自己去做分配内存等繁杂的琐事。 
调用CloseHandle来关闭文件。该函数接受一个先前打开的文件句柄。 
内容:

下面的代码段演示了:打开一个“打开文件”对话框,用户可以选择打开一个文本文件,然后在一个编辑控件中打开该文本文件的内容,另外用户还可以编辑该文本文件的内容并选择保存。

.386 
.model flat,stdcall 
option casemap:none 
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD 
include \masm32\include\windows.inc 
include \masm32\include\user32.inc 
include \masm32\include\kernel32.inc 
include \masm32\include\comdlg32.inc 
includelib \masm32\lib\user32.lib 
includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\comdlg32.lib 

.const 
IDM_OPEN equ 1 
IDM_SAVE equ 2 
IDM_EXIT equ 3 
MAXSIZE equ 260 
MEMSIZE equ 65535 

EditID equ 1                            ; ID of the edit control 

.data 
ClassName db "Win32ASMEditClass",0 
AppName  db "Win32 ASM Edit",0 
EditClass db "edit",0 
MenuName db "FirstMenu",0 
ofn   OPENFILENAME <> 
FilterString db "All Files",0,"*.*",0 
             db "Text Files",0,"*.txt",0,0 
buffer db MAXSIZE dup(0) 

.data? 
hInstance HINSTANCE ? 
CommandLine LPSTR ? 
hwndEdit HWND ?                               ; Handle to the edit control 
hFile HANDLE ?                                   ; File handle 
hMemory HANDLE ?                            ;handle to the allocated memory block 
pMemory DWORD ?                            ;pointer to the allocated memory block 
SizeReadWrite DWORD ?                   ; number of bytes actually read or write 

.code 
start: 
    invoke GetModuleHandle, NULL 
    mov    hInstance,eax 
    invoke GetCommandLine
    mov CommandLine,eax 
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT 
    invoke ExitProcess,eax 

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD 
    LOCAL wc:WNDCLASSEX 
    LOCAL msg:MSG 
    LOCAL hwnd:HWND 
    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,OFFSET MenuName 
    mov   wc.lpszClassName,OFFSET ClassName 
    invoke LoadIcon,NULL,IDI_APPLICATION 
    mov   wc.hIcon,eax 
    mov   wc.hIconSm,eax 
    invoke LoadCursor,NULL,IDC_ARROW 
    mov   wc.hCursor,eax 
    invoke RegisterClassEx, addr wc 
    invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ 
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ 
           CW_USEDEFAULT,300,200,NULL,NULL,\ 
           hInst,NULL 
    mov   hwnd,eax 
    invoke ShowWindow, hwnd,SW_SHOWNORMAL 
    invoke UpdateWindow, hwnd 
    .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 
    .IF uMsg==WM_CREATE 
        invoke CreateWindowEx,NULL,ADDR EditClass,NULL,\ 
                   WS_VISIBLE or WS_CHILD or ES_LEFT or ES_MULTILINE or\ 
                   ES_AUTOHSCROLL or ES_AUTOVSCROLL,0,\ 
                   0,0,0,hWnd,EditID,\ 
                   hInstance,NULL 
        mov hwndEdit,eax 
        invoke SetFocus,hwndEdit 
;============================================== 
;        Initialize the members of OPENFILENAME structure 
;============================================== 
        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 
    .ELSEIF uMsg==WM_DESTROY 
        invoke PostQuitMessage,NULL 
    .ELSEIF uMsg==WM_COMMAND 
        mov eax,wParam 
        .if lParam==0 
            .if ax==IDM_OPEN 
                mov  ofn.Flags, OFN_FILEMUSTEXIST or \ 
                                OFN_PATHMUSTEXIST or OFN_LONGNAMES or\ 
                                OFN_EXPLORER or OFN_HIDEREADONLY 
                invoke GetOpenFileName, ADDR ofn 
                .if eax==TRUE 
                    invoke CreateFile,ADDR buffer,\ 
                                GENERIC_READ or GENERIC_WRITE ,\ 
                                FILE_SHARE_READ or FILE_SHARE_WRITE,\ 
                                NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,\ 
                                NULL 
                    mov hFile,eax 
                    invoke GlobalAlloc,GMEM_MOVEABLE or 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 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -