1

刚买了一个新的东芝Satellite Z930,失望地发现没有提供音量增大/减小功能键。但是,超级本在电源按钮旁边确实有两个可编程键,所以我正在尝试开发一个可以从这些键调用的小型 C++ 应用程序。

到目前为止,我的所有代码都可以很好地根据传递给程序的命令行参数来增加/减少音量。我遇到的唯一问题是我想显示主音量滑块以让用户知道操作有效,并且我希望它出现在您单击扬声器图标时出现的正常位置通知区。

ATM 我只是使用 CreateProcess() 来运行“sndvol.exe -f”,它可以工作,但会在一个奇怪的位置(大约 {100、400})显示窗口。因此,我尝试通过 EnumWindows() 和 GetWindowThreadProcessId() 获取窗口句柄,并使用 SetWindowPos() 将其移动到我想要的位置,但这没有任何效果。我可以成功获得进程顶级窗口的句柄,但不能移动它!

谁能解释这种行为?这与将焦点从滑块窗口关闭的事实有关吗?页面表明我想要实现的目标可能的,那么我做错了什么?

MTIA:D

4

2 回答 2

0

不知何故,这个有趣的 STARTUPINFO 和 SetWindowPos 组合似乎起作用了:

#include "windows.h"
#include <iostream>

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) {
    const DWORD myProcessId = (DWORD) lParam;

    DWORD processId;
    GetWindowThreadProcessId(hWnd, &processId);
    if (processId == myProcessId) {
        SetWindowPos(hWnd, 0, 1, 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    }
    return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    STARTUPINFO si;
    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.wShowWindow = SW_SHOWNORMAL;
    si.dwFlags = STARTF_USESHOWWINDOW;
    wchar_t cmdline[33000] = L" -f";
    PROCESS_INFORMATION pi;
    BOOL x = CreateProcess(L"c:\\Windows\\System32\\sndvol.exe", &cmdline[0], 0, 0, true, 0, 0, 0, &si, &pi);
    //std::cerr << x << " " << GetLastError() << std::endl;
    WaitForInputIdle(pi.hProcess, 100);

    for (int i = 0; i < 200; ++i)
    {
        x = EnumWindows(EnumWindowsProc, (LPARAM) pi.dwProcessId);
        //std::cerr << x << " " << GetLastError() << std::endl;
        Sleep(20);
    }

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return 0;
}

您可能想尝试更多以获得更好的解决方案(例如,观察回调是否成功移动窗口至少k多次。我尝试检查一次成功但它并没有总是移动窗口。另外请务必检查您的进程是否处理仍然引用一个有效的过程 - 你不想写一个无限循环。)。

尽管通过最新的编辑,该解决方案变得非常可靠。

于 2013-01-21T03:36:51.190 回答
-1

从“开箱即用”开始,而不是从代码中处理窗口的位置,而是在 CreateProcess 调用中添加命令行参数,正如您可以在此处此处考虑的那样。显然,示例中的字母参数可以省略。我不确定我是否可以自己做数学,不熟悉坐标从哪里开始,但这似乎是一个可能的解决方案。

于 2018-04-05T03:06:55.127 回答