吉林大学远程教育课件--WindowsAPI编.ppt_第1页
吉林大学远程教育课件--WindowsAPI编.ppt_第2页
吉林大学远程教育课件--WindowsAPI编.ppt_第3页
吉林大学远程教育课件--WindowsAPI编.ppt_第4页
吉林大学远程教育课件--WindowsAPI编.ppt_第5页
已阅读5页,还剩544页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,第三十讲),/函数:WndProc /作用:主窗口消息循环 LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) static BOOL bNeedSave = FALSE; /是否保存文件的标志 static char szFileName_MAX_PATH;/文件名 static char szTitleName_MAX_FNAME + _MAX_EXT; static HINSTANCE hInst;/应用程序句柄 static HWND hwndEdit;/编辑框句柄 static int iOffset; static UINT iMsgFindReplace; LPFINDREPLACE pfr;,switch (iMsg) case WM_CREATE: /创建窗口 hInst = (LPCREATESTRUCT) lParam) - hInstance ; /创建编辑框 hwndEdit = CreateWindow (“edit“, NULL, WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |WS_BORDER | ES_LEFT | ES_MULTILINE |ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0, 0, 0, 0, hwnd, (HMENU) EDITID, hInst, NULL) ;,SendMessage (hwndEdit, EM_LIMITTEXT, 32000, 0L); PopFileInitialize (hwnd); /初始化ofn /注册消息FINDMSGSTRING iMsgFindReplace = RegisterWindowMessage (FINDMSGSTRING) ; lstrcpy (szFileName, (PSTR) (LPCREATESTRUCT) lParam)-lpCreateParams) ; if (strlen (szFileName) 0) GetFileTitle (szFileName, szTitleName, sizeof (szTitleName); /获取文件名 if (!PopFileRead (hwndEdit, szFileName)/读文件 OkMessage (hwnd, “文件 %s 不能读取!“, szTitleName); DoCaption (hwnd, szTitleName); return 0; case WM_SETFOCUS: SetFocus (hwndEdit); /使编辑框获得焦点 return 0;,case WM_SIZE: MoveWindow (hwndEdit, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE); return 0; case WM_COMMAND:/ 菜单命令 if (lParam ,break; switch (LOWORD (wParam) / 来自文件菜单的消息 case IDM_NEW:/新建 if (bNeedSave ,/弹出Open对话框 if (PopFileOpenDlg (hwnd, szFileName, szTitleName) /读文件 if (!PopFileRead (hwndEdit, szFileName) OkMessage (hwnd, “不能读取文件%s!“,szTitleName); szFileName0 = 0; szTitleName0 = 0; DoCaption (hwnd, szTitleName); bNeedSave = FALSE; return 0; case IDM_SAVE:/保存 if (szFileName0) ,/写文件 if (PopFileWrite (hwndEdit, szFileName) bNeedSave = FALSE; return 1; else OkMessage (hwnd, “不能写文件 %s“,szTitleName) ; return 0; ,case IDM_SAVEAS:/另存为 /弹出Save AS对话框 if (PopFileSaveDlg (hwnd, szFileName, szTitleName) DoCaption (hwnd, szTitleName) ; if (PopFileWrite (hwndEdit, szFileName) bNeedSave = FALSE; return 1; else OkMessage (hwnd, “不能写文件%s“,szTitleName) ; return 0; case IDM_EXIT:/结束 SendMessage (hwnd, WM_CLOSE, 0, 0); return 0;,case IDM_UNDO :/撤消 SendMessage (hwndEdit, WM_UNDO, 0, 0); return 0; case IDM_CUT: /剪切 SendMessage (hwndEdit, WM_CUT, 0, 0); return 0; case IDM_COPY:/复制 SendMessage (hwndEdit, WM_COPY, 0, 0); return 0; case IDM_PASTE:/粘贴 SendMessage (hwndEdit, WM_PASTE, 0, 0); return 0; case IDM_CLEAR:/清空 SendMessage (hwndEdit, WM_CLEAR, 0, 0); return 0; case IDM_SELALL:/全选 SendMessage (hwndEdit, EM_SETSEL, 0, -1); return 0;,case IDM_FIND:/查找 SendMessage (hwndEdit, EM_GETSEL, NULL,(LPARAM) ,break; case WM_CLOSE: if (!bNeedSave | IDCANCEL != AskAboutSave (hwnd, szTitleName) DestroyWindow (hwnd); return 0; case WM_QUERYENDSESSION : if (!bNeedSave | IDCANCEL != AskAboutSave (hwnd, szTitleName) return 1; return 0; case WM_DESTROY: PostQuitMessage (0); return 0; default: /处理“Find-Replace“ 消息 if (iMsg = iMsgFindReplace) ,pfr = (LPFINDREPLACE) lParam ; if (pfr-Flags ,break ; return DefWindowProc (hwnd, iMsg, wParam, lParam) ; /函数:PopFileInitialize /作用:初始化全局变量ofn void PopFileInitialize (HWND hwnd) static char szFilter = “文本文件(*.TXT)0*.txt0“ “ASCII文件(*.ASC)0*.asc0“ “所有文件 (*.*)0*.*00“ ; ofn.lStructSize= sizeof (OPENFILENAME) ; ofn.hwndOwner= hwnd ; ofn.hInstance= NULL ; ofn.lpstrFilter= szFilter ;,ofn.lpstrCustomFilter = NULL ; ofn.nMaxCustFilter= 0 ; ofn.nFilterIndex= 0 ; ofn.lpstrFile= NULL ; ofn.nMaxFile= _MAX_PATH ; ofn.lpstrFileTitle= NULL ; ofn.nMaxFileTitle= _MAX_FNAME + _MAX_EXT ; ofn.lpstrInitialDir= NULL ; ofn.lpstrTitle= NULL ; ofn.Flags= 0 ; ofn.nFileOffset= 0 ; ofn.nFileExtension= 0 ;,ofn.lpstrDefExt= “txt“ ; ofn.lCustData= 0L ; ofn.lpfnHook= NULL ; ofn.lpTemplateName= NULL ; /函数:PopFileOpenDlg /作用:弹出Open对话框 BOOL PopFileOpenDlg (HWND hwnd, PSTR pstrFileName, PSTR pstrTitleName) ofn.hwndOwner= hwnd ; ofn.lpstrFile= pstrFileName ; ofn.lpstrFileTitle= pstrTitleName ; ofn.Flags= OFN_HIDEREADONLY; return GetOpenFileName (/弹出Open对话框 ,/函数:PopFileSaveDlg /作用:弹出Save As对话框 BOOL PopFileSaveDlg (HWND hwnd, PSTR pstrFileName, PSTR pstrTitleName) ofn.hwndOwner= hwnd ; ofn.lpstrFile= pstrFileName ; ofn.lpstrFileTitle= pstrTitleName ; ofn.Flags= OFN_OVERWRITEPROMPT ; return GetSaveFileName (,吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第三十一讲),fseek (file, 0, SEEK_END) ; iFileLength = ftell (file) ; fseek (file, iCurrentPos, SEEK_SET) ; return iFileLength ; /函数:PopFileRead /作用:读取文件 BOOL PopFileRead (HWND hwndEdit, PSTR pstrFileName) FILE *file; int iLength; PSTR pstrBuffer;,/打开文件 if (NULL = (file = fopen (pstrFileName, “rb“) return FALSE; iLength = PopFileLength (file);/获取文件长度 if (NULL = (pstrBuffer = (PSTR) malloc (iLength) fclose (file); /关闭文件 return FALSE; fread (pstrBuffer, sizeof(char), iLength, file); /读取文件 fclose (file); pstrBufferiLength = 0;,SetWindowText (hwndEdit, pstrBuffer); /设置编辑框中的文本内容 return TRUE; /函数:PopFileWrite /作用:写文件 BOOL PopFileWrite (HWND hwndEdit, PSTR pstrFileName) FILE *file ; int iLength ; PSTR pstrBuffer ; if (NULL = (file = fopen (pstrFileName, “wb“)/打开文件 return FALSE ; iLength = GetWindowTextLength (hwndEdit) ; /获取编辑框中的文本内容长度,if (NULL = (pstrBuffer = (PSTR) malloc (iLength + 1) fclose (file) ;/关闭文件 return FALSE ; /获取编辑框中的文本内容 GetWindowText (hwndEdit, pstrBuffer, iLength + 1) ; /写文件 if (iLength != (int) fwrite (pstrBuffer, 1, iLength, file) fclose (file); /关闭文件 free (pstrBuffer); return FALSE; ,fclose (file); free (pstrBuffer); return TRUE; /函数:PopFindFindDlg /作用:弹出Find对话框 HWND PopFindFindDlg (HWND hwnd) static FINDREPLACE fr; /初始化fr变量 fr.lStructSize= sizeof (FINDREPLACE); fr.hwndOwner= hwnd; fr.hInstance= NULL; fr.Flags=FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD; fr.lpstrFindWhat= szFindText; fr.lpstrReplaceWith = NULL;,fr.wFindWhatLen= sizeof (szFindText); fr.wReplaceWithLen= 0; fr.lCustData = 0; fr.lpfnHook= NULL; fr.lpTemplateName= NULL; return FindText (,fr.Flags=FR_HIDEUPDOWN | FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD; fr.lpstrFindWhat= szFindText; fr.lpstrReplaceWith = szReplText; fr.wFindWhatLen= sizeof (szFindText); fr.wReplaceWithLen= sizeof (szReplText); fr.lCustData= 0; fr.lpfnHook= NULL; fr.lpTemplateName= NULL; return ReplaceText ( /弹出Replace对话框 ,/函数:PopFindFindText /作用:查找字符串 BOOL PopFindFindText (HWND hwndEdit, int *piSearchOffset, LPFINDREPLACE pfr) int iLength, iPos; PSTR pstrDoc, pstrPos; /获取编辑框中的文本内容长度 iLength = GetWindowTextLength (hwndEdit); if (NULL = (pstrDoc = (PSTR) malloc (iLength + 1) return FALSE; /获取编辑框中的文本内容 GetWindowText (hwndEdit, pstrDoc, iLength + 1); pstrPos = strstr (pstrDoc + *piSearchOffset, pfr-lpstrFindWhat); free (pstrDoc);,if (pstrPos = NULL) return FALSE; iPos = pstrPos - pstrDoc; *piSearchOffset = iPos + strlen (pfr-lpstrFindWhat); SendMessage (hwndEdit, EM_SETSEL, iPos, *piSearchOffset); SendMessage (hwndEdit, EM_SCROLLCARET, 0, 0); return TRUE; ,/函数:PopFindNextText /作用:查找下一处字符串 BOOL PopFindNextText (HWND hwndEdit, int *piSearchOffset) FINDREPLACE fr; fr.lpstrFindWhat = szFindText; return PopFindFindText (hwndEdit, piSearchOffset, ,SendMessage (hwndEdit, EM_REPLACESEL, 0, (LPARAM) pfr-lpstrReplaceWith); return TRUE; BOOL PopFindValidFind (void) return *szFindText != 0; 首先声明了一个OPENFILENAME结构体的全局静态变量ofn,这个变量用于记录打开一个文件时系统需要的各种信息。,OPENFILENAME结构体的具体定义如下:,在调用打开文件对话框打开一个文件之前,必须先对OFN变量的各个域进行初始化。 在处理消息WM_CREATE时,程序调用自定义的函数PopFilelnitialize对OFN进行初始化操作。,函数PopFileInitialize的完整定义如下:,然后,程序调用函数 RegisterWindowMessage对消息 FINDMSGSTRING进行注册。 Windows允许用户使用系统预定义的消息, 也允许用户使用自定义的消息,但是在使用 自定义的消息之前,必须对消息进行注册。函数RegisterWindowMessage的原型定义如下:,程序通过如下语句取得在命令行中指定的文件名:,其中,lParatn是消息处理函数的参数 lParam是指向CREATESTRUCT结构体 的指针,CREATESTRUCT结构体的成员 变量 lpCreateParams中记录在创建窗口时, 程序传递给CreateWindow函数的 lpParam参数的值 szCmdLine,而 szCmdLine又是 WinMain函数用于接收用户命令行的参数。 所以,上述语句的目的就是取得用户的命令行参数。lstrcpy用于把字符串复制到另一个字符串中,函数原型定义如下:,如果命令行中指定了打开的文件名, 即szFileName不为空,则程序调用如 下语句来加以处理:,吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第三十二讲),其中,函数GetFileTitle用于获取文件名, 函数原型定义如下所示。,在取得文件名后,程序调用函数PopFileRead把文件中的数据读人到编辑框中。函数PopFileRead的具体定义如下:,在PopFileRead函数中,首先定义了文件指 针file,然后通过函数fopen打开由 pstrFileName指定的文件,fopen函数的 原型定义如下:,然后,程序调用 PopFileLength采取得文件的长度,PopFileLength也是自定义的函数,其具体定义如下:,函数PopFileLength中首先通过ftell取得文件指针的当前位置,并把结果保存在iCurrentPos中,ftell函数的原型定义如下:,PopFileLength然后调用 fseek函数移动文件指针到文件末尾处, fseek函数的原型定义如下:,程序中指定 offset参数的值为 0,指定 origin参数的值为 SEEK_END,表示把文件指针移动到距离文件末尾为0的位置,即文件的末尾处。 在把文件指针移动到文件末尾后,再一次调用函数ftell取得当前的文件指针的位置,并把结果保存在iFileLength变量中。 在取得文件的长度后,还必须把文件指针复位,以便后续的文件操作。 函数fread实现读取文件中的数据,这个函数的原型定义如下;,函数SetWindowsText用于把读取到的数据 显示在编辑框中,函数原型定义如下:,OkMessage是自定义的一个通用函数,其主要作用是当程序顺利完成某一项操作后向用户通报操作成功的消息。 DoCaption也是自定义的一个通用函数,其主要作用是处理某个窗口的标题。 如果用户选择了文件菜单下的“打开”菜单项,则程序通过图形代码来进行相应的处理。,用户选择文件菜单下的“打开”菜单项的目的 就是希望打开一个新文件,但是在打开新文 件之前必须检查编辑框中的内容是否已经保 存,如果没有保存,则bNeedSave变量将被置 成TRUE,通过检查bNeedSave变量的值可以 决定是否需要对编辑框中的内容进行保存操作。函数AskAboutSave是自定义的函数,其作用是提示用户对没有保存的内容进行保存。函数AskAboutSave的具体定义如下:,在上述程序中,函数MessageBox用于弹出 一个消息框,函数原型定义如下:,如果用户认为需要保存文件,则必然会单击消息框中的Yes按钮,这时MessageBox函数的返回值为IDYES,程序于是接着调用SendMessage函数向应用程序发送一条WM_COMMAND消息,对这条消息的附加信息指定为IDM_SAVE。应用程序在接收到这条消息后,程序流程将转到对保存菜单项进行相应处理的代码处。,真正实现弹出 Open对话框的是 PopFileOpenDlg函数,函数的定义如下:,上述程序段中通过对 Windows API函数 GetOpenFileName的调用来实现弹出 Open对话框,GetOpenFileName函数的原型定义如下:,如果成功地打开某一个文件后,PopFileOpeDlg函数将返回TRUE,于是程序接着调用函数DoCaption改变窗口标题,同时把变量bNeedSave的值设置为FALSE。其他对话框的使用大致也遵循和Open对话框类似的过程。 例题的头文件Edith如下:,例题的资源文件如下,例题执行结果如图所示。,吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第三十三讲),第十章多文档界面,第一节MDI概念,第二节示例程序,吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第三十四讲),吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第三十五讲),吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第三十六讲),第十一章 动态链接库,第一节 动态链接库基础知识,吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第三十七讲),吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第三十八讲),吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第三十九讲),吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第四十讲),例1: #include #define MAX_STRINGS 256/最大字符串数 typedef struct HDC hdc; int xText; int yText; int xStart; int yStart; int xIncr; int yIncr; int xMax; int yMax; CBPARAM;,PSTR pszStringsMAX_STRINGS; int iTotal = 0;/当前字符串数目 BOOL CALLBACK GetStr (PSTR pString, CBPARAM *pcbp); /函数:DllMain /作用:DLL入口 int WINAPI DllMain ( HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved) return TRUE; ,/函数:EnterString /作用:输入字符串 int WINAPI EnterString (PSTR pStringIn) HANDLE hString; PSTR pString; int i, iLength, iCompare; if (iTotal = MAX_STRINGS - 1)/达到最大字符串数目 return FALSE; iLength = strlen (pStringIn);/获取字符串长度 if (iLength = 0)/空字符串 return FALSE; /创建映像文件 hString=CreateFileMapping(HANDLE)-1,NULL, PAGE_READWRITE, 0, 1 + iLength, NULL); if (hString = NULL) return FALSE;,pString = (PSTR) MapViewOfFile (hString, FILE_MAP_WRITE, 0, 0, 0); strcpy (pString, pStringIn); AnsiUpper (pString);/全部转换成大写 for (i = iTotal; i 0; i-) iCompare = strcmpi (pStringIn, pszStringsi - 1); /比较字符串 if (iCompare = 0)/字符出不等则调处循环 break; pszStringsi = pszStringsi - 1; /字符出相等则删除字符串 pszStringsi = pString; iTotal+; return TRUE; ,/函数:DeleteString /作用:输入字符串 int WINAPI DeleteString(PSTR pStringIn) int i, j, iCompare; if (0 = strlen (pStringIn)/忽略输入的空字符串 return FALSE; for (i = 0 ; i iTotal ; i+)/字符串排序 iCompare = lstrcmpi (pszStringsi, pStringIn); if (iCompare = 0) break; if (i = iTotal) return FALSE; UnmapViewOfFile (pszStringsi); for (j = i ; j iTotal ; j+) pszStringsj = pszStringsj + 1; pszStringsiTotal- = NULL; return TRUE; ,/函数:GetStrings /作用:输出所有的字符串 int WINAPI GetStrings(CBPARAM * pParam) BOOL bReturn; int i; for (i = 0; i iTotal; i+) bReturn = GetStr(pszStringsi, pParam); if (bReturn = FALSE) return i + 1; return iTotal; ,/函数:GetStrCallBack /作用:输出一个字符串 BOOL CALLBACK GetStr (PSTR pString, CBPARAM *pcbp) TextOut (pcbp-hdc, pcbp-xText, pcbp-yText,pString, strlen (pString); if (pcbp-yText += pcbp-yIncr) pcbp-yMax) pcbp-yText = pcbp-yStart; if (pcbp-xText += pcbp-xIncr) pcbp-xMax) return FALSE; return TRUE ; ,#include #include #include“exetest.h“ #define MAXLEN 32 #define MAX_STRINGS 256 /最大字符串数 #define WM_DATACHANGE WM_USER typedef struct HDC hdc; int xText; int yText; int xStart; int yStart; int xIncr; int yIncr; int xMax; int yMax; CBPARAM;,LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); /声明动态链接库中的函数原型 int WINAPI EnterString (PSTR pStringIn); int WINAPI DeleteString (PSTR pStringIn); int WINAPI GetStrings(CBPARAM * pParam); char szAppName = “exetest“; char szStringMAXLEN; /函数:WinMain /作用:程序入口 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow), HWND hwnd; MSG msg; WNDCLASSEX wndclass; wndclass.cbSize = sizeof (wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); RegisterClassEx (,hwnd = CreateWindow (szAppName, “DLL Demonstration Program“, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd); /消息循环 while (GetMessage ( ,/函数:DlgProc /作用:对话可小型处理 BOOL CALLBACK DlgProc (HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) switch (iMsg) case WM_INITDIALOG:/初始化窗口 SendDlgItemMessage (hDlg, IDD_STRING,EM_LIMITTEXT,MAXLEN - 1,0); return TRUE;,case WM_COMMAND:/响应用户在对话框中的操作 switch (wParam) case IDOK:/用户单击确认按钮 /获取字符串 GetDlgItemText (hDlg, IDD_STRING, szString, MAXLEN); EndDialog (hDlg, TRUE);/关闭对话框 return TRUE; case IDCANCEL:/用户单击关闭按钮 EndDialog (hDlg, FALSE);/关闭对话框 return TRUE; return FALSE ; ,/函数:EnumCallBack /作用:通知主窗口中的数据是否发生变化 BOOL CALLBACK EnumCallBack (HWND hwnd, LPARAM lParam) char szClassName16 ; GetClassName (hwnd, szClassName, sizeof (szClassName);/获取窗口类名 if (0 = strcmp (szClassName, szAppName) SendMessage (hwnd, WM_DATACHANGE, 0, 0) ; return TRUE ; /函数:WndProc /作用:处理主窗口消息 LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) ,static HINSTANCE hInst; static int cxChar, cyChar, cxClient, cyClient; CBPARAM cbparam; HDC hdc; PAINTSTRUCT ps; TEXTMETRIC tm; switch (iMsg) case WM_CREATE:/创建窗口消息 hInst = (LPCREATESTRUCT) lParam)-hInstance; hdc = GetDC (hwnd); GetTextMetrics (hdc, ,ReleaseDC (hwnd, hdc); return 0 ; case WM_COMMAND: switch (wParam) case IDM_ENTER :/单击输入菜单项 /生成添加对话框 if (DialogBox (hInst, “EnterDlg“, hwnd, ,case IDM_DELETE:/单击删除菜单项 /生成删除对话框 if (DialogBox (hInst, “DeleteDlg“, hwnd, ,case WM_SIZE:/改变窗口大小 cxClient = (int) LOWORD (lParam); cyClient = (int) HIWORD (lParam); return 0; case WM_DATACHANGE:/工作区中的数据发生变化 InvalidateRect (hwnd, NULL, TRUE); return 0; case WM_PAINT:/重绘窗口 hdc = BeginPaint (hwnd, ,/调用动态链接库定义中的函数GetStrings GetStrings ( ,吉林大学远程教育课件,Windows A P I编 程,主讲人 : 翟慧杰,学 时:48,(第四十一讲),第12章 Windows的内存管理,第一节 Windows内存管理概述 Windows是一个多任务的操作系统,由于同时可以运行多个任务,因此Windows必须小心地管理系统的存储空间,以便一个应用程序对内存的要求得到满足的同时不会影响其他任务的执行。 尽管微处理机向物理内存写或读都是使用物理地址,但是程序员在程序设计中却是使用逻辑地址来对物理内存进行操作。逻辑地址包括两部分: 段标识符 用于说明存取的内存段的值; 偏移值 相对于段地址的字节数。 微处理器能把由段地址和偏移地址组成的逻辑地址转换成物理地址。,在Windows系统平台中,进程是系统内存 管理的基础。通常,进程具有它自己私有 的虚拟地址空间、代码、数据和其他操作 系统资源。进程必须至少具有一个运行在 该进程之内的执行线程。 每个运行于Windows下的进程和其他进程可以得到私有的32位虚拟地址空间,最多可访问 4GB内存。在 Windows 95中底层 IGB的内存空间是处于完全保护状态,顶层2GB的内存空间处于较差的安全状态;而在Windows NT中,系统保持整个4GB的内存空间是完全保护的。 内存分配归为两个主要类型:堆分配和栈分配。当用堆分配时,使用指向内存块的指针;当用栈分配时,与实际内存进行交互操作。在堆上分配的空间则要求应用程序显式地删除堆分配;在栈上分配对象时,程序分配给对象的内存空间将会自动被删除。,堆和栈都是和某一个进程相关的内存块。 页是Windows对内存的分配单位,通过页 可以实现对内存的访问。 一、堆: 堆是保留由进程分配的一个内存区。 Windows在全局堆或局部堆中为应用程序 分配内存。全局堆对所有应用程序均可以 使用,而局部堆只局限于为一个应用程序所使用。 全局堆是Windows操作系统控制的内存空间,全局堆以Windows装入内存的地方开始,包括了剩余的可用内存。当Windows操作系统启动时,代码和数据内存块首先被分配。分配完代码和数据内存块后余下的内存称为自由内存区,它可以由应用程序使用。全局堆往往用来分配大的内存块(它也可以用于分配任意大小的内存块,只是在小内存块的分配中很少使用全局堆)。,全局堆内存块的分配一般应按照以下原则进行: 固定段从底往上分配; 可废弃段从顶住下分配; 可移动段和不可废弃的数据段在固定段与可废弃段之间进行分配; 最大的自由内存块往往位于可废弃段下面。 与栈变量不同的是,当定义堆变量时,它们不存在,而是使用指针访问堆变量,并使用C或C十内存分配函数、方法及操作码来动态分配内存。尽管最终可安全地使用Windows运行时库函数malloc和 free,但是在 C程序设计中,更为常见的是使用 new操作符分配内存和delete操作符解除分配。new和delete操作符包括自动对内存泄漏的检查。Windows中,堆的规模仅受系统中有效虚拟内存总容量所限制。 下面是典型的堆分配的实例:,二、栈 栈是保存函数参数和块局部变量的内存区,编译器为这些项自动进行内存分配,且只要有函数调用,就将建立栈。栈分配的两个特性是: 局部变量的自动分配,包括大型数组及数据结构; 当局部变量超出范围时,自动解除局部分配。 下面是典型的栈分配实例:,上面的程序中,语句CClass ObjectOfClass;将在栈中为对象ObjectOfClass。分配一个内存空间,当该函数的调用完成后,栈自动释放 ObjectOfClass所占据的内存空间。在应用程序执行时,只要对象定义一到达,立刻调用类的构造函数创建对象,在对象退出当前范围时,调用对象的析构函数。这样就能保证内存资源不会泄漏。 在栈上使用变量和分配对象的主要优点就是程序员不用担心由于栈变量的使用导致内存泄漏,其主要缺点是栈空间是有限的,处理大型的对象和数据结构时,栈可能被耗尽。,三、内存页管理 Windows API支持 32位寻址和页式内存。 Windows 95内存管理使用了内存分页和 32位线性寻址技术。整个32位地址空间 被分为四个主要段,每一个段被称为 Arena,每个Arena满足不同系统和进程 的需求。四个主要段如下所示: 第一个Arena是从04MB,该段用在MSDOSWndows3.x兼容层。 第二个Arena是从4MB2GB,每个Windows进程使用该区作为它的私有地址空间。 第三个Arena是从2G3GB,该地址空间由系统内所有进程共享,并包含内存映像文件及16位应用程序组件。 第四个 Arena从 3GB4GB,由 Windows 95保留使用。 这一切都是由windows 95的虚拟内存管理程序来实现,它使用如图所示的全部虚拟地址空间布局。,第三节 虚拟内存管理 进程所用的虚拟地址和物理内存地址并 不一对应,而是为每一个进程保持页映像, 页是一个数据结构,用于将虚拟地址转换 为物理地址。由于进程所拥有的4GB地址大 于一般个人PC内存总容量,Windows在硬盘上采用了分页文件技术来处理溢出。 Windows 3.l使用了交换文件技术将内存中的信息交换到硬盘上。此技术能够释放足够的RAM供应用程序使用,Windows中实现了相似的内存交换形式,用更合适的分页文件代替交换文件标记。这是通过使用处理分页任务的动态虚拟内存管理程序来实现。 分页技术为应用程序提供了比系统中实际RAM的物理容量大得多的内存空间。Windows利用硬盘空间模拟内存空间,也就是说,一个系统可以使用的全部内存容量等于RAM容量加上系统可以使用的分页文件空间总量。Windows使用了动态分页文件,当不需要时,可以缩小到OKB大小,假若需要时又可以长到硬盘上的全部自由空间。,在RAM和每个进程逻辑地址空间内,二者 内存的存储是按页组织的。页的大小与 系统硬件有关,对 Windows 95和 Windows NT 而言,在 Intel兼容机上,每页大小为 4KB。 为使内存管理更加灵活,Windows内核将内存 页面送入或送出磁盘上的分页文件,这些页 的物理地址映像到进程地址空间,且页映像连

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论