【问题标题】:Set specific size to application's window programmatically以编程方式将特定大小设置为应用程序的窗口
【发布时间】:2014-01-15 11:13:47
【问题描述】:

我的程序 (C#) 是一个任务栏,在它的菜单中我可以启动应用程序,兼容 XP 到 8.1。我想启动任何具有特定窗口大小的应用程序,因为很少有应用程序(OpenOffice、LibreOffice ...)在我第一次启动它们时开始变平。

我已经用ShellExecuteShowCommands.SW_MAXIMIZE 参数测试了最大化这个窗口:

ShellExecute(IntPtr.Zero, "open", executablePath, executableParam, "", ShowCommands.SW_MAXIMIZE);

但是当我点击窗口的“恢复”按钮时,出现了同样的问题,窗口被展平了。

虽然“恢复”大小不是通过手动调整大小来配置的,但使用的值是针对每个应用程序的。

我使用CreateProcess 来指定大小,而不是ShellExecute

const uint NORMAL_PRIORITY_CLASS = 0x0020;
STARTUPINFO si = new STARTUPINFO();
si.dwY = 50;
si.dwX = 50;
si.dwXSize = 200;
si.dwYSize = 800;
si.dwFlags = 0x00000006; //STARTF_USESIZE + STARTF_USEPOSITION
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();

CreateProcess(programPath, programParams, IntPtr.Zero, IntPtr.Zero, true, NORMAL_PRIORITY_CLASS, IntPtr.Zero, null, ref si, out pi);

但是有一个问题,我们可以使用 File->New-> 启动另一个 OpenOffice/LibreOffice 进程...在这种情况下,我的程序不会启动应用程序,因此我的默认大小不适用。

我在更改此值之前和之后检查了 Windows 注册表,更改了两个键:

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSavePidlMRU\reg]
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\Count]

这些键包含十六进制值(第一个键):

之前:

"MRUListEx"=hex:00,00,00,00,04,00,00,00,01,00,00,00,05,00,00,00,03,00,00,00,02,\00,00,00,ff,ff,ff,ff

之后:

"MRUListEx"=hex:01,00,00,00,00,00,00,00,04,00,00,00,05,00,00,00,03,00,00,00,02,\00,00,00,ff,ff,ff,ff

这对我来说是无法理解的,所以我仍在寻找是否存在一种编程方式来设置应用程序/所有应用程序的特定窗口大小或设置到 Windows 注册表中的其他规范。我不是在寻找解决方案来调整或移动已经启动的窗口,如SetWindowPos

但许多网站解释说只有一种定义窗口大小的解决方案:“将窗口拖动到该大小,然后关闭窗口并重新启动它”

http://help.wfu.edu/public/computers/standard-load-software/windows-7---set-default-window-size http://www.tomshardware.co.uk/forum/28659-45-change-default-window-size

这个答案是最终的解决方案还是有办法以编程方式做到这一点?

提前致谢。

编辑:

实际上,当一个窗口被恢复时,我只是第一次调整大小,直到用户杀死它。 我的程序将每个窗口的句柄保存在一个对象中,并将布尔值初始化为 false 以指定我的窗口是否已调整大小。我使用GetForegroundWindow 然后使用GetWindowPlacement 我检查WINDOWPLACEMENT.flags == WindowPlacementFlag.WPF_NONE 并且如果我的布尔值总是等于 false 在这种情况下我使用 GetWindowRect 和 SetWindowPos 设置具有相同位置的特定大小和将我的布尔值分配给 true。

我认为这是一个很好的解决方案,但是我丢失了用户保存的位置(当窗口的大小低于特定值但问题仍然存在时我可以这样做)并且我们看到了调整大小...

【问题讨论】:

  • 每个应用程序都以自己的方式决定如何定位其窗口。没有覆盖应用程序决定的标准。
  • 这就是我害怕的。感谢您的回答。

标签: c# windows registry window-resize


【解决方案1】:

这个问题通常是因为编码器使用GetWindowPos获取要保存的位置,但是窗口在最小化时是关闭的,所以位置是一个被任务栏隐藏的小窗口。这就是被保存的位置。正确的方法是使用GetWindowPlacement保存位置。

您可以枚举所有顶级窗口,检查GetWindowPlacement 以查看哪些可见和恢复但大小或位置不合适(例如,屏幕外、太小)。然后您可以调用SetWindowPlacement 将这些窗口移回屏幕上合理的最小尺寸。

当他们再次保存位置时,他们很可能会保存新位置。

但不要投票。而是使其成为用户可以在需要时运行的实用程序。 (您可能还需要一个例外列表 - 某些实用程序可能会故意创建一个屏幕外窗口。)

【讨论】:

  • 感谢您的回答。我已经编辑了我的帖子。我使用这些方法几乎完美的解决方案。可惜某处没有默认值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 2011-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多