Hoşgeldin Misafir

Windows API Kullanarak WinForm Oluşturalım C#

xS0N3R

23 Ağu 2020
5,424 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Uzun süredir üzerinde çalıştığım bir konuydu bu konu. Yani şöyle ki bir kod bilirkişisi C# programlama dilinin olmazsa olmazlarından birisi olan NetFrameWork yapısını kullanmadan bazı nesneler oluşturabilir miydi? Üstelik Windows API kullanarak... Geçmişte benzer nesneler kullandığımı hatırlayınca Form oluşturabildiğini keşfettim.

Üzülerek bahsetmekteyim uzun süren araştırmalarımda sürekli olarak bir form ögesi tanındığı için & bu tarz bir oluşum istemediğimden yapay zeka yardımı ve yukarıdaki makaleden de yararlandığım sabit değişkeni kaynakları üzerinden bir kod dizini oluşturdum ardından sizlere sonuçları paylaşmak istedim. Kodlarımıza geçelim...

Gerekli Kütüphaneler​

using System;
using System.Runtime.InteropServices;
using System.Text;

class Program verisi altına tanımlanan Windows API + Sabitleri

C#:
[StructLayout(LayoutKind.Sequential)]
struct MSG
{
    public IntPtr hwnd;
    public uint message;
    public IntPtr wParam;
    public IntPtr lParam;
    public uint time;
    public POINT pt;
}

[StructLayout(LayoutKind.Sequential)]
struct POINT
{
    public int x;
    public int y;
}

// Window Procedure delegate
delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

static IntPtr mainWindow; // Ana pencere handle'ı
static IntPtr textBoxHandle; // TextBox handle'ı
static IntPtr labelHandle; // Label handle'ı

Gelelim main verisi altına gireceğimiz Textbox, label, buton oluşturma kodlarına
C#:
 // Window Class tanımlama
 WNDCLASSEX wndClass = new WNDCLASSEX();
 wndClass.cbSize = (uint)Marshal.SizeOf(wndClass);
 wndClass.style = 0;
 wndClass.lpfnWndProc = WindowProc;
 wndClass.cbClsExtra = 0;
 wndClass.cbWndExtra = 0;
 wndClass.hInstance = GetModuleHandle(null);
 wndClass.hIcon = IntPtr.Zero;
// wndClass.hCursor = LoadCursor(IDC_ARROW);
 wndClass.hbrBackground = (IntPtr)(5 + 1); // COLOR_WINDOW
 wndClass.lpszMenuName = null;
 wndClass.lpszClassName = "MyWindowClass";
 wndClass.hIconSm = IntPtr.Zero;

 // Window Class'ı kaydetme
 ushort classAtom = RegisterClassEx(ref wndClass);
 if (classAtom == 0)
 {
     Console.WriteLine("RegisterClassEx failed!");
     return;
 }

 // Pencere oluşturma
 IntPtr hWnd = CreateWindowEx(
     0,                          // dwExStyle
     "MyWindowClass",            // lpClassName
     "Windows API Form - C#",    // lpWindowName
     WS_OVERLAPPEDWINDOW | WS_VISIBLE, // dwStyle
     100, 100,                   // x, y
     800, 600,                   // width, height
     IntPtr.Zero,                // hWndParent
     IntPtr.Zero,                // hMenu
     GetModuleHandle(null),      // hInstance
     IntPtr.Zero);               // lpParam

 if (hWnd == IntPtr.Zero)
 {
     Console.WriteLine("CreateWindowEx failed!");
     return;
 }

 // Ana pencere handle'ını saklıyoruz
 mainWindow = hWnd;

 // Label oluşturma
 IntPtr hLabel = CreateWindowEx(
     0,                          // dwExStyle
     "STATIC",                   // lpClassName (önceden tanımlanmış)
     "Adınızı girin:",           // lpWindowName (label metni)
     WS_CHILD | WS_VISIBLE | SS_LEFT, // dwStyle
     50, 20,                     // x, y
     150, 25,                    // width, height
     hWnd,                       // hWndParent (ana pencere)
     (IntPtr)LABEL_ID,           // hMenu (label ID'si)
     GetModuleHandle(null),      // hInstance
     IntPtr.Zero);               // lpParam

 if (hLabel == IntPtr.Zero)
 {
     Console.WriteLine("Label oluşturulamadı!");
 }
 else
 {
     labelHandle = hLabel;
 }

 // TextBox oluşturma
 IntPtr hTextBox = CreateWindowEx(
     0,                          // dwExStyle
     "EDIT",                     // lpClassName (önceden tanımlanmış)
     "",                         // lpWindowName (başlangıç metni)
     WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT, // dwStyle
     50, 50,                     // x, y
     300, 25,                    // width, height
     hWnd,                       // hWndParent (ana pencere)
     (IntPtr)TEXTBOX_ID,         // hMenu (textbox ID'si)
     GetModuleHandle(null),      // hInstance
     IntPtr.Zero);               // lpParam

 if (hTextBox == IntPtr.Zero)
 {
     Console.WriteLine("TextBox oluşturulamadı!");
 }
 else
 {
     textBoxHandle = hTextBox;
 }

 // Buton oluşturma
 IntPtr hButton = CreateWindowEx(
     0,                          // dwExStyle
     "BUTTON",                   // lpClassName (önceden tanımlanmış)
     "Merhaba De!",              // lpWindowName (buton metni)
     WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // dwStyle
     50, 90,                     // x, y (textbox'ın altına yerleştirdik)
     200, 30,                    // width, height
     hWnd,                       // hWndParent (ana pencere)
     (IntPtr)BUTTON_ID,          // hMenu (buton ID'si)
     GetModuleHandle(null),      // hInstance
     IntPtr.Zero);               // lpParam

 if (hButton == IntPtr.Zero)
 {
     Console.WriteLine("Button oluşturulamadı!");
 }

 // Pencereyi gösterme
 ShowWindow(hWnd, SW_SHOWNORMAL);
 UpdateWindow(hWnd);

 // Mesaj döngüsü
 MSG msg;
 while (GetMessage(out msg, IntPtr.Zero, 0, 0) > 0)
 {
     TranslateMessage(ref msg);
     DispatchMessage(ref msg);
 }

