使用文件和通用对话框——模仿windows记事本程序Part2
2012-11-07 15:50
399 查看
通用文件对话框
最常用的打开和保存文件的对话框分別通过GetOpenFileName()和GetSaveFileName()来调用, 它们两个都要一个OPENFILENAME结构体作参数.OPENFILENAME ofn; char szFileName[MAX_PATH] = ""; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW ofn.hwndOwner = hwnd; ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; ofn.lpstrFile = szFileName; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrDefExt = "txt"; if(GetOpenFileName(&ofn)) { // Do something usefull with the filename stored in szFileName }
请注意用了ZeroMemory()对结构体清零.这通常是个好的习惯,因为有些API对你传给的不用的参数要设为NULL很挑剔.用这种方法就不需要对每个不用的成员进行设置
了.
LpstrFilter值指向一个双NULL终止符的字符串,并且从例子中看到有数个 ''\0'',包括结尾的那个...编译器会在结尾加上第二个,就像它对字符串常量通常所做的一样(一般不用自己去加).这个字符串中的空字符把其分成多个过滤器,每个有两个部分.第一个过滤器有描述''TextFiles (*.txt)'',通配符在这里不是必需的,接下来的部分是第一个过滤器的实际的通配符,”*.txt”.对第二个过滤器做同样的处理,除了它是一个所有文件的通用过滤器之外.可以随你喜欢加不同的过滤器.
LpstrFile指向配置来保存文件名的內存,因为文件名不能长于MAX_PATH,所以也把这个值当作了此內存的大小.
几个标志表明了对话框对允许用戶输入已存在的文件(我们只想打开,不想创建)并隠藏了我们不打算支持的以只读方式打开的选项.最后我们提供了一个默认的文件扩展名,所以如果用戶输入了''foo'',而沒有找到,那么它会在最后放棄之前去试图打开''foo.txt''.
选择保存文件的代码和打开文件的代码几乎一样,除了调用GetSaveFileName()中我们需要改变一些标志以使选项更适合于保存文件.
OPENFILENAME ofn; char szFileName[MAX_PATH] = ""; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); // SEE NOTE BELOW ofn.hwndOwner = hwnd; ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; ofn.lpstrFile = szFileName; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrDefExt = "txt"; if(GetOpenFileName(&ofn)) { // Do something usefull with the filename stored in szFileName }
读
对createFile()的调用中,GENERIC_READ意即只想有读的权限.FILE_SHARE_READ的意思是如果其它的程序也在打开的时候打开它也可以,但是它们也要是只读才行,它们要是在我们读的时候在对其进行写操作就不行.OPEN_EXISTING意思是只打开已经存在的文件,不要创建它,也不要覆盖它.一旦打开了文件并检查了CreateFile()调用成功后,再来检查文件的大小以便知道要配置多少內存来读入整个文件.于是配置內存,并检查配置的成功与否,用ReadFile()把文件从硬盘读到內存中来.API函数不会知道什么文本文件之类的消息所以它们不能读入文本的一行,或在的字符串后加上一个NULL终止符.这就是为什么要额外地配置一个字节以便在读入整个文件后可以自己加上一个NULL,这样就可以把我们的整个缓冲区当作一个单字符串当为参数传给SetWindowText().
一旦所有的操作都成功了我们就把成功变量设为TRUE,并在函数的末尾处作一些清除工作,在函数最终返回到调用者之前释放配置的內存并关闭文件的句柄
写
与读文件十分类似,写文件的函数只有一点不同.首先在调用CreateFile()的时候要求有读权限,而且文件应该总是新创建(如果已经存在则它将会被打开并清除),如果不存在则它会被以常规属性创建.贴代码了:
#include <Windows.h> #include "resource.h" #define IDR_MAINMENU 102 #define ID_FILE_EXIT 40001 #define ID_FILE_OPENONE 40002 #define ID_FILE_S***EAS 40003 #define ID_FILE_NEWONE 40004 #define IDC_MAIN_EDIT 101 BOOL LoadTextFileToEdit(HWND hEdit, LPCTSTR pszFileName) { HANDLE hFile; BOOL bSuccess = FALSE; hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if(hFile != INVALID_HANDLE_VALUE) { DWORD dwFileSize; dwFileSize = GetFileSize(hFile, NULL); if(dwFileSize != 0xFFFFFFFF) { LPSTR pszFileText; pszFileText = (LPSTR)GlobalAlloc(GPTR, dwFileSize + 1); if(pszFileText != NULL) { DWORD dwRead; if(ReadFile(hFile, pszFileText, dwFileSize, &dwRead, NULL)) { pszFileText[dwFileSize] = 0; // if(SetWindowText(hEdit, pszFileText)) bSuccess = TRUE; // } GlobalFree(pszFileText); } } CloseHandle(hFile); } return bSuccess; } BOOL SaveTextFileFromEdit(HWND hEdit, LPCTSTR pszFileName) { HANDLE hFile; BOOL bSuccess = FALSE; hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile != INVALID_HANDLE_VALUE) { DWORD dwTextLength; dwTextLength = GetWindowTextLength(hEdit); if(dwTextLength > 0) { LPSTR pszText; DWORD dwBufferSize = dwTextLength + 1; pszText = (LPSTR)GlobalAlloc(GPTR, dwBufferSize); if(pszText != NULL) { if(GetWindowText(hEdit, pszText, dwBufferSize)) { DWORD dwWritten; if(WriteFile(hFile, pszText, dwTextLength, &dwWritten, NULL)) bSuccess = TRUE; } GlobalFree(pszText); } } CloseHandle(hFile); } return bSuccess; } void DoFileOpen(HWND hwnd) { OPENFILENAME ofn; char szFileName[MAX_PATH]= ""; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hwnd; ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All File (*.*)\0*.*\0"; ofn.lpstrFile = szFileName; ofn.nMaxFile = MAX_PATH; ofn.lpstrDefExt = "txt"; ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; if (GetOpenFileName(&ofn)) { HWND hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT); LoadTextFileToEdit(hEdit, szFileName); } } void DoFileSaveAs(HWND hwnd) { OPENFILENAME ofn; char szFileName[MAX_PATH]= "" ; ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hwnd; ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All File (*.*)\0*.*\0"; ofn.lpstrFile = szFileName; ofn.nMaxFile = MAX_PATH; ofn.lpstrDefExt = "txt"; ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; if(GetSaveFileName(&ofn)) { HWND hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT); SaveTextFileFromEdit(hEdit, szFileName); } } const char g_szClassName[] = "myWindowClass"; LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: { HWND hEdit; HFONT hDefFont; hEdit = CreateWindowEx(WS_EX_CLIENTEDGE,"Edit","",WS_CHILD|WS_VISIBLE |WS_VSCROLL|WS_HSCROLL|ES_MULTILINE|ES_AUTOHSCROLL|ES_AUTOVSCROLL, 0,0,100,100,hwnd,(HMENU)IDC_MAIN_EDIT,GetModuleHandle(NULL),NULL); if(hEdit == NULL) MessageBox(hwnd,"Create Edit Failed","Error",MB_OK|MB_ICONERROR); hDefFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); SendMessage(hEdit,WM_SETFONT,(WPARAM)hDefFont,MAKELPARAM(FALSE,0)); } break; case WM_SIZE: { HWND hEdit; RECT rect; GetClientRect(hwnd,&rect); hEdit = GetDlgItem(hwnd,IDC_MAIN_EDIT); SetWindowPos(hEdit,NULL,0,0,rect.right,rect.bottom,SWP_NOZORDER); } break; case WM_COMMAND: switch(LOWORD(wParam)) { case ID_FILE_EXIT: PostMessage(hwnd,WM_CLOSE,0,0); break; case ID_FILE_NEWONE: SetDlgItemText(hwnd, IDC_MAIN_EDIT, ""); break; case ID_FILE_OPENONE: DoFileOpen(hwnd); break; case ID_FILE_S***EAS: DoFileSaveAs(hwnd); break; } break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "Edit", WS_OVERLAPPEDWINDOW, 200, 200, 400, 400, NULL, NULL, hInstance, NULL); if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; }
相关文章推荐
- 把程序源代码的文件编码统一为UTF8,行结束符使用\n,不要再用Windows下的记事本工具。
- VS2010MFC对话框程序中使用Windows Media Player播放音频或视频文件
- 一个WinForm记事本程序(包含主/下拉/弹出菜单/打开文件/保存文件/打印/页面设置/字体/颜色对话框/剪切版操作等等控件用法以及记事本菜单事件/按键事件的具体代码)
- Windows做共享存储mount到Linux系统使用ftp工具上传与使用java程序上传文件
- Windows Store apps开发[47]使用默认程序打开文件
- windows下使用cx_freeze将Python程序打包成exe可执行文件
- 背水一战 Windows 10 (98) - 关联启动: 使用外部程序打开一个文件, 使用外部程序打开一个 Uri
- 工具栏和状态栏——模仿windows记事本程序Part3
- 一个WinForm记事本程序(包含主/下拉/弹出菜单/打开文件/保存文件/打印/页面设置/字体/颜色对话框/剪切版操作等等控件用法以及记事本菜单事件/按键事件的具体代码)
- 如何在Smartphone的Win32程序中使用Windows的通用菜单资源(MENU而不是SHMENUBAR)
- error 25015安装程序集“C:\Windows\Microsoft .NET\Framework\v2.0.50727\xxx.dll”失败,原因是出现了系统错误:另一个程序正在使用此文件,进程无法访问
- 第六章:模式对话框和Windows通用控件---第八章:使用ActiveX控件
- 使用py2exe在Windows下将Python程序转为exe文件
- 使用与 Win32API 文件通用对话框打开对话框
- 通用的使用 VIM Ctags Cscope 访问程序文件的方法
- xml数据岛,xsl,javascript,asp.net 的结合使用 web 程序模仿 windows 资源管理器
- 一个WinForm记事本程序(包含主/下拉/弹出菜单/打开文件/保存文件/打印/页面设置/字体/颜色对话框/剪切版操作等等控件用法以及记事本菜单事件/按键事件的具体代码)
- 动态创建控件——模仿windows记事本程序Part1
- TCC编译带通用对话框及资源的简单记事本程序
- Qt系统对话框中文化及应用程序实现重启及使用QSS样式表文件及使用程序启动界面