第 9 章 文件及剪贴板操作

30
第9第 第第第第第第第第

Upload: marva

Post on 27-Jan-2016

89 views

Category:

Documents


1 download

DESCRIPTION

第 9 章 文件及剪贴板操作. 32 位 操作系统. 最大文件长度可达 4GB. Windows 操作系统. 支持长达 56 字节 的文件名. 同一文件可被 不同进程 访问. 文件操作是 Windows 应用程序 经常要涉及的内容 , 利用 Windows 的 API 函数 , 能很好地实现文件操作的功能。. 常用的文件操作函数. CreateFile :创建或打开一个文件. HANDLE CreateFile ( LPCTSTR lpszName , // 文件名 DWORD dwDesiredAccess , // 文件访问形式标识, - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第 9 章  文件及剪贴板操作

第 9 章 文件及剪贴板操作

Page 2: 第 9 章  文件及剪贴板操作

文件操作是 Windows 应用程序经常要涉及的内容 , 利用 Windows 的 API 函数 , 能很好地实现文件操作的功能。

Windows 操作系统

32 位操作系统最大文件长度可达 4GB支持长达 56 字节的文件名同一文件可被不同进程访问

Page 3: 第 9 章  文件及剪贴板操作

HANDLE CreateFile(LPCTSTR lpszName , // 文件名DWORD dwDesiredAccess , // 文件访问形式标识,

读操作为 GENERIC_READ ,写操作为 GENERIC_WRITEDWORD dwshareMode , // 文件的共享模式标识LPSECURITY_ATTRIBUTES lpsecurityAttributes,DWORD dwCreationDisposition, // 文件创建操作标识,DWORD dwFlagsAndAttributes, // 文件属性标识HANDLE hTemplateFile // 指向文件属性模板的句柄)

CreateFile :创建或打开一个文件

文件共享模式

可写共享,其值为 FILE_SHARE_WRITE

可读共享,其值为 FILE_SHARE_READ

该文件不能共享,则其值为 0

指向安全属性数据结构的指针,常为 NULL

常用的文件操作函数

Page 4: 第 9 章  文件及剪贴板操作

ReadFile 函数:从文件指针的位置开始读取一个现存文件中的数据

BOOL ReadFile(HANDLE hFile, // 打开的文件句柄;LPVOID lpBuffer, // 指向接收读入数据缓冲区地址的指针;DWORD nNumberOfBytesToRead,// 将从文件中读入的数据字数;LPDWORD lpNumberOfBytesRead,// 指向实际读取字节数的指针;LPOVERLAPPED lpOverlapped // 指向一个 OVERLAPPED 数据结构的指针。)

NULL 表明从当前位置读取数据

Page 5: 第 9 章  文件及剪贴板操作

WriteFile 函数:从文件指针的位置开始向现存文件中的写入数据。

BOOL WriteFile

HANDLE hFile , // 打开的文件句柄:

LPVOID lpBuffer , // 指向写入数据的缓冲区地址的指针:

DWORD nNumberOfBytesToWrite , // 将向文件中写入的数据字数:

LPDWORD lpNumberOfBytesWitten , // 指向实际写入字节数的针:

LPOVERLAPPED lpOverlapped , // 指向一个 OVERLAPPED 数据结构的指针。

)NULL 表明从当前位置写入数据

Page 6: 第 9 章  文件及剪贴板操作

GetFileInformartiomByHandle 函数获取指定文件的信息,并将其保存在 BY_HANDLE_FILE_INFORMATION 数据结构中

BOOLGetFilelnformationByHandle(HANDLE hFile,LPBY_HANDEL_FILE_INFORMATION lpFilelnformation)

为指向 BY_HANDLE_FILE_INFORMATION 结构的指针

Page 7: 第 9 章  文件及剪贴板操作

SearchPath 函数根据给定搜索路径查找指定文件并返回指定文件的路径

DWORD SearchPath(LPCTSTR lpPath // 指定搜索路径;若为 NULL ,则采用默认路径;LPCTSTR lpFileName , // 搜索的文件名;LPCTSTR lPExtension , // 搜索文件的扩展名;DWORD nBufferLength , // 用来接收文件路径名的缓冲区长度;LPTSTR lpBuffer , // 指向接收文件路径名的缓冲区;LPTSTR * lPFilepart // 指向路径名中文件名部分地址的指针。

// 如果调用该函数未指定搜索路径,// 则采用默认系统路径进行搜索

)lpFileName 默认的搜索次序:(1) 当前目录;(2)Windows 操作目录;(3)Windows 系统所在目录;(4)PATH 环境变量包含的目录

Page 8: 第 9 章  文件及剪贴板操作

SetFilePionter 函数:设置文件指针的位置

DWORD SetFilePoiner(HANDLE hFile , // 文件句柄LONG lpistanceToMove , // 指针移动的字节数LPLONG lpDistanceToMoveHigh, // 指向指针移动距离的高位指针DWORD dwMoveMethod // 指针移动参考位置标识)

Page 9: 第 9 章  文件及剪贴板操作

文件操作应用举例【例 9-1 】本例创建一个具有打开文件功能的对话框,并可进行文件的编辑与保存。

Page 10: 第 9 章  文件及剪贴板操作

LRESULT APIENTRY MainWndProc( ...... )1. {static HWND hWndEdit; 2. switch(message)3. {case WM_CREATE:4. hWndEdit=CreateWindow("EDIT",NULL,WS_CHILD|WS_VISIBLE|

   WS_HSCROLL|ES_LEFT|ES_MULTILINE|ES_AUTOHSCROLL,    0,0,0,0,hWnd,(HMENU)ID_EDITCHILD,    (HINSTANCE)GetWindowLong(hWnd,GWL_HINSTANCE),NULL);5. break;6. case WM_SIZE: 7.     MoveWindow(hWndEdit,0,0,LOWORD(lParam),HIWORD(lParam),TRUE);   break;8. case WM_COMMAND:9. switch (LOWORD(wParam))10. {case IDM_FILEOPEN: OpenTextFile(hWnd,hWndEdit); break;11. case IDM_FILESAVE: SaveTextFile(hWnd,hWndEdit); break;12. case IDM_EXIT: SendMessage(hWnd,WM_DESTROY,0L,0L); break;13. case IDM_ABOUT:DialogBox(hInst,"AboutBox",hWnd,(DLGPROC)About);break ;14. default:return(DefWindowProc(hWnd,message,wParam,lParam));15. }16. break;17. case WM_DESTROY: PostQuitMessage(0); break;18. default: return(DefWindowProc(hWnd,message,wParam,lParam)); } return(0); }

Page 11: 第 9 章  文件及剪贴板操作

//* 调用公共对话框函数,显示【打开】对话框 , 检取用户选择的文本文件 ,然后打开该文本文件到编辑控件中。void OpenTextFile(HWND hWnd,HWND hWndEdit){OPENFILENAME OpenFileName; char szDirName[MAX_PATH]=""; char szFile[MAX_PATH]="\0"; char szFileTitle [MAX_PATH]="\0"; // OPENFILENAME 结构的过滤器规格说明。 char szFilter[]={“文本文件 (*.txt)\0*.txt\0C源程序文件 (*.c)\0*.c\0 所有文件 \0*.*\0"}; OpenFileName.lStructSize=sizeof(OPENFILENAME); ......  OpenFileName.lpstrDefExt="*.txt"; OpenFileName.lCustData=0;OpenFileName.Flags= OFN_PATHMUSTEXIST|

  OFN_FILEMUSTEXIST|  OFN_HIDEREADONLY;

填写OpenFileName

对象属性

Page 12: 第 9 章  文件及剪贴板操作

1. if(GetOpenFileName(&OpenFileName))2. {HANDLE hFile; DWORD dwFileSize,dwBytesRead; char * lpBufPtr; 3. hFile=CreateFile( ...... );   // 打开指定的文件4. if(hFile!=INVALID_HANDLE_VALUE)5. {dwFileSize=GetFileSize(hFile,NULL); // 检取文件字节大小6. if(dwFileSize!=0xFFFFFFFF)7. {lpBufPtr=(char *)malloc(dwFileSize); // 分配用来读入文件的缓冲区8. if(lpBufPtr!=NULL)9. {ReadFile(hFile,(LPVOID)lpBufPtr,dwFileSize,&dwBytesRead,NULL);10. if(dwBytesRead!=0) {//把文件内容装入多行编辑控件中 11. SendMessage(hWndEdit,WM_SETTEXT,0,(LPARAM)lpBufPtr);12. SetWindowText(hWnd,OpenFileName.lpstrFile);}13. else14. MessageBox(hWnd,“读入字节数为零” ,NULL,MB_OK|MB_ICONEXCLAMATION);15. free(lpBufPtr);16. }17. else18. MessageBox(NULL," 内存分配失败! ",NULL,MB_OK|MB_ICONEXCLAMATION); 19. }20. else21. MessageBox(NULL," 检取文件大小失败 ",NULL,MB_OK|MB_ICONEXCLAMATION);22. CloseHandle(hFile) ;23. }24. else MessageBox(hWnd, " 打开文件失败 ",NULL,MB_OK|MB_ICONEXCLAMATION);25. }}

把文件内容读入缓冲区

Page 13: 第 9 章  文件及剪贴板操作

//* 调用公共对话框函数,显示【另存为】对话框 ,//* 用户选择文本名 ,然后把编辑控件中的内容保存到该文件中void SaveTextFile(HWND hWnd, HWND hWndEdit ) { OPENFILENAME OpenFileName;

char szDirName[MAX_PATH]="";char szFile[MAX_PATH]="\0";char szFileTitle[MAX_PATH]="\0";char szFilter[]={"All Files\0*.*\0"};OpenFileName.lStructSize=sizeof(OPENFILENAME);OpenFileName.hWndOwner=hWnd; ......OpenFileName.lCustData=0;OpenFileName.Flags=OFN_OVERWRITEPROMPT;

Page 14: 第 9 章  文件及剪贴板操作

1. if (GetSaveFileName (&OpenFileName))2. {HANDLE hFile; DWORD dwFileSize,dwBytesWrite; char *lpBufPtr;3.   hFile=CreateFile( ...... );4. if(hFile!=INVALID_HANDLE_VALUE)5. { // 检取编辑控件内容的字节大小。6. dwFileSize=SendMessage(hWndEdit,WM_GETTEXTLENGTH,0,0);7. if(dwFileSize!=0)8. { lpBufPtr=(char *)malloc(dwFileSize); // 分配文件缓冲区。 9. if(dwFileSize!=0)10.    {// 把编辑控件中的内容装到文件缓冲区。 11.    SendMessage(hWndEdit,WM_GETTEXT,dwFileSize,(LPARAM)lpBufPtr);12.   //把文件缓冲区中的数据存写到文件中。 13.    WriteFile(hFile,(LPVOID)lpBufPtr,dwFileSize,&dwBytesWrite,NULL); 14. SetWindowText(hWnd,OpenFileName.lpstrFile);15. free(lpBufPtr); 16.   }17. else 18. MessageBox(NULL," 内存分配失败! ",NULL,MB_OK|MB_ICONEXCLAMATION); 19. }20. else 21. MessageBox(NULL," 编辑控件中内容为空 ",NULL,MB_OK|MB_ICONEXCLAMATION);22. CloseHandle(hFile);23. }24. else 25. MessageBox(hWnd," 创建文件失败! ",NULL,MB_OK|MB_ICONEXCLAMATION);26. }}

创建文件,如果已有同名文件,则覆盖

Page 15: 第 9 章  文件及剪贴板操作

BOOL APIENTRY About( HWND hDlg,UINT message,WPARAM wParam,LPARAM lparam)

{ switch (message) { case WM_INITDIALOG: return (TRUE ); case WM_COMMAND: if(LOWORD(wParam)==IDOK||LOWORD(wParam)==IDCANCEL) {

EndDialog(hDlg,TRUE); return (TRUE);

} break; }return(FALSE);}

Page 16: 第 9 章  文件及剪贴板操作

剪贴板 : 通过剪贴板的操作,可对某一部分内容进行不同位置的复制、移动。

使用剪贴板首先应考虑的问题是其支持的数据格式。

在使用剪贴板之前,应用程序需将准备操作剪贴板的数据初始化为系统预定义的数据格式。

剪贴板

Page 17: 第 9 章  文件及剪贴板操作

应用程序向剪贴板发送文本

应用程序向剪贴板发送文本的操作过程可分为如下 5 个步骤:

1. 拷贝文本到全局内存

调用 GlobalAlloc 函数为文本分配全局存储空间HGLOBAL GlobalAlloc( UINT uFlags , // 函数分配内存形式标识 DWORD dwBytes) // 分配字节数

然后调用 GlobalLock 函数锁定分配的内存块 LPVOID GlobalLock ( HGLOBAL hMem ) //hMem 为内存块地址

把数据拷贝到内存以后,应及时调用 GlobalUnLock 解锁内存句柄BOOL GlobalUnLock ( HGLOBAL hMem ) //hMem 为内存句柄

Page 18: 第 9 章  文件及剪贴板操作

2. 打开剪贴板该步骤由应用程序调用 OpenClipboard 函数完成 BOOL OpenClipboard ( HWND hwnd )

//hwnd 为打开剪贴板的窗口句柄

3 .清除剪贴板中的所有句柄该步骤由应用程序调用函数 EmptyClipboard 完成BOOL EmptyClipboard ( VOID )

4. 向剪贴板传送文本全局内存句柄该步骤由应用程序调用函数 SetClipboardData 完成,HANDLE SetClipboardData( UINT uFormat , // 数据格式标识 HANDLE hMem) // 数据句柄应用程序一旦将文本内存句柄传递给剪贴板,则该句柄属于剪贴板,应用程序不能再对其进行操作。

Page 19: 第 9 章  文件及剪贴板操作

5. 关闭剪贴板该步骤由应用程序调用函数 CloseClipboard完成: BOOL CloseClipboard ( VOID )

下面的程序段是应用程序向剪贴板发送文本的一般过程:1. HANDLE hText ; LPTSTR lpString , lpText ;2. …3. case IDM_COPY; // 分配全局内存4. if (!( hText=GloalbAlloc ( GWND , Sizeof ( lpSring )))5. { MessageBox ( hwnd,`“ 全局内存分配失败!”,“ 提示”, MB_OK) ;break;}6. lpText=GlobalLock(hText); //锁定文本内存句柄并返回文本指针7. lstrcpy ( lpText , lpString ) ; //拷贝文本8. GlobalUnlock ( hText ); //解锁文本内存句柄9. If (! OpenClipboard ( hwnd ))10. { MessageBox(hwnd,″剪贴板打开失败!″ ,″ 提示″ ,MB_OK);break ; }11. EmptyClipboard( ); //清除剪贴板12. SetCilpboardData ( CF_TEXT,hText ) ; // 设置剪贴板文本13. CloseClipboard (); //关闭剪贴板14. hText=NULL //以避免应用程序再通过该句柄执行其他操作15. break ;

Page 20: 第 9 章  文件及剪贴板操作

获取剪贴板文本应用程序从剪贴板上获取文本的操作过程可分为如下 4 个步骤:1 .打开剪贴板 : 调用函数 OpenClipboard 打开剪贴板2 .检查剪贴板数据格式 :由函数 IsClipboardFormatAvailable完成 BOOL IsClipboardFormatAvailable ( UINT uformat )

4 .关闭剪贴板:调用函数 CloseClipboard关闭剪贴板。

获取的内存句柄属于剪贴板,不属于应用程序,因此应用程序读取剪贴板中的数据后,只能调用函数 GlobalUnlock解锁该内存句柄而无法将其释放。

3 .获取剪贴板文本 :由函数 GetClipboardData完成 HANDLE GetClipboardData ( UINT uformat)

uformat 为数据格式标识获取剪贴板文本内

存句柄后即可调用GlobalLock 返回指向文本的指针

Page 21: 第 9 章  文件及剪贴板操作

1. 下面的程序段是应用程序获取剪贴板文本的一般形式:2. HANDLE hText ;3. LPTSTR lpString , lpText ;4. …5. case IDM_PASTE; 6. if(!IsClipboardFormstAvailable(CF_TEXT)) // 检查剪贴板的数据格式7. {MessageBox(hwnd,“剪贴板上无文本数据”,“提示”, MB_OK); Break ; }8. if (! OpenClipboard ( hwnd )) // 打开剪贴板9. {MessageBox ( hwnd“剪贴板板开失败”,“提示”, MB_OK);Brdak;}10. // 获取剪贴板文本内存句柄11. if(!(hText=GetClipboardData(CF_TEXT)))12. {MessageBox(hwnd,“无法读取剪贴板数据” ,“提示” ,MB_OK);13. CloseClipboard(); Break; }14. lpTexe=GlobalLock(hText); //锁定文本内存名柄并返回文本指针15. //复制剪贴板文本内容16. lpString= ( LPTSTR ) malloc ( GlobalSize ( hText ));17. lpstrcpy ( lpString , lpText );18. GlobalUnlock ( hText ); //解锁文本内存句柄19. CloseClipboard (); //关闭剪贴板20. …21. break ;

Page 22: 第 9 章  文件及剪贴板操作

剪贴板应用举例

【例 9-2 】本例要求创建一个对话框,具有剪切、复制、粘贴、取消动作及退出等功能。

Page 23: 第 9 章  文件及剪贴板操作

# include <windows.h># include <commctrl.h># include <richedit.h># include <string.h># include <stdio.h># include <stdlib.h># include "9_2.h"

HINSTANCE hInst;HWND hWndMain;HWND hWndRichEdit;CHAR szRtfFileName[MAX_PATH];HCURSOR hCursorWait;HCURSOR hCursorNormal;HANDLE hRTFLib;

Page 24: 第 9 章  文件及剪贴板操作

LRESULT APIENTRY MainWndProc(……,……,……,……){static TCHAR szBuf[128]; static TCHAR szFontString[1024]; UINT uItem; switch (message) {case WM_CREATE: {// 创建多格式文字编辑控件。 hWndRichEdit=CreateWindowEx(

WS_EX_CLIENTEDGE, // 使多格式文字编辑控件有一个客户型边界

"RICHEDIT", // 多格式文字编辑控件的窗口类名称NULL, // 多格式文字编辑控件中的初始文字WS_CHILD|WS_VISIBLE|ES_MULTILINE|ES_SAVESEL|

WS_HSCROLL|WS_VSCROLL,//窗口风格0, 0, 0, 0, // 位置和尺寸待定hWnd, // 父窗口句柄(HMENU)ID_RICHEDIT, // 控件标识号hInst, // 实例句柄NULL);

lstrcpy(szRtfFileName, "粘贴示例 "); SetWindowText(hWnd, szRtfFileName); } break;

Page 25: 第 9 章  文件及剪贴板操作

case WM_SIZE:MoveWindow(hWndRichEdit,0,0,LOWORD(lParam),HIWORD(lParam),TRUE); break;case WM_INITMENUPOPUP: if((BOOL)HIWORD(lParam)) // 如果是系统菜单 , 则不作检查。 break;

// 检查是否可以进行撤销操作 , 并由此设置菜单项的状态。if(SendMessage(hWndRichEdit,EM_CANUNDO,0,0)) EnableMenuItem(GetMenu(hWndMain),IDM_EDITUNDO,MF_BYCOMMAND|MF_ENABLED);else EnableMenuItem(GetMenu(hWndMain), IDM_EDITUNDO,MF_BYCOMMAND|MF_GRAYED);//* 检查是否可以进行粘贴操作 , 并由此设置菜单项的状态。if(SendMessage(hWndRichEdit,EM_CANPASTE,0,0)) EnableMenuItem(GetMenu(hWndMain), IDM_EDITPASTE,MF_BYCOMMAND|MF_ENABLED); else EnableMenuItem(GetMenu(hWndMain), IDM_EDITPASTE,MF_BYCOMMAND|MF_GRAYED);break;

Page 26: 第 9 章  文件及剪贴板操作

case WM_COMMAND: uItem = LOWORD(wParam); switch (uItem) {case IDM_EDITUNDO:

SendMessage(hWndRichEdit, WM_UNDO, 0, 0);break; case IDM_EDITCUT:

SendMessage(hWndRichEdit, WM_CUT, 0, 0); break; case IDM_EDITCOPY:

SendMessage(hWndRichEdit, WM_COPY, 0, 0);break; case IDM_EDITPASTE:

SendMessage(hWndRichEdit, WM_PASTE, 0, 0);break; case IDM_EDITDELETE:

SendMessage(hWndRichEdit, WM_CLEAR, 0, 0);break; case IDM_EDITSELECTALL:

SendMessage(hWndRichEdit, EM_SETSEL,0,-1);break; case IDM_EXIT:

SendMessage(hWnd, WM_CLOSE, 0, 0L);return 0; default:

return(DefWindowProc(hWnd,message,wParam,lParam)); }break;if (hRTFLib); {FreeLibrary(hRTFLib); hRTFLib=NULL;} PostQuitMessage(0); break;default:return(DefWindowProc(hWnd,message,wParam,lParam));}return(0);}

Page 27: 第 9 章  文件及剪贴板操作

【例 9-3 】本例题将在用户区中创建两个编辑框子窗口,用户可以在第一个编辑框中输入文本,并将其中的某些文本选中,然后选择“复制第一个编辑框中的选中文本”菜单项,即可将选中文本复制到剪贴板中。选择“将文本粘贴到第二个编辑框”菜单项可将剪贴板中的文本粘贴到第二个编辑框中。

#include <windows.h>#include <string.h>#include"resource.h"#define IDE_1 102 // 第一个编辑框的标识#define IDE_2 103 // 第二个编辑框的标识long WINAPI WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam);HWND hEdit1,hEdit2; // 定义输入编辑框 ,输出编辑框HINSTANCE hInst; // 定义应用程序实例句柄

Page 28: 第 9 章  文件及剪贴板操作

long WINAPI WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam){DWORD begin,end; HGLOBAL hSel; LPTSTR pSel,pEdit,pGlobal; long length; unsigned i; switch(iMessage) {case WM_CREATE: //窗口初始化消息

hEdit1=CreateWindow("EDIT", // 创建 EDIT对象

NULL, //无标题WS_CHILD|WS_VISIBLE|ES_LEFT|WS_BORDER, //

样式230,20,300,30, hWnd,(HMENU)IDE_1, // 编辑框标识hInst, NULL);

hEdit2=CreateWindow("EDIT", // 创建 EDIT编辑框

NULL, //无标题WS_CHILD|WS_VISIBLE|ES_LEFT|WS_BORDER, //

样式230,70,300,30, hWnd,(HMENU)IDE_2, // 编辑框标识hInst,NULL);

break;

Page 29: 第 9 章  文件及剪贴板操作

1 case WM_COMMAND:2 switch(LOWORD(wParam))3 { case IDE_1: if(HIWORD(wParam)==EN_SETFOCUS) SetFocus(hEdit1); break;4 case IDE_2: if(HIWORD(wParam)==EN_SETFOCUS) SetFocus(hEdit2); break;5 case IDM_COPY:6 SendMessage(hEdit1,EM_GETSEL,(WPARAM)&begin,(LPARAM)&end);7 length=GetWindowTextLength(hEdit1);8 pEdit=(LPTSTR)malloc((length+1)*sizeof(char));9 GetWindowText(hEdit1,pEdit,length+1);10 pSel=(LPTSTR)malloc((end-begin+1)*sizeof(char));11 for(i=begin;i<end;i++)12 *(pSel+(i-begin))=*(pEdit+i);13 *(pSel+i-begin)='\0';14 if(begin!=end)15 { if(!(hSel=GlobalAlloc(GHND,sizeof(char)*(end-begin+1))))16 { MessageBox(hWnd," 全局内存分配失败 ","提示 ",MB_OK); break;}17 pGlobal=(LPTSTR)GlobalLock(hSel);18 lstrcpy(pGlobal,pSel);19 GlobalUnlock(hSel);20 if(!OpenClipboard(hWnd))21 { MessageBox(hWnd," 剪贴板打开失败 ","提示 ",MB_OK); break; }22 EmptyClipboard();23 SetClipboardData(CF_TEXT,hSel);24 CloseClipboard();25 hSel=NULL;26 free(pEdit);27 free(pSel);28 }29 return 1;

Page 30: 第 9 章  文件及剪贴板操作

1. case IDM_PASTE:2. if(!IsClipboardFormatAvailable(CF_TEXT))3. { MessageBox(hWnd," 剪贴板上无文本 ","提示 ",MB_OK); break; }4. if(!OpenClipboard(hWnd))5. { MessageBox(hWnd," 打开剪贴板失败 ","提示 ",MB_OK); break; }6. if(!(hSel=GetClipboardData(CF_TEXT)))7. { MessageBox(hWnd," 不能读取剪贴板上的数据 ","提示 ",MB_OK);8. CloseClipboard(); break; }9. pGlobal=(LPTSTR)GlobalLock(hSel);10. pSel=(LPTSTR)malloc(GlobalSize(hSel));11. lstrcpy(pSel,pGlobal);12. GlobalUnlock(hSel);13. CloseClipboard();14. SetWindowText(hEdit2,pSel);15. free(pSel);16. return 1;17. }18. break;19. case WM_DESTROY:20. PostQuitMessage(0); break;21. default: return(DefWindowProc(hWnd,iMessage,wParam,lParam));22. }23. return 0;24. }