win32拖拽TXT文本

使用win32实现在窗体内拖拽txt文本的消息响应与读取。兼容Unicode于多字节字符集下,对TXT格式中UTF-8、ANSI与UNICODE编码的转换。文本格式的判断使用正则实现。

完整示例代码(VS2015):http://pan.baidu.com/s/1qYp4r2s

// Win32_1.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "DragTxt.h"
#include "GB2312UTF8.h"
#include 
#include 
#include 
using namespace std;

#define MAX_FILE_PATH 256

// 全局变量: 
HINSTANCE hInst;                                // 当前实例
HWND g_hMainWnd;

INT_PTR CALLBACK DialogProc(
    _In_  HWND hwndDlg,
    _In_  UINT uMsg,
    _In_  WPARAM wParam,
    _In_  LPARAM lParam
);

std::string WideChar2MultiByte(std::wstring src);
std::wstring MultiByte2WideChar(std::string src);
void OnDropFiles(TCHAR* szFilePath);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    hInst = hInstance;
    HWND hWnd = ::CreateDialog(hInstance, (LPCTSTR)IDD_DIALOG_MAIN, NULL, DialogProc);
    if (hWnd == INVALID_HANDLE_VALUE)
        return 0;

    g_hMainWnd = hWnd;
    ShowWindow(hWnd, SW_SHOW);

    MSG msg;
    // 主消息循环: 
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (msg.message == WM_QUIT)
            break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

INT_PTR CALLBACK DialogProc(
    _In_  HWND hwndDlg,
    _In_  UINT uMsg,
    _In_  WPARAM wParam,
    _In_  LPARAM lParam
)
{
    switch (uMsg)
    {
    case WM_CLOSE: 
        PostQuitMessage(0);
        break;
    case WM_INITDIALOG:
        SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON)));
        break;
    case WM_DROPFILES:
    {
        HDROP hDrop = (HDROP)wParam;
        TCHAR szFilePath[MAX_FILE_PATH + 1];
        WORD n = ::DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
        for (WORD i = 0; i < n; i++)
        {
            ::DragQueryFile(hDrop, i, szFilePath, sizeof(szFilePath));
            OnDropFiles(szFilePath);
        }
        DragFinish(hDrop);
    }
        break;
    case WM_DESTROY:
        DestroyWindow(hwndDlg);
        break;
    default:
        return (INT_PTR)FALSE;
    }
    return (INT_PTR)FALSE;
}

std::string WideChar2MultiByte(std::wstring src)
{
    int nLen = WideCharToMultiByte(CP_ACP, 0, src.c_str(), -1, NULL, 0, NULL, NULL);
    char * szString = new char[nLen];//malloc  and    
    int nReturnLen = WideCharToMultiByte(CP_ACP, 0, src.c_str(), -1, szString, nLen, NULL, NULL);
    std::string ret = szString;
    delete[] szString;
    return ret;
}

std::wstring MultiByte2WideChar(std::string src)
{
    std::wstring result = L"";
    WCHAR * wszString;
    int i = MultiByteToWideChar(936, 0, src.c_str(), -1, NULL, 0);
    if (i)
    {
        wszString = new   WCHAR[i * 2];
        RtlZeroMemory(wszString, i * sizeof(WCHAR) * 2);
        MultiByteToWideChar(936, 0, src.c_str(), -1, wszString, i);
        result = wszString;
        delete[] wszString;
    }
    return result;
}

void OnDropFiles(TCHAR* szFilePath)
{
    int cnt = 0;
    unsigned short head;
    string path;

    regex_constants::syntax_option_type f1 = regex_constants::icase;
#ifdef UNICODE
    path = WideChar2MultiByte(szFilePath);
#else
    path = szFilePath;
#endif
    regex pattern("\\.txt", f1);
    if (!regex_search(path, pattern))
    {
        ::MessageBox(g_hMainWnd, _T("不是一个txt文件"), _T("提示"), MB_OK | MB_ICONHAND);
        return;
    }

    HWND hWnd = GetDlgItem(g_hMainWnd, IDC_TEXT);
#ifdef UNICODE
#define TFOPEN _wfopen 
#else
#define TFOPEN fopen 
#endif // UNICODE

    FILE *pFile = TFOPEN(szFilePath, _T("rb"));
#ifdef UNICODE// Unicode
        char szTxt[2048] = { 0 };
        char* pUtf8;
        while ((cnt = fread(szTxt, sizeof(char), sizeof(szTxt) - 1, pFile)) > 0)
        {
            memcpy(&head, szTxt, sizeof(unsigned short));
            switch (head)
            {
            case 0xFEFF://Unicode
                ::SetDlgItemText(g_hMainWnd, IDC_TEXT, (LPCWSTR)szTxt);
                break;
            case 0xBBEF://UTF-8
                pUtf8 = szTxt;
                pUtf8 += 3;
                ::SetDlgItemTextA(g_hMainWnd, IDC_TEXT, _G(pUtf8));
                break;
            default://ANSI
                ::SetDlgItemTextA(g_hMainWnd, IDC_TEXT, szTxt);
                break;
            }
        }
#else// 多字节
        wchar_t szTxt[2048] = { 0 };
        wchar_t* pUnicode;
        while ((cnt = fread(szTxt, sizeof(wchar_t), sizeof(szTxt) - 1, pFile)) > 0)
        {
            memcpy(&head, szTxt, sizeof(unsigned short));
            std::string src;
            char * p;
            switch (head)
            {
            case 0xFEFF://Unicode
                pUnicode = szTxt;
                pUnicode += 1; // 去掉文件头
                ::SetDlgItemTextW(g_hMainWnd, IDC_TEXT, (LPCWSTR)pUnicode);
                break;
            case 0xBBEF://UTF-8
                p = (char*)szTxt;
                p = p + 3;// 去除文件头
                ::SetDlgItemText(g_hMainWnd, IDC_TEXT, (LPCSTR)_G(p));
                break;
            default:
                ::SetDlgItemText(g_hMainWnd, IDC_TEXT, (LPCTSTR)szTxt);
            break;
            }
        }
#endif // UNICODE   

    fclose(pFile);
}

你可能感兴趣的:(windows)