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

时间:2011-06-07 14:59:12

标签: c# .net windows winapi pinvoke

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

我使用Windows 7旗舰版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);
}

1 个答案:

答案 0 :(得分:4)

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

// 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 documentation表示它仅限于设置包含指定矩形的监视器的工作区域:

  

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