[C#] Windows Formunda Sistem Menüsünü Yönetmek

  • Konuyu başlatan Konuyu başlatan EftelyA
  • Başlangıç tarihi Başlangıç tarihi

EftelyA

Yaşayan Forum Efsanesi
Katılım
22 Kas 2007
Mesajlar
9,097
Tepkime puanı
59
Konum
EsEs
Windows ortamında geliştirdiğimiz desktop tabanlı exe programındaki her formun task barında standart pencere yönetim menüsü çıkar. Pencerenin ikonu tıklandığında, title bar veya taskbar sağ tıklandığında görünen bu sistem menüsü formun türüne göre farklılık gösterse de genellikle, Restore, Move, Size, Minimize, Maximize ve Close eventleri içerir. Uygulamalarımızda bu menüyü yönetmek isteyebiliriz örneğin oradaki default menüden bazılarını disable etme ihtiyacı doğabilir veya birçok programda gördüğümüz “About” bölümünü ekleyebiliriz. Sistem menüsünü yönetmek için .NET plaftormunda özel bir kütüphane bulunmamaktadır. Bunu sağlamak için Windows API’si kullanılır.
Sistem menüsü yönetimi için Windows API’sindeki GetSystemMenu() fonksiyonu çağrılır. Bu fonskiyon, çalışan pencereye ait System Menu’nun kopyasını döndürür. Bu menü üzerinde değişiklik veya ekleme yapmak için AppendMenu(), InsertMenu() metodları kullanılır. user32.dll API’sini projeye dahil edip ilgili fonksiyonları kullanalım.


Kod:
using System.Runtime.InteropServices;
…
[DllImport("user32.dll")]
private static extern int GetSystemMenu(int hwnd, int bRevert); 

[DllImport("user32.dll")]
private static extern int AppendMenu(int hMenu, int Flagsw, int IDNewItem, string lpNewItem);
private **** Form1_Load(object sender, EventArgs e)
{
    //System menu’sünü handle edelim
    int systemMenu = GetSystemMenu(this.Handle.ToInt32(), 0);
    //Bir separator ekleyelim
    AppendMenu(systemMenu, 0xA00, 0, null);
    //Hakkında menüsünü ekleyelim
    AppendMenu(systemMenu, 0, 100, "&Hakkında");
}//Form1_Load
Menüdeki “Hakkında” bölümüne ait bir click event yazmak için WndProc() metodu override edilir. Bu metod, menüden gelecek mesajları dinler. Gelen mesaj, “Hakkında” bölümüyle ilgiliyse bunu Hakkinda_Click metoduyla ilişkilendirilir. Aslında bu bölümde açıklama yapılacak bir durum olmadığı için doğrudan kodu vermemiz daha yönlendirici olacaktır.


Kod:
protected override **** WndProc(ref System.Windows.Forms.Message m)
{
    base.WndProc(ref m); 

    if (m.Msg == 0×112) // WM_SYSCOMMAND
        WmSysCommand(m.WParam.ToInt32());
}//WndProc
private **** WmSysCommand(int wParam)
{
    if (wParam == 100) //Menüye ait ID bilgisi
    {
        Hakkinda_Click(this, [URL="http://www.google.com/search?q=new+msdn.microsoft.com"]   new[/URL] EventArgs());
    }
}//WmSysCommand
private **** Hakkinda_Click(object sender, System.EventArgs e)
{
    MessageBox.Show("Hakkında Bölümü");
}//Hakkinda_Click
Penceredeki Close buttonunu disable etmek
Konuyla ilgili olarak en çok ihtiyaç duyulan işlemlerden biri de sistem menüsündeki “X Close” bölümünü kapatmaktır. .NET’teki Form class’ının ControlBox property’sini false olarak set edebiliriz ancak bu durumda maximize, minimize buttonlarını da görünmez yapmış oluruz. Sistem menüsünden bir bölümü kaldırmak için API’nin RemoveMenuItem() metodu kullanılır. Bu metoda parametre olarak disable edilecek item’in index numarası verilir. “Close” bölümü, menünün en son elemanı olduğu için menünün eleman sayısının 1 eksiği bu menünün indexini verecektir. Menünün item sayısını GetMenuItemCount() fonksiyonunu döndürür. Disable, remove işlemi yapıldıktan sonra menüyü yeniden oluşturmak için DrawMenuBar() metodu kullanılır.


Kod:
[DllImport("user32")]
public static extern int GetMenuItemCount(int systemMenu); 

[DllImport("user32")]
public static extern int RemoveMenu(int systemMenu, int itemPosition, int flag);
[DllImport("user32")]
public static extern int DrawMenuBar(int currentWindow);
        
private **** Form1_Load(object sender, EventArgs e)
{
    //System menu’sünü handle edelim
    int systemMenu = GetSystemMenu(this.Handle.ToInt32(), 0);
    //Sistem menüsündeki Item sayısını alalım
    int itemCount = GetMenuItemCount(systemMenu);
    //Menudeki "Close" bölümünü disable edelim
    const Int32 MF_BYPOSITION = 0×400;
    const Int32 MF_REMOVE = 0×1000;
    RemoveMenu(systemMenu, itemCount - 1, MF_BYPOSITION | MF_REMOVE);
    //Uygulamadaki menu barı yeniden çizdirelim
    DrawMenuBar(this.Handle.ToInt32());
}//Form1_Load
Bu işlem sayesinde Close menüsüne disable etmiş olduk ancak kullanıcı bu pencereyi ALT+F4 kısa yoluyla yine kapatabilir. Bunu yönetmek için Form’un Form1_FormClosing eventini kullanabiliriz

Kod:
private **** Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    DialogResult result;
    //Formu kapatmaya çalışırken uyarı verelim.
    result = MessageBox.Show("Uygulamadan çıkmak istediğinize emin misiniz?", "Uygulamadan Çıkış ?", MessageBoxButtons.OKCancel);
    
    //Kullanıcının yanıtını okuyalım
    //OK düğmesini tıklamışsa
    if (result == System.Windows.Forms.DialogResult.OK) 
    {
        //Uygulamayı kapat
        e.Cancel = false;
    }
    else //Cancel düğmesini tıklamışsa
    {
        //Uygulamayı açık bırak
        e.Cancel = true;
    } 

}//Form1_FormClosing
 
Geri
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.