如何使用 SPI_SETWORKAREA 标志调整桌面工作区域的大小?

发布于 2024-11-14 10:23:41 字数 1026 浏览 1 评论 0原文

我已经尝试调整桌面工作区域(窗口最大化的区域)的大小已经有一段时间了。我已经找到了所需的 API,但我似乎无法调整工作区域的大小。它什么也没做。

我使用 Windows 7 Ultimate x64,因此我也尝试在 x64“模式”下编译它,但仍然没有成功。有人可以推动我朝正确的方向前进吗?

这是我到目前为止得到的:

[DllImport("user32.dll", EntryPoint = "SystemParametersInfoA")]
private static extern Int32 SystemParametersInfo(Int32 uAction, Int32 uParam, IntPtr lpvParam, Int32 fuWinIni);

private const Int32 SPIF_SENDWININICHANGE = 2;
private const Int32 SPIF_UPDATEINIFILE = 1;
private const Int32 SPIF_change = SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE;
private const Int32 SPI_SETWORKAREA = 47;
private const Int32 SPI_GETWORKAREA = 48;

public struct RECT
{
    public Int32 Left;
    public Int32 Right;
    public Int32 Top;
    public Int32 Bottom;
}

private static int SetWorkspace(RECT oRECT)
{
    IntPtr ptr = IntPtr.Zero;
    ptr = Marshal.AllocHGlobal(Marshal.SizeOf(oRECT));
    Marshal.StructureToPtr(oRECT, ptr, true);
    return SystemParametersInfo(SPI_SETWORKAREA, Marshal.SizeOf(oRECT), ptr, SPIF_change);
}

I have been trying for quite a while now to resize the desktop work area (the area where windows get maximized). I have found the required API, but I can't seem to resize the work area. It does just nothing.

I use Windows 7 Ultimate x64 so I also tried compiling it in x64 'mode', and still no luck. Could someone give me a push in the right direction?

Here is what I got so far:

[DllImport("user32.dll", EntryPoint = "SystemParametersInfoA")]
private static extern Int32 SystemParametersInfo(Int32 uAction, Int32 uParam, IntPtr lpvParam, Int32 fuWinIni);

private const Int32 SPIF_SENDWININICHANGE = 2;
private const Int32 SPIF_UPDATEINIFILE = 1;
private const Int32 SPIF_change = SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE;
private const Int32 SPI_SETWORKAREA = 47;
private const Int32 SPI_GETWORKAREA = 48;

public struct RECT
{
    public Int32 Left;
    public Int32 Right;
    public Int32 Top;
    public Int32 Bottom;
}

private static int SetWorkspace(RECT oRECT)
{
    IntPtr ptr = IntPtr.Zero;
    ptr = Marshal.AllocHGlobal(Marshal.SizeOf(oRECT));
    Marshal.StructureToPtr(oRECT, ptr, true);
    return SystemParametersInfo(SPI_SETWORKAREA, Marshal.SizeOf(oRECT), ptr, SPIF_change);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无可置疑 2024-11-21 10:23:41

以下代码应该可以正常工作:

// 1. Change the function to call the Unicode variant, where applicable.
// 2. Ask the marshaller to alert you to any errors that occur.
// 3. Change the parameter types to make marshaling easier. 
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SystemParametersInfo(
                                                int uiAction,
                                                int uiParam,
                                                ref RECT pvParam,
                                                int fWinIni);

private const Int32 SPIF_SENDWININICHANGE = 2;
private const Int32 SPIF_UPDATEINIFILE = 1;
private const Int32 SPIF_change = SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE;
private const Int32 SPI_SETWORKAREA = 47;
private const Int32 SPI_GETWORKAREA = 48;

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public Int32 Left;
    public Int32 Top;   // top is before right in the native struct
    public Int32 Right;
    public Int32 Bottom;
}

private static bool SetWorkspace(RECT rect)
{
   // Since you've declared the P/Invoke function correctly, you don't need to
   // do the marshaling yourself manually. The .NET FW will take care of it.

   bool result = SystemParametersInfo(SPI_SETWORKAREA,
                                      IntPtr.Zero,
                                      ref RECT,
                                      SPIF_change);
   if (!result)
   {
       // Find out the error code
       MessageBox.Show("The last error was: " +
                       Marshal.GetLastWin32Error().ToString());
   }

   return result;
}

但我不太确定您要做什么。默认情况下,工作区域是屏幕上未被系统任务栏或应用程序桌面工具栏遮挡的部分。您将无法使其大于屏幕上的可用区域(不过,如果可以的话,这是一个巧妙的技巧!)。当您最大化窗口时,您的窗口是否已经填满整个屏幕?

即使在具有多个显示器的计算机上,您也无法将工作区域设置为跨多个显示器。 MSDN 文档表示它仅限于设置显示器的工作区域包含指定的矩形:

在具有多个显示器的系统中,该函数设置包含指定矩形的显示器的工作区域。

The following code should work just fine:

// 1. Change the function to call the Unicode variant, where applicable.
// 2. Ask the marshaller to alert you to any errors that occur.
// 3. Change the parameter types to make marshaling easier. 
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SystemParametersInfo(
                                                int uiAction,
                                                int uiParam,
                                                ref RECT pvParam,
                                                int fWinIni);

private const Int32 SPIF_SENDWININICHANGE = 2;
private const Int32 SPIF_UPDATEINIFILE = 1;
private const Int32 SPIF_change = SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE;
private const Int32 SPI_SETWORKAREA = 47;
private const Int32 SPI_GETWORKAREA = 48;

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public Int32 Left;
    public Int32 Top;   // top is before right in the native struct
    public Int32 Right;
    public Int32 Bottom;
}

private static bool SetWorkspace(RECT rect)
{
   // Since you've declared the P/Invoke function correctly, you don't need to
   // do the marshaling yourself manually. The .NET FW will take care of it.

   bool result = SystemParametersInfo(SPI_SETWORKAREA,
                                      IntPtr.Zero,
                                      ref RECT,
                                      SPIF_change);
   if (!result)
   {
       // Find out the error code
       MessageBox.Show("The last error was: " +
                       Marshal.GetLastWin32Error().ToString());
   }

   return result;
}

But I'm not really sure what you're trying to do. By default, the work area is the portion of the screen not obscured by the system taskbar or by application desktop toolbars. You're not going to be able to make it any larger than the area that's available on your screen (neat trick if you could, though!). Do your windows not already fill the entire screen when you maximize them?

And even on machines with multiple monitors, you can't set the working area to span multiple monitors. The MSDN documentation says that it's constrained to setting the working area of the monitor that contains the specified rectangle:

In a system with multiple display monitors, the function sets the work area of the monitor that contains the specified rectangle.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文