2008-09-27 7 views

Respuesta

3

Como Raymond Chen dijo hace algún tiempo, si usted está pensando acerca de los límites identificador de ventana, es probable que estés haciendo algo mal :)

De todos modos, apuesto a que no hay C# forma especial para hacerlo, porque es muy específico del sistema. Puede usar las mismas funciones que usaría en una aplicación C++. Llame a las funciones usando P/Invoke. Para aprender a escribir las importaciones, vaya al pinvoke.net.

Editar: Como entiendo su pregunta, supongo que ya sabe cómo hacerlo en una aplicación Win32.

15

Si lees la publicación de Raymond Chen, probablemente la encuentres tan molesta como yo. Solo "probablemente estás haciendo algo mal" porque estás haciendo algo que Windows no es capaz de hacer.

En mi aplicación, la primera vez que un usuario visita una página de pestañas, creo y expongo todos los controles en esa página. Esto toma una cantidad de tiempo notable; puede haber fácilmente 50 controles en una página. Así que no descarto los controles en una página de pestañas después de rellenarla, si es posible, y dejo al usuario el cierre de conjuntos de pestañas.

Como sucede, algunos usuarios nunca desean cerrar cualquiera conjuntos de páginas con pestañas. ¿Por qué debería estar forzándolos a hacerlo? Con mi UI, pueden navegar muy rápidamente a cualquiera de los más de 300 conjuntos de transacciones que son responsables de administrar. Sus máquinas son lo suficientemente rápidas y tienen suficiente memoria para que todo esto responda muy bien. El único problema es que Windows no puede soportarlo.

¿Por qué estoy usando controles, y no otra tecnología UI? Porque ellos trabajan. Necesito admitir eventos de enfoque, orden de tabulación, eventos de validación, diseño dinámico y enlace de datos: los usuarios en realidad están administrando miles de registros, en docenas de tablas, en un DataSet en memoria. La cantidad de desarrollo que tendría que hacer para, digamos, implementar algo usando controles sin ventana es astronómico.

Solo estoy "haciendo las cosas mal" porque Windows tiene un límite estricto en el número de identificadores de ventanas que puede admitir. Ese límite estricto se basa en una serie de suposiciones de hace una década sobre cómo se podría construir la IU de una computadora. No soy yo quien "está haciendo algo mal".

En cualquier caso, mi solución a esto se divide en dos partes.

En primer lugar, una clase que puede decirle cuántas ventana que controla su proceso está utilizando:

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); 
     } 
    } 
} 

En segundo lugar, mantener una caché menos utilizado recientemente de mi página pestaña objetos. El .NET Framework no proporciona una clase genérica de caché LRU, así que construí uno, que puede obtener here si necesita uno. Cada vez que el usuario visita una página de pestañas, la agrego al LRU Cache. Luego verifico si me estoy quedando sin controladores de ventana.Si lo estoy, descarto los controles en la página de pestañas usadas menos recientemente, y sigo haciendo eso hasta que tenga suficientes identificadores de ventana nuevamente.

Cuestiones relacionadas