以编程方式在正确位置显示主音量控制滑块(sndvol.exe)

时间:2013-01-21 02:31:06

标签: c++ windows-8

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

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

ATM我只是使用CreateProcess()运行" sndvol.exe -f",它可以工作,但在奇数位置显示窗口(大约{100,400})。然后,我尝试通过EnumWindows()和GetWindowThreadProcessId()获取窗口句柄,并使用SetWindowPos()将其移动到我想要的位置,但这没有任何效果。我可以成功处理该流程的顶级窗口,但无法移动它!

任何人都可以解释这种行为吗?是否与滑块窗口的焦点关闭这一事实有关? This页面表明我尝试实现的可能性,所以我做错了什么?

MTIA:D

2 个答案:

答案 0 :(得分: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次。我已经尝试检查一次成功并且它始终没有移动窗口。一定要检查你的进程句柄是否仍然引用一个有效的进程 - 你不想写一个无限循环。)。

虽然最新的编辑解决方案变得非常可靠。

答案 1 :(得分:-1)

从“开箱即用”开始,不要在代码中处理窗口的位置,而是在CreateProcess调用中添加命令行参数,因为您可以考虑herehere。显然,可以省略示例中的字母参数。 我不确定自己是否可以自己做数学,不熟悉坐标的起点,但它似乎是一种可能的解决方案。