Win32 Api 学习记录-Ocrosoft
浙江财经大学
信工学院ACM集训队

Win32 Api 学习记录

本文由 Ocrosoft 于 2018-05-16 10:12:05 发表

摘要:使用列表框显示文件列表LB_DIR,文件的读取CreateFile,ReadFile,显示文本DrawText

1.1.源码:

#include <windows.h>

#define ID_LIST 1
#define ID_TEXT 2

#define MAXREAD 8192
// 管它什么,全都显示出来
#define DIRATTR (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | DDL_SYSTEM | DDL_DIRECTORY | DDL_ARCHIVE | DDL_DRIVES)
#define DTFLAGS (DT_WORDBREAK | DT_EXPANDTABS | DT_NOCLIP)

/*
 * DT_WORDBREAK:自动换行
 * DT_EXPANDTABS:使每个TAB为8,但是不使用TAB处会变成黑块
 * DT_NOCLIP:无裁剪绘制时使DT函数加快
 * DT_NOPREFIX:关闭前缀处理,不关闭会进行转义处理,如&&显示为&
 */

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

// 旧的窗口处理
WNDPROC OldList;

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

    hInstance = hInstance;

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

    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
        return 0;
    }

    hwnd = CreateWindow(szAppName, TEXT("head"), 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;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static BOOL bValidFile;
    static BYTE buffer[MAXREAD];
    static HWND hwndList, hwndText;
    // 显示文本内容的矩形
    static RECT rect;
    static TCHAR szFile[MAX_PATH + 1];
    HANDLE hFile;
    HDC hdc;
    int i, cxChar, cyChar;
    PAINTSTRUCT ps;
    TCHAR szBuffer[MAX_PATH + 1];

    switch(message)
    {
    case WM_CREATE:
        cxChar = LOWORD(GetDialogBaseUnits());
        cyChar = HIWORD(GetDialogBaseUnits());

        rect.left = 20 * cxChar;
        rect.top = 3 * cyChar;

        hwndList = CreateWindow(TEXT("listbox"), NULL,
                                WS_CHILDWINDOW | WS_VISIBLE | LBS_STANDARD,
                                cxChar, cyChar * 3,
                                cxChar * 13 + GetSystemMetrics(SM_CXVSCROLL),
                                cyChar * 10,
                                hwnd, (HMENU)ID_LIST,
                                (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
                                NULL);

        // 获取当前目录,很神奇地最大字符数在前面
        GetCurrentDirectory(MAX_PATH + 1, szBuffer);

        hwndText = CreateWindow(TEXT("static"), szBuffer, WS_CHILDWINDOW | WS_VISIBLE | SS_LEFT,
                                cxChar, cyChar, cxChar * MAX_PATH, cyChar,
                                hwnd, (HMENU)ID_TEXT,
                                (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
                                NULL);

        OldList = (WNDPROC)SetWindowLong(hwndList, GWL_WNDPROC, (LPARAM)ListProc); // hook

        // LB_DIR:设置筛选器,用符合筛选器的文件列表填充列表
        SendMessage(hwndList, LB_DIR, DIRATTR, (LPARAM) TEXT("*.*"));
        return 0;

    case WM_SIZE:
        rect.right = LOWORD(lParam);
        rect.bottom = HIWORD(lParam);
        return 0;

    case WM_SETFOCUS:
        SetFocus(hwndList);
        return 0;

    case WM_COMMAND:
        if (LOWORD(wParam) == ID_LIST && HIWORD(wParam) == LBN_DBLCLK) // 列表双击事件
        {
            if (LB_ERR == (i = SendMessage(hwndList, LB_GETCURSEL, 0, 0))) // 获取选择项下标
                break;

            SendMessage(hwndList, LB_GETTEXT, i, (LPARAM)szBuffer); // 获取选择项内容

            // 创建文件句柄(打开文件),参数1的szBuffer是文件名
            if(INVALID_HANDLE_VALUE != (hFile = CreateFile(szBuffer,
                                                GENERIC_READ, FILE_SHARE_READ, NULL,
                                                OPEN_EXISTING, 0, NULL)))
            {
                CloseHandle(hFile);
                bValidFile = TRUE;
                lstrcpy(szFile, szBuffer);
                GetCurrentDirectory(MAX_PATH + 1, szBuffer);

                // 如果获取到的目录最后不是\\则添加
                if (szBuffer[lstrlen(szBuffer) - 1] != '\\')
                    lstrcat(szBuffer, TEXT("\\"));
                SetWindowText(hwndText, lstrcat(szBuffer, szFile));
            }
            else // 是文件夹或..等情况,会用[]括起来
            {
                bValidFile = FALSE;
                szBuffer[lstrlen(szBuffer) - 1] = '\0'; // 去掉]

                if (!SetCurrentDirectory(szBuffer + 1)) // 是盘符的情况,C盘会显示[-c-]
                {
                    szBuffer[3] = ':'; // 去掉-]变成:
                    szBuffer[4] = '\0';
                    SetCurrentDirectory(szBuffer + 2); // 去掉[-
                }

                GetCurrentDirectory(MAX_PATH + 1, szBuffer); // 去掉[
                SetWindowText(hwndText, szBuffer);
                SendMessage(hwndList, LB_RESETCONTENT, 0, 0); // 重新填充
                SendMessage(hwndList, LB_DIR, DIRATTR, (LPARAM)TEXT("*.*"));
            }
            InvalidateRect(hwnd, NULL, TRUE);
        }
        return 0;

    case WM_PAINT:
        if (!bValidFile)
            break;

        if (INVALID_HANDLE_VALUE == (hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)))
        {
            bValidFile = FALSE;
            break;
        }

        // 读取文件hFile,保存到buffer,最多读取MAXREAD,最终读取了i
        ReadFile(hFile, buffer, MAXREAD, &i, NULL);
        CloseHandle(hFile);

        hdc = BeginPaint(hwnd, &ps);
        SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
        SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
        SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));

        DrawTextA(hdc, buffer, i, &rect, DTFLAGS);

        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, message, wParam, lParam);
}

// 窗口子类化(自hook)
LRESULT CALLBACK ListProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if (message == WM_KEYDOWN && wParam == VK_RETURN) // 处理键盘消息
        SendMessage(GetParent(hwnd), WM_COMMAND, MAKELONG(1, LBN_DBLCLK), (LPARAM)hwnd);
    return CallWindowProc(OldList, hwnd, message, wParam, lParam);
}

1.2.运行

欢迎转载,请保留出处与链接。Ocrosoft » Win32 Api 学习记录

点赞 (0)or拍砖 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址