Win API通用对话框之GetOpenFileName

作为《windows程序设计》对话框-podpad3.c,其是一个大一些的程序了, 这样的大块头, 如果你想消化它, 得慢慢来, 我们首先看GetOpenFileName函数和OPENFILENAME结构了:
OPENFILENAME:

typedefstruct tagOFN{
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCTSTR lpstrFilter;
LPTSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPTSTR lpstrFile;
DWORD nMaxFile;
LPTSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCTSTR lpstrInitialDir;
LPCTSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCTSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
#if(_WIN32_WINNT>= 0x0500)
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif// (_WIN32_WINNT >= 0x0500)

} OPENFILENAME,*LPOPENFILENAME;

没有谁能完整地记住上面的结构, 也没有必要, 但是我们得知道结构当中每一项的意义:

// 确定结构的大小
ofn.lStructSize = sizeof(OPENFILENAME);
// 指定它的父窗口
ofn.hwndOwner = hwnd;
// 一般为NULL,表示我们使用的是通用对话框
// ,当然我们也可以自定义对话框,此时hInstance指示
// 资源的handle。
ofn.hInstance = NULL;
// 指示打开或者保存文件时的过滤器,比如说:
// static TCHAR szFilter[] = TEXT("Text Files(*.txt)\0*.txt\0") \
// TEXT("All Files(*.*)\0*.*\0\0");
// 结构是这样的:描述\0过滤\0, 最后一项必须是两个\0,
// 详情请参考MSDN。
ofn.lpstrFilter = szFilter;
// 一般为NULL
ofn.lpstrCustomFilter = NULL;
// 一般为0
ofn.nMaxCustFilter = 0;
// 指示默认过滤器为第几项
ofn.nFilterIndex = 0;
// 用于保存文件的完事路径及文件名
ofn.lpstrFile = fullPath;
// 指示上面结构的大小
ofn.nMaxFile = MAX_PATH;
// 用于保存文件名,不包括路径
ofn.lpstrFileTitle = fileName;
// 指示上面结构的大小
ofn.nMaxFileTitle = MAX_PATH;
// 指示打开对话框的第一路径,
// 我发现为NULL时,初始化路径总是
// “我的文档”。
ofn.lpstrInitialDir = NULL;
// 指示对话框的caption, 我们一般为NULL,
// 让系统指示, 当然也可以自己设置。
ofn.lpstrTitle = NULL;
// 这个东西在打开保存等有点不同,下面是为了打开而设置的
// 我们以后会看到保存时此项的设置。
ofn.Flags = OFN_HIDEREADONLY;
// 为0就可以了
ofn.nFileOffset = 0;
// 为0就可以了
ofn.nFileExtension = 0;
// 如果你保存的时候忘记加.txt时,
// 它会自动给你加上。
ofn.lpstrDefExt = TEXT("txt");
// 为0就可以了
ofn.lCustData = 0;
// 为NULL就可以了
ofn.lpfnHook = NULL;
// 如果想定制对话框, 下面的就不能为NULL了
// 但是我们一般为NULL。
ofn.lpTemplateName = NULL;

OK, 这样就差不多了, 我相信如果你已经适应的API编程, 就不会觉得上面的结构太长太复杂, WINDOWS SDK编程就这样,习惯了吧,哈哈……
我们用GetOpenFileName来创建对话框, 当按OK时, 函数返回非0值, 按CANCEL或者CLOSE时, 函数返回0值。
这是一个例子:
我用它打开了一部3MB的小说。
code:

#include<windows.h>
#include<commdlg.h>
#include"resource.h"

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

static OPENFILENAME ofn;


int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow){
static TCHAR szAppName[]= TEXT("openFile");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, szAppName);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = szAppName;
wndclass.lpszClassName = szAppName;

if(!RegisterClass(&wndclass)){
MessageBox(NULL, TEXT("Register failure..."),
szAppName, MB_ICONERROR);
return 0;
}

hwnd = CreateWindow(szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);

ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

