如何在.NET中获取当前的窗口句柄计数和窗口句柄限制?

问题描述 投票:10回答:3

我想获得C#中当前的窗口句柄数和系统范围的窗口句柄限制。我该怎么办?

.net window handle
3个回答
16
投票

[如果您阅读了Raymond Chen的文章,您可能会发现它和我一样令人讨厌。您只是在“可能做错了什么”,因为您在做Windows无法完成的事情。

在我的应用程序中,用户第一次访问选项卡页面时,我在该页面上创建并布置了所有控件。这需要花费大量时间-一个页面上可以轻松包含50个控件。因此,即使有可能,我也不会在标签页上丢弃控件(如果可能的话),并将关闭的标签页集留给用户使用。

碰巧,某些用户从不希望关闭any套标签页。我为什么要强迫他们这样做?借助我的用户界面,他们可以非常快速地导航到他们负责管理的300多种交易中的任何一套。他们的机器速度足够快,并且具有足够的内存,可以使这一切变得非常灵敏。唯一的问题是Windows无法支持它。

为什么我使用控件,而不使用其他UI技术?因为他们work。我需要支持焦点事件,选项卡顺序,验证事件,动态布局和数据绑定-用户实际上是在内存数据集中管理数十个表中的数千条记录。我要做的开发工作量-说-使用无窗口控件实现某些功能是天文数字。

我只是“做错了”,因为Windows对它可以支持的窗口句柄数量有严格的限制。这个硬性限制基于关于计算机UI可能如何构建的数十年的假设。不是我在“做错事”。

无论如何,我的解决方案分为两部分。

首先,一个可以告诉您进程使用多少窗口句柄的类:

using System;
using System.Runtime.InteropServices;

namespace StreamWrite.Proceedings.Client
{
    public class HWndCounter
    {
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetCurrentProcess();

        [DllImport("user32.dll")]
        private static extern uint GetGuiResources(IntPtr hProcess, uint uiFlags);

        private enum ResourceType
        {
            Gdi = 0,
            User = 1
        }

        public static int GetWindowHandlesForCurrentProcess(IntPtr hWnd)
        {
            IntPtr processHandle = GetCurrentProcess();
            uint gdiObjects = GetGuiResources(processHandle, (uint)ResourceType.Gdi);
            uint userObjects = GetGuiResources(processHandle, (uint)ResourceType.User);

            return Convert.ToInt32(gdiObjects + userObjects);
        }
    }
}

其次,我为我的标签页对象保留了最近最少使用的缓存。 .NET框架没有提供通用的LRU缓存类,因此我建立了一个类,如果需要,可以获取here。每次用户访问选项卡页时,我都会将其添加到LRU缓存中。然后,检查窗口把手是否不足。如果是,我将最近使用最少的选项卡页上的控件丢弃,并继续执行此操作,直到再次拥有足够的窗口句柄为止。


3
投票

正如雷蒙德·陈(Raymond Chen)前段时间所说,如果您正在考虑窗口句柄限制,那么您可能做错了:)]

总之,我敢打赌,没有特殊的C#方法可以做到,因为它是特定于系统的。您可以使用与C ++应用程序中相同的功能。使用P / Invoke调用功能。要学习如何编写导入,请转到pinvoke.net

编辑:据我所知,假设您已经知道如何在Win32应用程序中执行此操作。


0
投票

OregonGhost引用的全引号是

© www.soinside.com 2019 - 2024. All rights reserved.