.NET:屏幕保护程序配置对话框所有者和预览焦点
我创建了一个屏幕保护程序(C#、.NET 4.0,如果这很重要的话),但我有几个问题(不过,在更美观的层面上)。这些问题可能很容易解决,但我很可能从未使用过 Win32 API,因此在涉及到这一点时我很容易错过明显的问题。
Q1:我设置了这样的小预览窗口:
SetParent(Handle, hwndParent); SetWindowLong(Handle, GWL_STYLE, new IntPtr(GetWindowLong(Handle, GWL_STYLE) | WS_CHILD)); Rectangle parentRect; GetClientRect(hwndParent, out ParentRect); Size = parentRect.Size;
其中 hwndParent
是从第二个命令参数解析的。这里的问题是预览窗口窃取了屏幕保护程序设置选项卡的焦点。作为一个天真的尝试,我调用了 SetFocus(hwndParent)
但这没有任何效果。将焦点保持在应有的位置的正确方法是什么
Q2:如果我以创建表单的“通常方式”打开配置对话框,即该
Application.Run(new ConfigurationForm());
对话框将不是控制面板小程序的模式。如何才能实现这一目标?我知道目标父级的 HWND 是通过命令参数“/c:nnnnnnnn”提供的,但这就是我所得到的。 (使用 SetParent(hwndParent)
的行为很奇怪,所以它显然不是正确的函数。)
I have created a screen saver (C#, .NET 4.0 if that matters) but I have a couple of problems (on a more cosmetic level, though). These are probably easy to solve, but I have prettu much never used the Win32 API, so I can easily miss the obvious when it comes to that.
Q1: I set up the small preview window like this:
SetParent(Handle, hwndParent); SetWindowLong(Handle, GWL_STYLE, new IntPtr(GetWindowLong(Handle, GWL_STYLE) | WS_CHILD)); Rectangle parentRect; GetClientRect(hwndParent, out ParentRect); Size = parentRect.Size;
where hwndParent
is parsed from the 2nd command argument. The problem here is that the preview window steals focus from the screen saver settings tab. As a naive attempt, I called SetFocus(hwndParent)
but that didn't have any effect. What's the correct way of keeping the focus where it should be
Q2: If I open the configuration dialog in the "usual way" of creating a form, i.e.
Application.Run(new ConfigurationForm());
the dialog will not be modal to the Control Panel applet. How can this be achieved? I've understood that the HWND of the intended parent is provided with the command argument as "/c:nnnnnnnn" but thats as far I've gotten. (Using SetParent(hwndParent)
just behaved weirdly so it is apparently not the correct function.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您没有检查 API 调用的返回值...我知道,我还从 CodeProject“借用”了该代码,并且它在 XP 之前的任何 Windows 中都损坏了。
您对 SetWindowsLong 的调用失败,因为一旦您更改了窗口的父级,您就无法再更改它。如果您检查返回值并使用 GetLastError,您将看到 GetWindowLong 和 SetWindowLong 失败,错误 = 5(访问被拒绝)。
我通过将对 SetParent 的调用移至使 Window 成为子窗口的调用之后修复了此问题。在这个问题中查看我的代码:
您很快也会问我在那里问的问题:-)
You aren't checking the return values on your API calls... I know, I also "borrowed" that code from CodeProject, and it's broken in any Windows past XP.
Your call to SetWindowsLong is failing, because once you change the parent of the window, you don't have access to change it any more. If you checked your return values and used GetLastError, you would see that GetWindowLong and SetWindowLong are failing with error = 5 (access denied).
I fixed this by moving the call to SetParent to AFTER the call to make the Window a child window. See my code over in this question: Why won't the screen saver control panel kill my form when it dies?
You will also soon be asking the question I asked there :-)