相关函数说明:
SendMessage 函数功能:该函数将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回。 函数原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam); 参数: hWnd:其窗口程序将接收消息的窗口的句柄。如果此参数为HWND_BROADCAST,则消息将被发送到系统中所有顶层窗口,包括无效或不可见的非自身拥有的窗口、被覆盖的窗口和弹出式窗口,但消息不被发送到子窗口。 Msg:指定被发送的消息。 wParam:指定附加的消息指定信息。 IParam:指定附加的消息指定信息。 返回值:返回值指定消息处理的结果,依赖于所发送的消息。 备注:需要用HWND_BROADCAST通信的应用程序应当使用函数RegisterWindowMessage来为应用程序间的通信取得一个唯一的消息。 如果指定的窗口是由调用线程创建的,则窗口程序立即作为子程序调用。如果指定的窗口是由不同线程创建的,则系统切换到该线程并调用恰当的窗口程序。线程间的消息只有在线程执行消息检索代码时才被处理。发送线程被阻塞直到接收线程处理完消息为止。
#include <windows.h> #include <string.h> #include "menutest.h" #define FILE_LIST DDL_DIRECTORY|DDL_READWRITE
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam); //窗口函数声明 BOOL ShowFileInfo(HWND hWnd,HDC hDC,HDROP hDropInfo);
BOOL CALLBACK DlgProcGetFileName(HWND,UINT,WPARAM,LPARAM); //获取文件名 BOOL FileToEditBox(HWND,LPSTR); //文件到编辑框 BOOL EditBoxToFile(HWND,LPCTSTR); //编辑框到文件 BOOL EditBoxToClip1(HWND); //编辑框到剪贴板(复制) BOOL EditBoxToClip2(HWND); //编辑框到剪贴板(剪切) BOOL ClipToEditBox(HWND); //剪贴板到编辑框 bool check(char* , char* ); //判断两个字符串是否相等
HWND hWnd; //窗口句柄 HINSTANCE hInst; //应用程序实例句柄
HWND hList; //文件列表框句柄 HANDLE hFile; //文件句柄 HWND hWndEdit; //编辑框句柄 HWND hStatic; //状态栏句柄
OPENFILENAME ofn;
char szFile[255]; char szFileTitle[255];
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { WNDCLASSEX wndclass; MSG msg; HACCEL hAccel; // 定义加速键句柄
// 为窗口类结构赋值 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(hInstance,"MYICON"); //设置程序的图标(不能缺少) wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = CreateSolidBrush(RGB(192,192,192)); wndclass.lpszMenuName = "Menu"; wndclass.lpszClassName = "TestWindowClass"; wndclass.hIconSm = LoadIcon(hInstance,"MYICON"); //设置程序的图标(不可缺少)
// 注册窗口类 if (!RegisterClassEx(&wndclass)) return 0;
// 用上面创建的类(即已经赋值的类)创建新窗口 hWnd = CreateWindowEx( //创建一个窗口并赋予窗口句柄hWnd 0, //扩展窗口风格,为默认 "TestWindowClass", //创建窗口所用的类(这是上面的类的名字) //不同的类以名字来区分!!!
"记事本仿真程序^O^", //窗口的名称,(在标题栏) WS_OVERLAPPEDWINDOW, //窗口风格为OVERLAPPED风格(和记事本一样的), CW_USEDEFAULT, //这四个参数定义了窗口的位置和大小,现为默认 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, //父窗口句柄,这里没有,所以设为NULL NULL, //菜单句柄,,,这里没有,,,为NULL hInstance, //创建窗口的应用程序的当前句柄 NULL); //创建参数,用于给程序传递数据,程序没用到,,所以为空
if (!hWnd) return FALSE; //如果创建窗口失败,返回FALSE
hInst=hInstance;
ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd);
SendMessage(hWnd,WM_COMMAND,IDM_NEW,0L);
//加载加速键 hAccel=LoadAccelerators(hInstance,MAKEINTRESOURCE(IDR_ACCELERATOR1)); //加载快捷键表,若你在程序中没有快捷键表,则不需要用这个函数。
while (GetMessage(&msg,NULL,0,0)) { //在消息循环中截获加速键消息 if(!TranslateAccelerator(hWnd,hAccel,&msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }
return 0; // 如果没有特殊要求,这里也可以是代表成功执行 }
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { HDC hDC; RECT ClientRect; LPCTSTR lpTemp=""; // 空字符串 char *p=NULL;
static bool flag=false; //若没有打开文件,flag=flase static bool flag2=false; //若没有新建文件,flag2=false static bool flag3=false; //用来判断文件名是否带了后缀,在IDM_SAVE 中将会用到 static bool flag4=false; //用来判断是否保存了文件
switch (message) { case WM_CREATE: GetClientRect(hwnd,&ClientRect); //获取客户区大小 hWndEdit=CreateWindow("EDIT", //创建编辑框 NULL, WS_CHILD|WS_VISIBLE|WS_VSCROLL|ES_MULTILINE|WS_BORDER,
ClientRect.left, ClientRect.top, ClientRect.right, ClientRect.bottom,
hwnd, (HMENU)ID_EDITCHILD, hInst, NULL); EnableWindow(hWndEdit,0); //使编辑框不能接受输入 DragAcceptFiles( hwnd,TRUE ); //API函数:允许hWnd所指的窗口实现文件拖放 // 如果没有这个函数或设置为FALSE // 窗口都不能实现文件的拖放 return 0;
case WM_SIZE: //当窗口大小改变的时候,编辑框与状态栏跟着改变 MoveWindow(hWndEdit,0,0,LOWORD(lParam),HIWORD(lParam),true); //编辑框 return 0;
case WM_COMMAND: switch(LOWORD(wParam)) { case IDM_OPEN: SendMessage(hWndEdit,EM_SETSEL,0,-1); //选中所有文本 SendMessage(hWndEdit,EM_REPLACESEL,wParam,(DWORD)lpTemp); //用空串代码 EnableWindow(hWndEdit,0); //使编辑框不能接受输入
ZeroMemory(&ofn,sizeof(OPENFILENAME)); ofn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_FILEMUSTEXIST |OFN_PATHMUSTEXIST ; ofn.lpstrFile=szFile; ofn.nMaxFile=sizeof(szFile); ofn.lpstrFileTitle=szFileTitle; ofn.lpstrInitialDir=NULL; ofn.nMaxFileTitle = NULL; ofn.lpstrFilter="文本文件\0*.txt"; ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner=hwnd; //父窗口句柄 //注:如果不指明父窗口句柄,当我们打开通用对话框 // 时将仍然可以对主窗口进行操作,这不是我们需要的 // 只有指明了父窗口句柄才能把焦点限定在通用对话框
if (GetOpenFileName(&ofn)==TRUE) { EnableWindow(hWndEdit,1); //使编辑框可以接受输入 FileToEditBox(hwnd,szFile); //文件到编辑框!!!!!!!!!!!! } EnableWindow(hWndEdit,1); //使编辑框可以接受输入
flag=true; //打开了一个文件,flag=true flag4=false; //打开了一个文件,还未保存,flag4=false return 0;
case IDM_NEW: //弹出文件名对话框 SendMessage(hWndEdit,EM_SETSEL,0,-1); //选中所有文本 SendMessage(hWndEdit,EM_REPLACESEL,wParam,(DWORD)lpTemp); //用空串代码 EnableWindow(hWndEdit,1); //允许编辑框输入 SetFocus(hWndEdit); //编辑框获得焦点 flag2=true; //新建了文件,flag2=true flag4=false; //新建了文件,还未保存,flag4=false return 0;
case IDM_CLOSE: SendMessage(hWndEdit,EM_SETSEL,0,-1); //选中所有文本 SendMessage(hWndEdit,EM_REPLACESEL,wParam,(DWORD)lpTemp); //用空串代码 EnableWindow(hWndEdit,0); //禁止编辑框输入 flag=false; flag2=false; return 0;
case IDM_SAVE: //将编辑框中所有内容输出到文件 if(flag==true || flag2==true) { if(flag4==false) { ofn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER |OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT; ofn.lpstrFile=szFile; ofn.nMaxFile=sizeof(szFile); ofn.lpstrFileTitle=szFileTitle; ofn.lpstrInitialDir=NULL; ofn.nMaxFileTitle = NULL; ofn.lpstrFilter="文本文件\0*.txt"; ofn.lStructSize = sizeof(OPENFILENAME); ofn.lpstrTitle ="另存为..."; ofn.hwndOwner=hwnd; //父窗口句柄
EnableWindow(hWndEdit,0); //使编辑框不能接受输入 GetSaveFileName(&ofn); EnableWindow(hWndEdit,1); //使编辑框可以接受输入
p=szFileTitle; while(*p!='\0') { if(*p=='.') //字符串里有"."号,说明文件名带了后缀 { flag3=true; //文件名带了后缀, flag3=true
if(check(p,".txt") || check(p,".TXT")) //如果后缀是".txt" 或".TXT" break; //OK,跳出循环
else //如果后缀不是".txt" 或".TXT" strcat(p,".txt"); //在其末尾加上".txt" } p++; } if(flag3==false) { strcat(p,".txt"); //文件名没有带后缀,我们给它加上后缀 } } EditBoxToFile(hwnd,szFileTitle); flag4=true; } return 0;
case IDM_SAVEAS: if(flag==true || flag2==true) { ofn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER |OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT; ofn.lpstrFile=szFile; ofn.nMaxFile=sizeof(szFile); ofn.lpstrFileTitle=szFileTitle; ofn.lpstrInitialDir=NULL; ofn.nMaxFileTitle = NULL; ofn.lpstrFilter="文本文件\0*.txt"; ofn.lStructSize = sizeof(OPENFILENAME); ofn.lpstrTitle ="另存为..."; ofn.hwndOwner=hwnd; //父窗口句柄
EnableWindow(hWndEdit,0); //使编辑框不能接受输入 GetSaveFileName(&ofn); EnableWindow(hWndEdit,1); //使编辑框可以接受输入
p=szFileTitle; while(*p!='\0') { if(*p=='.') //字符串里有"."号,说明文件名带了后缀 { flag=true; //设置flag=false; if(check(p,".txt") || check(p,".TXT")) //如果后缀是".txt" 或".TXT" break; //OK,返回 else //如果后缀不是".txt" 或".TXT" strcat(p,".txt"); //在其末尾加上".txt" } else //若字符串里没有"."号,说明文件名没有带后缀 flag=false; //设置flag=false; p++; } if(flag==false) //若flag=false,说明文件名没有带后缀 { strcat(szFileTitle,".txt"); //给文件名加上后缀".txt" flag=true; } if(flag==true) { EditBoxToFile(hwnd,szFileTitle); flag4=true; } } return 0;
case IDM_EXIT: SendMessage(hwnd,WM_DESTROY,0,0); return 0;
case IDM_COPY: EditBoxToClip1(hwnd); return 0;
case IDM_CUT: EditBoxToClip2(hwnd); return 0;
case IDM_PASTE: ClipToEditBox(hwnd); return 0;
case IDM_ABOUT: MessageBox(hwnd,TEXT("记事本仿真程序(V1.0)\n\n广西工学院计:黄伟林\nQQ: 362176730\n最后更新: 2005-1-19"),TEXT("记事本仿真程序(V1.0)"),MB_OK|MB_ICONINFORMATION); return 0; } return 0;
case WM_DROPFILES: //当有文件被拖入窗口并放下时激发此消息 HDROP hDropInfo; //HDROP句柄,用以存放拖入文件的信息 hDropInfo = ( HDROP )wParam; //初始化hDropInfo(不进行初始化运行会出错)
hDC = GetDC( hwnd ); ShowFileInfo( hwnd,hDC,hDropInfo ); DragFinish( hDropInfo ); ReleaseDC( hwnd,hDC );
flag=true; //打开了一个文件,flag=true flag4=false; //打开了一个文件,还未保存,flag4=false return 0;
case WM_KEYDOWN: switch(wParam) { case VK_ESCAPE: DestroyWindow(hList); //消毁文件列表框 return 0; } return 0;
case WM_CLOSE: // 窗口关闭前的消息(比如用户点了关闭按钮) DWORD dwFileSize; dwFileSize=SendMessage(hWndEdit,WM_GETTEXTLENGTH,0,0);
if((flag==true||flag2==true)&&flag4==false) //如果新建了文件或打开了文件 { //并且文件没有被保存过
if(dwFileSize!=0) //如果编辑框内容不为空 { int t; t=::MessageBox(NULL,"文件还未保存,是否要保存?","提示",MB_YESNOCANCEL|MB_ICONINFORMATION); if(t==IDYES) { SendMessage(hWnd,WM_COMMAND,IDM_SAVEAS,0L); //保存文件 DestroyWindow(hwnd); //毁灭窗口 return 0; } else if(t==IDCANCEL) { return 0; } } }
DestroyWindow(hwnd); return 0; // 此时Windows还根本没有对窗口做任何事,可以用MessageBox来测试
case WM_DESTROY: // 窗口关闭以后的消息,此时Windows已经毁坏了窗口 DragAcceptFiles( hwnd,FALSE ); PostQuitMessage(0); return 0; }
return DefWindowProc(hwnd, message, wParam, lParam); // 默认消息处理 }
BOOL FileToEditBox(HWND hwnd, LPSTR lpszFileName) { DWORD dwFileSize,dwByteRead; //文件大小,文件读入字节 char *lpBufPtr=NULL; //文件缓冲区
//打开文件 hFile=CreateFile(lpszFileName, //文件名 GENERIC_READ, //只进行读文件操作 FILE_SHARE_READ, //读方式:共享读 NULL, OPEN_EXISTING, //打开一个文件,如果文件不存在,函数失败 FILE_ATTRIBUTE_NORMAL, //常规文件 (HANDLE)NULL);
if(hFile!=INVALID_HANDLE_VALUE) //若打开文件成功 { dwFileSize=GetFileSize(hFile,NULL); //读取文件大小 if(dwFileSize!=0xFFFFFFFF) //若读取文件大小成功 { lpBufPtr=(char*)malloc(dwFileSize); //开辟文件缓冲区 if(lpBufPtr!=NULL) //若开辟文件缓冲区成功 { //读取文件 ReadFile(hFile, //文件句柄 (LPVOID)lpBufPtr, //文件缓冲区指针 dwFileSize, //文件大小 &dwByteRead, //记录读入了多少字节 NULL); //从文件当前位置读取
if(dwByteRead!=0) //若读取文件成功 { //将文件写入编辑框 SendMessage(hWndEdit,WM_SETTEXT,0,(LPARAM)lpBufPtr); } else { MessageBox(NULL,"读入字节数为0 ","",0); free(lpBufPtr); return 0; } } else { MessageBox(hwnd,"内存分配失败","",0); return 0; } } else { MessageBox(hwnd,"获取文件大小失败","",0); return 0; } } else { MessageBox(hwnd,"打开文件失败","",0); return 0; } CloseHandle(hFile); return 1; }
BOOL EditBoxToFile(HWND hwnd,LPCTSTR lpszFileName) { DWORD dwFileSize,dwByteWrite; //文件大小,已写入的字节数 char *lpBufPtr=NULL; //文件缓冲区 hFile=CreateFile(lpszFileName, GENERIC_READ|GENERIC_WRITE, //读写文件 FILE_SHARE_WRITE, //写方式:共享写 NULL, CREATE_ALWAYS, //创建一个文件,如果文件已存在将被重写 FILE_ATTRIBUTE_NORMAL, //常规文件 (HANDLE)NULL);
if(hFile!=INVALID_HANDLE_VALUE) { //读取编辑框中的文本的大小 dwFileSize=SendMessage(hWndEdit,WM_GETTEXTLENGTH,0,0); dwFileSize+=1; //文本长度+,否则丢失最后一个字符 if(dwFileSize!=0) //若读取文件大小成功 { lpBufPtr=(char*)malloc(dwFileSize); //开辟文件缓冲区 if(lpBufPtr!=NULL) //若开辟文件缓冲区成功 { //读取编辑框中的内容 GetWindowText(hWndEdit,lpBufPtr,dwFileSize);
//将文件缓冲区内容写入文件 WriteFile(hFile,(LPVOID)lpBufPtr,dwFileSize,&dwByteWrite,NULL); free(lpBufPtr); //释放缓冲区 } else { // MessageBox(NULL,"内存分配失败","",0); return 0; } } else { // MessageBox(NULL,"编辑框内容为空","",0); CloseHandle(hFile); return 0; } } else { // MessageBox(NULL,"创建文件失败","",0); return 0; } CloseHandle(hFile); return 1; }
//编辑框到剪贴板(复制操作) BOOL EditBoxToClip1(HWND hWnd) { LPTSTR lpCopyStr,lpText; HANDLE hText; //全局内存句柄 DWORD dPos; WORD wStart,wEnd; char *lpBufPtr; DWORD dwFileSize; //文本大小
//得到选中的文本位置 dPos=SendMessage(hWndEdit,EM_GETSEL,NULL,NULL); wEnd=HIWORD(dPos); //开始位置 wStart=LOWORD(dPos); //结束位置
//获得文本框中文本长度 dwFileSize=SendMessage(hWndEdit,WM_GETTEXTLENGTH,0,0L); lpBufPtr=(char*)malloc(dwFileSize+2); //开辟文本缓冲区 if(lpBufPtr!=NULL) { // 读取编辑框文本内容保存到lpBufPtr(读取的是所有文本,而不仅仅是选中的文本) SendMessage(hWndEdit,WM_GETTEXT,dwFileSize,(LPARAM)lpBufPtr);
// 截取我们选中的文本 lpCopyStr=lpBufPtr+wStart; *(lpCopyStr+(wEnd-wStart))='\0'; } else { MessageBox(hWnd,"内存分配失败","",MB_OK|MB_ICONEXCLAMATION); return 0; }
if(!(hText=GlobalAlloc(GHND,wEnd-wStart+1))) { MessageBox(hWnd,"全局内存分配失败","",MB_OK); return 0; }
//复制文本到全局内存 lpText=(LPTSTR)GlobalLock(hText); //锁定全局内存并返回全局内存指针 lstrcpy(lpText,lpCopyStr); //复制文本到全局内存 GlobalUnlock(hText); //解锁全局内存
//以下为剪贴板操作 if(!OpenClipboard(hWnd)) //打开剪贴板 { MessageBox(hWnd,"剪贴板打开失败!","",MB_OK); return 0; } EmptyClipboard(); //清空剪贴板 SetClipboardData(CF_TEXT,hText); //设置剪贴板内容 CloseClipboard(); //关闭剪贴板
hText=NULL; return 1; }
//编辑框到剪贴板(剪切操作) BOOL EditBoxToClip2(HWND hWnd) { EditBoxToClip1(hWnd); SendMessage(hWndEdit,EM_REPLACESEL,1,(LPARAM)""); //以空格取代编辑框被选中的文本 return 1; }
//剪贴板到编辑框 BOOL ClipToEditBox(HWND hWnd) { LPTSTR lpPasteStr,lpText; HANDLE hText; DWORD dPos; WORD wStart,wEnd;
//得到文本位置 dPos=SendMessage(hWndEdit,EM_GETSEL,NULL,NULL); wEnd=HIWORD(dPos); wStart=LOWORD(dPos);
if((wEnd-wStart)>=0) //文本长度必须>=0 { if(!(IsClipboardFormatAvailable(CF_TEXT))) { /*---------API函数小帖士------------- 名称 IsClipboardFormatAvailable 原型 BOOL IsClipboardFormatAvailable (UINT uFormat) 描述 检测剪贴板是否支持某种数据类型 返回值:成功返回TRUE,失败返回FALSE 现支持类型: CF_TEXT,即目前只支持检测文本模式 ------------------------------*/ MessageBox(hWnd,"剪贴板文本模式不可用","",MB_OK); return 0; } if(!OpenClipboard(hWnd)) { MessageBox(hWnd,"剪贴板打开失败","",MB_OK); return 0; } if(!(hText=GetClipboardData(CF_TEXT))) { MessageBox(hWnd,"无法读取剪贴板数据","",MB_OK); return 0; }
lpText=(LPTSTR)GlobalLock(hText); //锁定内存并返回内存指针 lpPasteStr=(LPTSTR)malloc(GlobalSize(hText)); //根据剪贴板内容开辟文本缓冲区 lstrcpy(lpPasteStr,lpText); //文本复制 GlobalUnlock(hText); //解锁全局内存
//在编辑框中的光标位置插入lpPasteStr SendMessage(hWndEdit,EM_REPLACESEL,1,(LPARAM)lpPasteStr); } else MessageBox(hWnd,"文本插入位置错误","",MB_OK); return 1; }
bool check(char* a, char* b) //判断两个字符串是否相等 { int i; int j=strlen(b); for(i=0; i<j; i++) { if(*a==*b) { a++; b++; } else return 0; } return 1; }
BOOL ShowFileInfo( HWND hwnd,HDC hDC,HDROP hDropInfo ) { WORD cFiles; char lpszFile[255];
/*----------API 函数小帖士---------------- API函数DragQueryFile(): UINT DragQueryFile(HDROP hDrop, UINT iFile, LPTSTR lpszFile, UINT cch )
---- 其中hDrop是指向拖动文件结构的句柄; ---- iFile 是以开始的被托动文件的序号,因为一次可能拖动多个文件。当此参数 ---- 设为xFFFFFFFF,则函数返回拖动文件的数量; ---- lpszFile 是指向文件名的缓冲区; ---- cch 是文件名缓冲区的大小,即文件名的字符数。 ----------------------------------*/
// 返回拖入的文件数目 cFiles = DragQueryFile( hDropInfo,( UINT )0xFFFFFFFF,( LPTSTR )NULL,( UINT )NULL );
if( cFiles > 1 ) //如果施入的文件不只一个,显示如下信息: { // MessageBox(NULL,"你拖入的文件过多,请重新操作","提示",0); return FALSE; }
else //如果拖入的文件只有一个 { DragQueryFile( hDropInfo,0,lpszFile,sizeof( lpszFile ) ); //从hDropInfo 获取文件信息存放到lpszFile //注:DragQueryFile()函数取得的信息是完整的文件名, // 即除了文件名外还包含了文件路径,可以用MessageBox()函数测试
EnableWindow(hWndEdit,1); //使编辑框可以接受输入 FileToEditBox(hwnd,lpszFile); //文件到编辑框!!!!!!!!!!!! } return TRUE; } |
|
来自: Rainboy913 > 《计算机》