C#, GDI+ ve UpdateLayeredWindow
Kategori C#, Genel, Programlama, Oluşturulma Jul.11, 2011
Bir önceki yazımda Delphi ile GDI+ kütüphanesinin nasıl kullanılacağını açıklamaya çalışmıştım. Generic Clock bu konu hakkında yeterli olur sanırım. Daha detaylı bir örnek ise Hava Cıva! projesidir. Generic Clock projesini .NET platformunda da yapabilirsiniz aslında. İlgilenen arkadaşlar olabilir diye aynı projeyi bir de C# ile yazdım. Delphi ye göre fazla bir değişiklik yapmadan kolayca geçiş yapabilirsiniz. C# ile geliştirirken sadece Windows API fonksiyonlarının yazılması biraz can sıkabilir o kadar. Gerçi internette hazır birçok kod bulabilirsiniz. Ben üşenmedim ve belli başlı API fonksiyonlarını projeye import ettim. Windows.cs olarak proje dahil ettikten sonra gerisi çok kolay.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace GenericClock
{
internal class Windows
{
[DllImport("user32.dll", SetLastError = true)]
public extern static bool UpdateLayeredWindow(IntPtr handle, IntPtr hdcDst, ref Point pptDst, ref Size pSize, IntPtr hDc, ref Point pptSrc, int crKey, ref BlendFunction pBlend, int dwFlags);
[DllImport("user32.dll", ExactSpelling = false, SetLastError = true)]
public extern static long SetWindowLong(IntPtr handle, int index, IntPtr dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
public extern static IntPtr GetDC(IntPtr handle);
[DllImport("user32.dll", SetLastError = false)]
public extern static int ReleaseDC(IntPtr hWnd, IntPtr hDc);
[DllImport("user32.dll", SetLastError = false)]
public extern static bool ReleaseCapture();
[DllImport("user32.dll", SetLastError = true)]
public extern static int SendMessage(IntPtr handle, int msg, int wparam, int lparam);
[DllImport("gdi32.dll", SetLastError = true)]
public extern static IntPtr CreateCompatibleDC(IntPtr hDc);
[DllImport("gdi32.dll", SetLastError = true)]
public extern static bool DeleteDC(IntPtr hDc);
[DllImport("gdi32.dll", SetLastError = false)]
public extern static IntPtr SelectObject(IntPtr hDc, IntPtr hgdiObject);
[DllImport("gdi32.dll", SetLastError = true)]
public extern static bool DeleteObject(IntPtr hgdiObject);
public struct Point
{
public int X;
public int Y;
}
public struct Size
{
public int X;
public int Y;
}
public struct BlendFunction
{
public byte BlendOp;
public byte BlendFlags;
public byte SourceConstantAlpha;
public byte AlphaFormat;
}
public const byte AC_SRC_OVER = 0x00;
public const byte AC_SRC_ALPHA = 0x01;
public const int ULW_COLORKEY = 0x00000001;
public const int ULW_ALPHA = 0x00000002;
public const int WS_EX_LAYERED = 0x00080000;
public const int GWL_EXSTYLE = -20;
public const int WM_SYSCOMMAND = 0x0112;
public const int SC_DRAGMOVE = 0xf012;
}
}
Projeyi Microsoft Visual Studio 2008 ortamında geliştirdim ve Target Framework' u .NET Framework 3.5 olarak seçtim. Ayrıca Microsoft Visual Studio 2010 ve .NET Framework 4.0 ile de denedim. Derleme ve çalışma sırasında hata oluşmadı. Gönül rahatlığı ile kullanabilirsiniz. Projenin içinde fonksiyonların kullanımı hakkında açıklamalar mevcut. Kaynak kodu incelemenizi şiddetle tavsiye ederim.
Generic Clock projesinin C# versiyonunu aşağıdaki linkten indirebilirsiniz.
generic-clock-csharp-source.rar [63 KB] |
July 13th, 2011 on 1:07 am
C#’a yeni başlamış biri olarak benim için imkansız gördüğüm olaydan biriydi. Değilmiş. 😀 Ama zormuş açıkçası…
C#’la ilgili böyle paylaşımlar beklerim… 🙂
July 13th, 2011 on 2:39 pm
Merhaba Berat,
Evet biraz zor ama kod iyice anlaşılınca sorun çıkmaz. Fazla karmaşık olmasın diye uğraştım ama ancak bu kadar sadeleştirebildim 🙂
March 23rd, 2012 on 10:57 pm
transparan bir textbox koymak istiyorum
çalışır bir buton da yanına koymak istiyorum
internette bu tip projeleri araştırdım hiçkimsenin AlphaBlendTextBox konusunda bilgisi yok.
Sizce böyle birşey yapılması mümkün müdür ?
March 24th, 2012 on 6:12 pm
Maalesef normal windows bileşenleri kullanarak transparent textbox yapmak imkansız. Ama bazı tekniklerle “sahte” bir transparent textbox yapılabiliyor. Burada birkaç yaklaşım var.
1. Yaklaşım: Standart Windows EDIT kullanarak yapılamıyor. Sebebi Windows ta EDIT sınıfının background çizimi pasif duruma getirilemiyor. Windows kendi bileşenlerini transparent çizim yapacak şekilde geliştirmediğinden mutlaka bir zemin oluyor ve bu işimize yaramıyor. Ama textbox’ın parent’inin bir görüntüsünü kendi zeminine çizerek sahte bir transparent textbox yapılabiliyor. Denedim ve çalışıyor. Örneğin RDK da Radyo Arama bu tip bir teknikle çalışıyor.
2. Yaklaşım: Bütün işi gücü bırakıp textbox sınıfını yeniden yazabilirsiniz. Oldukça zor ama imkansız değil. Üstelik full transparent olur. Burada normal edit kutusunun tüm davranışları sağlanırsa çok iyi olur. Klavye girişleri, fare ve klavyeden selection işlemleri gibi. Ben bunuda denedim ve işime yarar kadarı çalışıyor. Örneğin Mini Google 1.0 da bu tip bir textbox var. Fakat Mini Google 1.5 ta 1. yaklaşıma geçtim.
3. Yaklaşım: WPF kullanarak yapmak. Eğer .NET platformu ile yazacaksanız WPF ile yapmak en kısa ve akıllıca yöntem olur. WPF bizim için full ransparent textbox yapmış zaten. Hatta diğer tüm bileşenleride yapmış. Oldukça kolay bir kullanımı var. Tavsiye ederim.
Şimdiden kolay gelsin…
March 18th, 2013 on 11:29 pm
freedelphi bey yorumunuzdaki 1. yaklaşımı tam anlayamadın textbox u nasıl kullanacam yardımlarınız için teşekkürler Güzel örnek …
March 18th, 2013 on 11:44 pm
En zor kısmı seçmişsiniz. .NET üzerinde gerçek zamanlı bir kod yazmadığım için detaylı bilgi veremiyorum. Eğer Delphi biliyorsanız açıklayabilirim. Sizde .NET’ e uyarlarsınız.