Son kısımda ise mesaj kutusu göstermek için gireceğimiz kodu verelim.
C#:
 static IntPtr WindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
 {
     switch (msg)
     {
         case WM_COMMAND:
             // Buton tıklamasını kontrol et
             int controlId = wParam.ToInt32() & 0xFFFF; // Alt 16 bit kontrolün ID'si
             int notificationCode = (wParam.ToInt32() >> 16) & 0xFFFF; // Üst 16 bit bildirim kodu

             if (controlId == BUTTON_ID)
             {
                 // TextBox'tan metni al
                 StringBuilder textBuffer = new StringBuilder(256);
                 SendMessage(textBoxHandle, WM_GETTEXT, (IntPtr)textBuffer.Capacity, textBuffer);

                 string inputText = textBuffer.ToString();

                 // Eğer TextBox boşsa varsayılan mesaj göster
                 if (string.IsNullOrEmpty(inputText))
                 {
                     MessageBox(hWnd, "Merhaba Dünya!", "Windows API Mesajı", MB_OK);
                 }
                 else
                 {
                     // TextBox'taki metinle kişiselleştirilmiş mesaj göster
                     MessageBox(hWnd, $"Merhaba {inputText}!", "Windows API Mesajı", MB_OK);
                 }
             }
             return IntPtr.Zero;

         case WM_CLOSE:
             PostQuitMessage(0);
             return IntPtr.Zero;

         case WM_DESTROY:
             PostQuitMessage(0);
             return IntPtr.Zero;

         default:
             return DefWindowProc(hWnd, msg, wParam, lParam);
     }

Ardından Derleyelim Bakalım Sonuçlar Nasıl?

92nrpw5.PNG
 

Location

12 Ocak 2022
10 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
.net üzerine birşeyler yapmaya çalışan kişi olarak burada ki konuyu anlamadım. Eğitimler Basit, orta, uzman diye ayrılıyor ya bu uzmanlık dışı mı anlamadım :)

Konuyu anlamamam seviyemin düşük olmasıdır.
 

THS-AI

THS-AI

THS YAPAY ZEKA
Turkhacks Kurumsal
20 Haz 2025
11,255 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
WinForm oluşturmak için öncelikle bir projede System.Windows.Forms kullanmalısın. Basit bir örnekle:

```csharp
using System;
using System.Windows.Forms;

class Program
{
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

Form form = new Form()
{
Text = "WinForm Örneği",
Width = 400,
Height = 300
};

Application.Run(form);
}
}
```

Bu kod ile temel bir Windows Forms uygulaması oluşturabilirsin.