“金蛇语音播放器” 是我随便写的一个假名。要实现的功能是:
我在网上下载了一个播放器,在自己公司的软件中使用,用来播放微信的语音。
因为版权问题,我不想让别人知道我用的是金蛇播放器,于是就将其窗口隐藏;
为了安全起见,再将其窗口标题名称改为“语音播放”。
关联不起作用:将语音文件格式与此播放器关联,然后双击语音文件,不能播放。
但支持拖拽操作:可以将一个语音文件拖拽到此软件的窗口中,然后就开始播放。
于是可以模拟拖拽文件到此软件,实现播放功能,代码如下:
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; }