2008-09-27 11 views

ответ

3

Как Raymond Chen положить его некоторое время назад, если вы думаете об ограничениях ручки окна, вы, вероятно, делаете что-то неправильно :)

Во всяком случае, я уверен, что нет никакого специального C# способа сделать это, потому что это очень специфично для системы. Вы можете использовать те же функции, которые будут использоваться в приложении C++. Вызовите функции, используя P/Invoke. Чтобы узнать, как писать импорт, перейдите на страницу pinvoke.net.

Редактировать: Поскольку я понимаю ваш вопрос, я полагаю, вы уже знаете, как это сделать в приложении Win32.

15

Если вы читаете сообщение Раймонда Чена, вы, вероятно, найдете его таким же раздражающим, как я. Вы только «возможно, что-то не так», потому что вы делаете то, на что не способен Windows.

В моем приложении при первом посещении пользователем страницы вкладки я создаю и выкладываю все элементы управления на этой странице. Это занимает заметное количество времени - на странице может легко быть 50 элементов управления. Поэтому я не отбрасываю элементы управления на закладке после ее заполнения, если это вообще возможно, и оставляйте закрывающие наборы страниц вкладок до пользователя.

Как это бывает, некоторые пользователи никогда не хотят закрывать любые наборы страниц вкладок. Почему я должен их заставлять? С моим пользовательским интерфейсом они могут быстро перемещаться к любому из 300 + наборов транзакций, за которые они отвечают за управление. Их машины достаточно быстры, и у них достаточно памяти, чтобы сделать это очень отзывчивым. Единственная проблема заключается в том, что Windows не может ее поддерживать.

Почему я использую элементы управления, а не некоторые другие технологии пользовательского интерфейса? Потому что они работают. Мне нужно поддерживать фокусные события, порядок табуляции, события проверки, динамическую компоновку и привязку данных - пользователи фактически управляют тысячами записей в десятках таблиц в DataSet в памяти. Объем разработки, который я должен был бы сделать, например, - реализовать что-то, используя элементы управления без окон, является астрономическим.

Я только «делаю это неправильно», потому что Windows имеет жесткий предел количества оконных дескрипторов, которые он может поддерживать. Этот жесткий предел основан на куче десятилетних предположений о том, как можно создать пользовательский интерфейс компьютера. Это не я, кто «делает что-то неправильно».

Во всяком случае, мое решение в этом состоит из двух частей.

Во-первых, класс, который может сказать вам, сколько окна обрабатывает ваш процесс с помощью:

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 framework не предоставляет общий класс кеша LRU, поэтому я создал один, который вы можете получить here, если вам это нужно. Каждый раз, когда пользователь посещает вкладку, я добавляю ее в LRU Cache. Затем я проверяю, не работает ли я на окнах.Если я есть, я удаляю элементы управления на странице с последними используемыми закладками и продолжаю делать это, пока у меня не будет достаточно оконных дескрипторов.