while(GetMessage(&msg,NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}

/*

初始文件

把初始文件作为一个函数,在创建窗口的时候调用

这样才不用在保存文件的时候再写一次

*/
void PopFileInitialize(HWND hwnd)
{
static TCHAR szFilter[] = TEXT("文本文档(*.txt)\0*.txt\0") \
TEXT("ASCII文档 (*.ASC)\0*.asc\0") \
TEXT("所有文档(*.*)\0*.*\0\0");
// 确定结构的大小
ofn.lStructSize = sizeof(OPENFILENAME);


// 指定它的父窗口
ofn.hwndOwner = hwnd;

// 一般为NULL,表示我们使用的是通用对话框,
// 当然我们也可以自定义对话框,此时hInstance指示资源的handle。
ofn.hInstance = NULL;

// 指示打开或者保存文件时的过滤器,比如说:
// static TCHAR szFilter[] = TEXT("Text Files(*.txt)\0*.txt\0") \
//    TEXT("All Files(*.*)\0*.*\0\0");
// 结构是这样的:描述\0过滤\0, 最后一项必须是两个\0,
// 详情请参考MSDN。
ofn.lpstrFilter = szFilter;

// 一般为NULL
ofn.lpstrCustomFilter = NULL;

// 一般为0
ofn.nMaxCustFilter = 0;

// 指示默认过滤器为第几项
ofn.nFilterIndex = 0;

// 用于保存文件的完事路径及文件名
ofn.lpstrFile = NULL;

// 指示上面结构的大小
ofn.nMaxFile = MAX_PATH;

// 用于保存文件名,不包括路径
ofn.lpstrFileTitle = NULL;

// 指示上面结构的大小
ofn.nMaxFileTitle = MAX_PATH;

// 指示打开对话框的第一路径,
// 我发现为NULL时,初始化路径总是“我的文档”。
ofn.lpstrInitialDir = NULL;

// 指示对话框的caption, 我们一般为NULL,让系统指示, 当然也可以自己设置。
ofn.lpstrTitle = NULL;

// 这个东西在打开保存等有点不同,下面是为了打开而设置的
// 我们以后会看到保存时此项的设置。
ofn.Flags = OFN_HIDEREADONLY;

// 为0就可以了
ofn.nFileOffset = 0;

// 为0就可以了
ofn.nFileExtension = 0;

// 如果你保存的时候忘记加.txt时,它会自动给你加上。
ofn.lpstrDefExt = TEXT("txt");

// 为0就可以了
ofn.lCustData = 0;

// 为NULL就可以了
ofn.lpfnHook = NULL;

// 如果想定制对话框, 下面的就不能为NULL了
// 但是我们一般为NULL。
ofn.lpTemplateName = NULL;

}

BOOL openDlg(HWND hwnd, TCHAR* fullPath, TCHAR* fileName) {
ofn.hwndOwner= hwnd; 
ofn.lpstrFile= pstrFileName; 
ofn.lpstrFileTitle= pstrTitleName; 
ofn.Flags= OFN_HIDEREADONLY| OFN_CREATEPROMPT;


return GetOpenFileName(&ofn);

}

BOOL openReadFile(HWND hwnd, TCHAR* fullPath){
HANDLE hFile;
PBYTE pBuffer;
int iFileLength;
DWORD dwByteRead;

if(INVALID_HANDLE_VALUE==(hFile= CreateFile(
fullPath, GENERIC_READ, FILE_SHARE_READ,NULL,
OPEN_EXISTING, 0,NULL)))
return FALSE;

iFileLength = GetFileSize(hFile,NULL);
pBuffer = malloc(iFileLength + 2);
ReadFile(hFile, pBuffer, iFileLength,&dwByteRead,NULL);
CloseHandle(hFile);
pBuffer[iFileLength]= pBuffer[iFileLength+ 1]='\0';
SetWindowText(hwnd, pBuffer);
free(pBuffer);
return TRUE;
}

LRESULT CALLBACK WndProc(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam) {
static TCHAR fullPath[MAX_PATH], fileName[MAX_PATH];
TCHAR* pText;
static HWND hwndEdit;

switch(message){
case WM_CREATE:
hwndEdit = CreateWindow(TEXT("edit"),
NULL,
WS_CHILD | WS_VISIBLE | ES_LEFT
| WS_HSCROLL | WS_VSCROLL | ES_MULTILINE |
ES_AUTOVSCROLL,
0, 0, 0, 0,
hwnd,
(HMENU)1,
(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);

PopFileInitialize(hwnd);//初始化文件设置
return 0;
case WM_SIZE:
MoveWindow(hwndEdit, 0, 0, LOWORD(lParam),
HIWORD(lParam),TRUE);
return 0;

case WM_COMMAND:
switch(LOWORD(wParam)){
case IDM_FILE_OPEN:
if(!openDlg(hwnd, fullPath, fileName)){
MessageBox(NULL, TEXT("can not open file."),
TEXT("Error"), MB_ICONERROR);
fullPath[0]='\0';
fileName[0]='\0';
return 0;
}
if(!openReadFile(hwndEdit, fullPath)){
MessageBox(NULL, TEXT("error read file."),
TEXT("Error"), MB_ICONERROR);
fullPath[0]='\0';
fileName[0]='\0';
return 0;
}
break;
default:
break;
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}


根据下面这篇文章改的,但是打开还会出现乱码,改好之后再更新。

附上原文地址:http://blog.chinaunix.net/uid-16318340-id-2748758.html

你可能感兴趣的:(Windows)