Chinaunix首页 | 论坛 | 博客
  • 博客访问: 525316
  • 博文数量: 158
  • 博客积分: 4015
  • 博客等级: 上校
  • 技术积分: 1711
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-27 14:00
文章分类

全部博文(158)

文章存档

2010年(71)

2009年(87)

我的朋友

分类: C/C++

2010-01-21 14:31:37

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

typedef struct 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);
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;
}

BOOL openDlg(HWND hwnd, TCHAR* fullPath, TCHAR* fileName) {
    static OPENFILENAME ofn;
    static TCHAR szFilter[] = TEXT("Text Files(*.txt)\0*.txt\0") \
        TEXT("All Files(*.*)\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 = 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;

    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);
        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);
}


阅读(13864) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~