C#‘da Process.MainWindowHandle
Davranışını Anlamak
C# ve .NET uygulamalarıyla çalışırken, Process.MainWindowHandle
ile ilgili beklenmedik bir davranışla karşılaşabilirsiniz. Bu özellik, genellikle başlatıldığında oluşturulan süreçteki ana pencereye atıfta bulunmalıdır. Ancak birçok geliştirici, çalışma zamanında dinamik olarak değişiyormuş gibi göründüğünü fark etmiştir; bu, resmi Microsoft belgelerinin önerdiği durumun tersidir. Bu olguyu anlamaya ve arka planda neler olduğunu incelemeye başlayalım.
Görünür Karmaşa
MSDN belgelerine göre, ana pencere, bir süreç başladığında oluşturulan ilk pencere olarak tanımlanmıştır. Daha sonra modal ve üst düzey pencereler gibi ek pencerelerin görünebileceğini belirtirken, ilk oluşturulan pencerenin ana pencere olarak tutarlı bir şekilde kalması gerektiğini öne sürer.
Buna rağmen, bir uygulamayı hata ayıklarken MainWindowHandle
‘ı gözlemliyorsanız, değerinin beklenmedik bir şekilde değiştiği durumlarla karşılaşabilirsiniz. Belirli etkileşimler sırasında, örneğin bir Windows Forms uygulamasında açılır menü açarken, tutamağın dalgalandığını fark etmek karmaşayı artırır.
Değişiklikleri Gözlemlemek İçin Bir Test Kurma
Bu davranışı daha iyi anlamak için, bir geliştirici Visual Studio (DEVENV
) sürecinin MainWindowHandle
‘ını izleyen basit bir WinForms uygulaması oluşturdu. Aşağıda, MainWindowHandle
‘ı her 100 milisaniyede bir kontrol eden temel uygulama yer almaktadır:
IntPtr oldHWnd = IntPtr.Zero;
void GetMainwindowHandle()
{
Process[] processes = Process.GetProcessesByName("DEVENV");
if (processes.Length != 1)
return;
IntPtr newHWnd = processes[0].MainWindowHandle;
if (newHWnd != oldHWnd)
{
oldHWnd = newHWnd;
textBox1.AppendText(processes[0].MainWindowHandle.ToString("X") + "\r\n");
}
}
private void timer1Tick(object sender, EventArgs e)
{
GetMainwindowHandle();
}
Bu kod, sürekli olarak MainWindowHandle
‘daki değişiklikleri kontrol eden bir zamanlayıcı çalıştırır. İlginç bir şekilde, belirli UI öğelerine tıklamanın gerçekten de tutamağı değiştirebileceği doğrulanmıştır.
Temel Sorunu İnceleme
Değişen MainWindowHandle
ile ilgili karmaşa, .NET’in ana pencereyi nasıl belirlediğinden kaynaklanıyor olabilir. .NET kaynak kodunu incelediğimizde, iç işleyişinin nasıl çalıştığını görebiliriz:
private bool IsMainWindow(IntPtr handle)
{
return (!(NativeMethods.GetWindow(new HandleRef(this, handle), 4) != IntPtr.Zero)
&& NativeMethods.IsWindowVisible(new HandleRef(this, handle)));
}
Bu yöntem, pencerenin üst düzey görünür bir pencere olup olmadığını kontrol eder; dolayısıyla, birden fazla görünür üst düzey pencere olduğunda, bu kriterleri karşılayan ilk karşılaştığı pencere ana pencere haline gelir. Bu nedenle, teknik olarak ‘ilk’ görünür pencereyi açan başka bir pencere belirdiğinde, MainWindowHandle
bu yeni pencereye kayabilir.
Sonuç ve Çıkarım
Sonuç olarak, Process.MainWindowHandle
davranışı her zaman belgeleriyle uyumlu olmayabilir. Görünürlük ve diğer pencerelerin aktivitesine bağlı olarak değerin değiştiği görünüyor. Bu yüzden, bu özelliği kullanarak uygulama geliştirirken, tutamağın başlangıçta varsayıldığı kadar sabit olmayabileceğini unutmamak önemlidir.
Bir dahaki sefere uygulamanızda MainWindowHandle
‘da beklenmedik değişiklikler gözlemlediğinizde, .NET’in pencere görünürlüğü üzerindeki yönetiminin bu şaşırtıcı davranışa yol açabileceğini hatırlayın. Uygulamalarınızın bu tür incelikleri zarif bir şekilde yönetmesini her zaman sağladığınızdan emin olun.