A kontrol elkészítése
Kontrolunk a TextBox osztályból származik, és az input karaktereket fogjuk ellenőrizni, és ha szükséges letiltani a megjelenésüket.
A kontrol készítésekor először végig kell gondolnunk, hogy a billentyűzetről bevihető karakterek milyen fő kategóriákba sorolhatók. Az alábbi kategóriákba soroltuk a karaktereket:
- Vezérlőkarakterek
- Alfanumerikus karakterek (az ABC kis- és nagybetűi, valamint a 10 db számkarakter)
- Szimbólumok
Az elkészítendő kontrolban az alfanumerikus csoport elemeit külön lehet engedélyezni, illetve tiltani.
A készítés előtt meg kell határozni, hogy milyen módszer alkalmas arra, hogy még megjelenítés előtt ellenőrizni tudjuk a szövegmezőbe bevinni szándékozott karaktereket. Sajnos nem használhatjuk a hagyományos eseménykezelő függvényeket, hiszen ezekkel nem tudjuk elkapni azt a pillanatot, amikor a szövegmezőnek küldött üzenet még nem jutott el hozzá, és nem volt feldolgozva. Más módszert kell használnunk.
A kontrolban felülírtuk az ősosztály WndProc virtuális metódusát. A függvény paraméterként az adott vezérlőnek küldött üzenet objektumát tartalmazza, így alkalmas arra, hogy ezt lekérdezzük, szűrjük. Itt van módunk megtenni a szükséges lépéseket annak érdekében, hogy bizonyos karakterek ne jelenhessenek meg a kontrolban, vagyis az ilyen tartalmú üzeneteket el sem juttatjuk a kontrolhoz.
A dolgunkat nehezíti, hogy az adott kontrol többféle üzenetet kaphat, rendszerből küldött üzenetet csakúgy, mint felhasználóit. Meg kell vizsgálnunk, hogy az adott üzenet milyen természetű, és kezelnünk kell, ha az felhasználói üzenet. Amennyiben a felhasználói üzenet a billentyűzetről, vagy egyéb helyről kezdeményezett input, akkor ki kell vennünk az üzenet paraméteréből a küldött karakterkódot, és meg kell vizsgálnunk. Lássunk is neki.
A kontrolban deklaráltunk öt változót, és értéküknek beállítására öt property-t, melyekkel megadhatjuk, hogy az adott karaktertípust engedélyezzük, vagy tiltjuk.
A nagybetűk engedélyezésére:
private bool allowuppers = true;
A kisbetűk ellenőrzésére:
private bool allowlowers = true;
A számjegyek ellenőrzésére:
private bool allowdigits = true;
A szimbólumok ellenőrzésére:
private bool allowsymbols = true;
A vezérlőkarakterek ellenőrzésére:
private bool allowcontrols = true;
A beérkező üzenetek felismeréséhez deklarálnunk kell két konstanst. Egyiket a bevitt billentyűkarakterekhez:
private const int WM_CHAR = 0x0102;
A másikat az egér jobb gombjának lenyomásához, mivel a szöveges beviteli mezők esetén van lehetőség arra, hogy a Vágólapról szövegeket másoljunk a mezőbe, vagy onnan szövegeket másoljunk a Vágólapra.
Kontrolunk szempontjából ennek a ténynek ott van jelentősége, hogy amikor minden típusú karakter bevitele tiltott, ne tudjuk a Vágólapon található, nem megengedett karaktereket sem a szövegmezőbe bevinni.
private const int WM_RBUTTONDOWN = 0x0204;
A WndProc metódusban először létrehozunk egy feltételt, mely akkor igaz, ha a vezérlőkaraktereken kívül valamennyi típusú beviteli karakter engedélyezett. Ez abban fog segíteni, hogy amikor ez nem teljesül, akkor ne tudjunk egeret sem használni a szövegmező fölött:
protected override void WndProc(ref Message message)
{
bool state = (allowuppers && allowlowers && allowdigits && allowsymbols);
Az érkező üzenetnek az Msg nevű property-jét kell lekérdeznünk ahhoz, hogy meghatározzuk, milyen típusú üzenet érkezett. Ha ez a billentyűzetről érkező üzenet, akkor annak WParam property-jéből megtudhatjuk, hogy milyen kód került a billentyűzet-pufferbe:
if(message.Msg == WM_CHAR)
{
char inputChar = (char)message.WParam;
A bevitt kódnak csak akkor lesz hatása, ha el is jut az üzenet a kontrolhoz, vagyis meghívjuk az ősosztály WndProc metódusát. Ezt csak akkor szabad engedélyezni, ha az adott üzenet kódja az engedélyezett kódok közt van, vagyis:
Szám, és a számok engedélyezettek:
if (allowdigits)
{
if (Char.IsDigit(inputChar))
{
base.WndProc(ref message);
}
}
Nagybetűs karakter, és ezek engedélyezettek:
if (allowuppers)
{
if (Char.IsUpper(inputChar))
{
base.WndProc(ref message);
}
}
Kisbetűs karakter, és ezek engedélyezettek:
if (allowlowers)
{
if (Char.IsLower(inputChar))
{
base.WndProc(ref message);
}
}
Szimbólumoknál létrehoztunk egy karakterláncot, melybe beraktuk az összes karaktert. Így ha engedélyezett a szimbólumok használata, meg kell vizsgálni, hogy a karakter benne van-e a láncban:
if (allowsymbols)
{
string validsymbs = "...";
if (validsymbs.IndexOf(inputChar) >= 0)
{
base.WndProc(ref message);
}
}
Kontrolbillentyűknél is megvizsgáljuk, hogy a karakter kontrol-e, valamint hogy eleget tesz-e a következő feltételeknek:
if (allowcontrols)
{
if (Char.IsControl(inputChar))
{
Minden más engedélyezett, és a billentyűkód a TAB, vagy valamely Vágólap-művelet kódja:
if (state && (Convert.ToInt32(inputChar) == 22 || Convert.ToInt32(inputChar) == 8 || Convert.ToInt32(inputChar) == 3 || Convert.ToInt32(inputChar) == 24))
{
base.WndProc(ref message);
}
}
Ha szóköz, vagy ENTER:
if (Char.IsWhiteSpace(inputChar))
{
base.WndProc(ref message);
}
}
Ha azonban az üzenet nem a billentyűzetről jött, hanem az egér jobb gombjának lenyomásakor keletkezett és a fenti feltétel igaz:
if (message.Msg == WM_RBUTTONDOWN && state)
{
base.WndProc(ref message);
}
Minden egyéb esetben, hogy az egyéb üzenetek is célba jussanak:
if (message.Msg != WM_RBUTTONDOWN && message.Msg != WM_CHAR)
{
base.WndProc(ref message);
}
}
Felhasználása előtt a kontrolt fel kell tenni a ToolBox-ra a szokásos módon: kattintsunk a ToolBox valamely lapján az egér jobb gombjával, majd a megjelenő menüből válasszuk ki a Customize ToolBox pontot, a megjelenő ablakban a .NET Frameworks Components fület. A Browse gombbal keressük elő az imént létrehozott .DLL-t.
Felhasználás
A mellékelt Windows-os alkalmazásban a Form-ra feltett kontrolunkba bevihető karakterek típusát lehet egy-egy CheckBox kontrol jelölésével engedélyezni, vagy törlésével tiltani.