2008-09-27 6 views

Antwort

3

Als Raymond Chen legte es vor einiger Zeit, wenn Sie denken über Grenzen Fenstergriff, sind Sie wahrscheinlich etwas falsch zu machen :)

Wie dem auch sei, ich wette, es gibt keine speziellen C# Art und Weise, es zu tun, weil Es ist sehr systemspezifisch. Sie können dieselben Funktionen verwenden, die Sie in einer C++ - Anwendung verwenden würden. Rufen Sie die Funktionen mit P/Invoke auf. Um zu erfahren, wie Sie die Importe schreiben, gehen Sie zu pinvoke.net.

Edit: Wie ich Ihre Frage verstehe, nehme ich an, Sie wissen bereits, wie man das in einer Win32-Anwendung macht.

15

Wenn Sie Raymond Chens Post lesen, werden Sie es wahrscheinlich genauso nervig finden wie ich. Sie tun nur "wahrscheinlich etwas falsch", weil Sie etwas tun, wozu Windows nicht in der Lage ist.

In meiner Anwendung, wenn ein Benutzer zum ersten Mal eine Registerkarte besucht, erstelle ich alle Steuerelemente auf dieser Seite und lege sie an. Dies nimmt eine beachtliche Zeit in Anspruch - auf einer Seite können bis zu 50 Steuerelemente verwendet werden. Daher verwerfe ich die Steuerelemente auf einer Registerkarte nach dem Auffüllen nicht, wenn es überhaupt möglich ist, und überlasse dem Benutzer schließende Sätze von Registerkarten.

Wie es passiert, wollen einige Benutzer niemals irgendwelche Sätze von Registerkarten schließen. Warum sollte ich sie zwingen? Mit meiner Benutzeroberfläche können sie sehr schnell zu einer der über 300 Transaktionsgruppen navigieren, für die sie zuständig sind. Ihre Maschinen sind schnell genug und haben genug Speicher, um alles sehr reaktionsschnell zu machen. Das einzige Problem ist, dass Windows es nicht unterstützen kann.

Warum verwende ich Steuerelemente und keine andere UI-Technologie? Weil sie arbeiten. Ich muss Fokus-Ereignisse, Tab-Reihenfolge, Validierungsereignisse, dynamisches Layout und Datenbindung unterstützen - die Benutzer verwalten tatsächlich Tausende von Datensätzen in Dutzenden von Tabellen in einem In-Memory-DataSet. Die Menge an Entwicklung, die ich tun müsste, um - etwas zu implementieren - etwas mit fensterlosen Steuerungen zu implementieren, ist astronomisch.

Ich mache nur "es falsch machen", weil Windows eine harte Grenze für die Anzahl der Fenstergriffe hat, die es unterstützen kann. Dieses harte Limit basiert auf einer Reihe jahrzehntelanger Annahmen darüber, wie die Benutzeroberfläche eines Computers aufgebaut sein könnte. Es ist nicht ich, der etwas falsch macht.

Meine Lösung besteht jedenfalls aus zwei Teilen.

Zuerst wird eine Klasse, die man kann sagen, wie viele Fenstergriffe Ihr Prozess verwendet:

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

Zweitens halten wir am wenigsten kürzlich verwendete Cache meiner Registerkarte Objekte. Das .NET-Framework bietet keine generische LRU-Cache-Klasse, also habe ich eine erstellt, die Sie here erhalten können, wenn Sie eine benötigen. Jedes Mal, wenn der Benutzer eine Registerkarte aufruft, füge ich ihn dem LRU-Cache hinzu. Dann überprüfe ich, ob mir die Fenstergriffe knapp werden.Wenn das so ist, werfe ich die Steuerelemente auf der zuletzt verwendeten Registerkarte weg und mache das so lange, bis ich wieder genug Fenstergriffe habe.