[模拟拖拽] 模拟将一个文件拖拽到一个软件窗口上,实现拖拽操作(微信语音播放器)

“金蛇语音播放器” 是我随便写的一个假名。要实现的功能是:

我在网上下载了一个播放器,在自己公司的软件中使用,用来播放微信的语音。

因为版权问题,我不想让别人知道我用的是金蛇播放器,于是就将其窗口隐藏;

为了安全起见,再将其窗口标题名称改为“语音播放”。

关联不起作用:将语音文件格式与此播放器关联,然后双击语音文件,不能播放。

但支持拖拽操作:可以将一个语音文件拖拽到此软件的窗口中,然后就开始播放。

于是可以模拟拖拽文件到此软件,实现播放功能,代码如下:

BOOL SimulateDropFile(LPCTSTR lpszPath)
{
    HWND hMain = ::FindWindow(NULL, _T("语音播放"));
    if (hMain == NULL) //第一次打开此播放器
    {
        //打开语音播放器
        CString appPath = Utils::GetAppPath();
        appPath += L"Data\amrplayer.exe";
        ShellExecute(NULL, L"open", appPath, NULL, NULL, SW_MINIMIZE);//SW_HIDE 没效果

        int count = 0;
        while (1)
        {
            //找到语音播放器的窗口句柄,
            hMain = ::FindWindow(NULL, _T("金蛇语音播放器"));
            if (hMain != NULL)
                break;
            Sleep(200);
            count++;
            if (count > 50)
                break;
        }
        if (hMain == NULL)
        {
            LOG_ERROR(L"未找到语音播放器");
            return FALSE;
        }

        //改变窗口播放器窗口的标题文本
        SetWindowText(hMain, L"语音播放");
        ::ShowWindow(hMain, SW_HIDE); //隐藏窗口
    }

    CString strFilePath = lpszPath;
    if (!::PathFileExists(strFilePath))
        return FALSE;

    //模拟拖拽操作
    char szFile[MAX_PATH] = { 0 };
    wcstombs(szFile, strFilePath.GetBuffer(0), _MAX_PATH);
    DWORD dwBufSize = sizeof(DROPFILES) + strlen(szFile) + 1;
    BYTE* pBuf = new BYTE[dwBufSize];
    if (pBuf == NULL)
        return FALSE;

    BOOL bResult = FALSE;
    memset(pBuf, 0, dwBufSize);
    DROPFILES* pDrop = (DROPFILES*)pBuf;
    pDrop->pFiles = sizeof(DROPFILES);
    strcpy((char*)(pBuf + sizeof(DROPFILES)), szFile);

    DWORD dwProcessId = 0;
    GetWindowThreadProcessId(hMain, &dwProcessId); //播发器的进程ID
    if (dwProcessId != NULL)
    {
        HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwProcessId);
        if (hProcess != NULL)
        {
            LPSTR pszRemote = (LPSTR)VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE);
            if (pszRemote && WriteProcessMemory(hProcess, pszRemote, pBuf, dwBufSize, 0))
            {
                ::SendMessage(hMain, WM_DROPFILES, (WPARAM)pszRemote, NULL); //发送拖拽消息
                bResult = TRUE;
            }
        }
    }

    if (pBuf)
    {
        delete[] pBuf;
        pBuf = NULL;
    }
    return bResult;
}
原文地址:https://www.cnblogs.com/pjl1119/p/8628788.html