Grafikus C# – Windows Forms tanfolyam › 2.7 lecke Windows Forms · 2.7 lecke · haladó A RichTextBox balra, középre és jobbra tud igazítani, de sorkizártat nem, pedig a Wordben ez az egyik leggyakrabban használt igazítás. A megoldáshoz le kell nyúlnunk a Windows saját szövegszerkesztő komponenséhez. Ez haladó téma, ezért kész segédosztályt használunk, és közben megértjük, mit csinál.Sorkizárt igazítás: a RichTextBox korlátja és a megoldás

A lecke végére
- érted, miért hiányzik a sorkizárt a RichTextBoxból;
- ismered a Windows üzenetküldés (
SendMessage), a DLL és aDllImportalapgondolatát; - beépíted a projektbe a kész
RichTextBoxHelpersegédosztályt; - egy gombbal sorkizártra állítod a bekezdéseket;
- megoldod, hogy a megnyitott sorkizárt dokumentum is helyesen jelenjen meg;
- ellenőrzöd az eredményt mentés, újranyitás és Word segítségével.
Mielőtt elkezded
Ehhez a leckéhez kell a három igazítógomb a 2.6 lecke után. Nem kell mindent érteni a kódból: a segédosztályt kimásolhatod, de a leckében lépésről lépésre elmagyarázzuk.
Miért hiányzik a sorkizárt?
A Windows Forms RichTextBox valójában a Windows saját RichEdit szerkesztő vezérlőjét csomagolja be. A RichEdit tud sorkizártat, de a .NET csak a legfontosabb funkciókat tette elérhetővé: a HorizontalAlignment felsorolásban ezért csak három érték van. A hiányzó részeket közvetlenül a Windowstól kell kérnünk.
Jósolj!
Mit gondolsz: ha a Wordben sorkizárttal elmentett RTF fájlt nyitsz meg a MiniWordben, az igazítás megmarad a fájlban, vagy elveszik?
Jóslat ellenőrzése
Az RTF fájlban az igazítás ott van, a RichEdit pedig kezelni is tudja. Hogy a MiniWord helyesen megjelenítse, az ehhez szükséges beállítást a Windowstól kell kérni. Ezt a lecke 4. szakasza mutatja meg.
Négy fogalom, amit most kell ismerned
A Windowsban minden ablak és vezérlő üzeneteket kap, amelyeket a rendszer küld. Mi most egy ilyen üzenetet fogunk küldeni a szövegdobozunknak: „állítsd sorkizártra ezt a bekezdést”.
EM_SETPARAFORMAT.user32.dll). A DllImport segítségével a C# kódunk meg tudja hívni a függvényeit.rtbDokumentum.Handle megmondja, melyik ablaknak címezzük az üzenetet.Nem kell mindent megjegyezned
Ez a technika az ablakos programozás haladó témája. A feladathoz elég, ha a segédosztályt beépíted, és tudod, mit csinál. A részleteket a lecke végén, a „Mélyebben” szakaszban találod.
A segédosztály beépítése
A Windows hívását egy külön osztályba tesszük, hogy a Form1 kódja áttekinthető maradjon.
- A Solution Explorerben kattints jobb gombbal a projektre, és válaszd az Add → Class lehetőséget.
- A fájl neve legyen
RichTextBoxHelper.cs, majd kattints az Add gombra. - Töröld ki a fájl teljes tartalmát, és másold be az alábbi kódot.
Mit tegyél ide: az „Add New Item” ablak, amelyben a Class elem és a RichTextBoxHelper.cs fájlnév látszik. Mellette a Solution Explorer, benne az új fájllal.Javasolt fájlnév: winforms-2-7-add-class.webp · Alt szöveg: Új osztály hozzáadása a projekthez a Visual Studióban
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public static class RichTextBoxHelper
{
private const int EM_SETPARAFORMAT = 0x447;
private const int EM_SETTYPOGRAPHYOPTIONS = 0x4CA;
private const int TO_ADVANCEDTYPOGRAPHY = 1;
private const int PFM_ALIGNMENT = 8;
private const int PFA_JUSTIFY = 4;
[StructLayout(LayoutKind.Sequential)]
private struct PARAFORMAT2
{
public int cbSize;
public uint dwMask;
public short wNumbering;
public short wReserved;
public int dxStartIndent;
public int dxRightIndent;
public int dxOffset;
public short wAlignment;
public short cTabCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public int[] rgxTabs;
public int dySpaceBefore;
public int dySpaceAfter;
public int dyLineSpacing;
public short sStyle;
public byte bLineSpacingRule;
public byte bOutlineLevel;
public short wShadingWeight;
public short wShadingStyle;
public short wNumberingStart;
public short wNumberingStyle;
public short wNumberingTab;
public short wBorderSpace;
public short wBorderWidth;
public short wBorders;
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, ref PARAFORMAT2 lParam);
// Bekapcsolja a speciális szövegmegjelenítést (ez kell a sorkizárthoz).
public static void EngedelyezSorkizartot(RichTextBox rtb)
{
SendMessage(rtb.Handle, EM_SETTYPOGRAPHYOPTIONS, (IntPtr)TO_ADVANCEDTYPOGRAPHY, (IntPtr)TO_ADVANCEDTYPOGRAPHY);
}
// Sorkizártra állítja a kijelölt bekezdéseket.
public static void Sorkizart(RichTextBox rtb)
{
EngedelyezSorkizartot(rtb);
PARAFORMAT2 pf = new PARAFORMAT2();
pf.cbSize = Marshal.SizeOf(pf);
pf.dwMask = PFM_ALIGNMENT;
pf.wAlignment = PFA_JUSTIFY;
pf.rgxTabs = new int[32];
SendMessage(rtb.Handle, EM_SETPARAFORMAT, IntPtr.Zero, ref pf);
}
}Pontosan másold át!
Ebben a kódban minden szám és név számít: a kisbetű-nagybetű, a mezők sorrendje és a számértékek is. Egyetlen elírás esetén a Windows nem szól, hanem egyszerűen nem történik semmi. Ha a kódot átgépeled, ellenőrizd vissza minden sort.
A gomb és a Load esemény
Tegyél a formázó sorba egy btnSorkizart nevű gombot Sorkizárt felirattal. Az eseménykezelője egyetlen sor:
private void btnSorkizart_Click(object sender, EventArgs e)
{
RichTextBoxHelper.Sorkizart(rtbDokumentum);
rtbDokumentum.Focus();
}
private void Form1_Load(object sender, EventArgs e)
{
RichTextBoxHelper.EngedelyezSorkizartot(rtbDokumentum);
}A Mit tegyél ide: a MiniWord egy hosszabb, több soros bekezdéssel, amely sorkizárt: a sorok jobb széle is egyenes. Fent látszik a Sorkizárt gomb.Javasolt fájlnév: winforms-2-7-sorkizart.webp · Alt szöveg: A MiniWord egy sorkizártra igazított bekezdésselForm1_Load eseménykezelő létrehozását a 0.8 leckében tanultad (dupla kattintás az ablak üres részére).
Próbáld ki alaposan
- Írj vagy másolj be egy hosszabb szöveget (legalább 4–5 sorosat) Enter nélkül, és kattints a Sorkizárt gombra. A sorok mindkét széle egyenes lesz, de az utolsó sor nem nyúlik, mert az a bekezdés vége.
- Kattints a Balra gombra: a bekezdés visszaáll balra igazítottra. A sorkizárt tehát a többi igazítással váltogatható.
- Mentsd el RTF fájlként, zárd be a programot, majd nyisd meg újra a fájlt. A sorkizárt megmarad.
- Nyisd meg a mentett fájlt a Wordben is, és vesd össze a két megjelenést.
- Készíts a Wordben egy sorkizárt dokumentumot, mentsd RTF-ként, és nyisd meg a MiniWordben.
Mit tegyél ide: két egymás melletti kép ugyanarról a bekezdésről: bal oldalon a MiniWord, jobb oldalon a Word. Mindkettőben sorkizárt, azonos tördelés látszik.Javasolt fájlnév: winforms-2-7-miniword-es-word.webp · Alt szöveg: Ugyanaz a sorkizárt bekezdés a MiniWordben és a Wordben
Megvan a négy igazítás
A MiniWord mostantól balra, középre, jobbra és sorkizártra is tud igazítani, ahogy a Word.
Mélyebben: mit csinál a kód?
Ez a szakasz opcionális. Ha érdekel, mit jelentenek a kódban a számok és a nevek, nyisd le a magyarázatot: A Az egyik egyszerű számokat küld (a speciális megjelenítés bekapcsolására), a másik egy A konstansok jelentése
Név Szerepe EM_SETPARAFORMATAz üzenet száma, amely azt kéri a szövegdoboztól, hogy állítsa be a kijelölt bekezdés formátumát. PFM_ALIGNMENTMegmondja, hogy a bekezdés formátumából csak az igazítást szeretnénk beállítani, mást nem. PFA_JUSTIFYAz igazítás értéke: a 4 jelenti a sorkizártat. (A balra a 1, a jobbra a 2, a középre a 3.) EM_SETTYPOGRAPHYOPTIONSAz az üzenet, amellyel a speciális szövegmegjelenítést kapcsoljuk be. TO_ADVANCEDTYPOGRAPHYA kapcsoló értéke: a sorkizárt megjelenítéséhez ez kell. A PARAFORMAT2 struktúra
PARAFORMAT2 egy adatcsomag (struct), amelyben a bekezdés összes formázási beállítása benne van: behúzás, igazítás, térköz, szegély és így tovább. A Windows pontosan ezt a szerkezetet várja, ezért kell a mezőket ugyanabban a sorrendben megadni. A kódban csak az cbSize (a csomag mérete), a dwMask (melyik mezők érvényesek) és a wAlignment (az igazítás) mezőt állítjuk be.Miért van két SendMessage?
PARAFORMAT2 csomagot (az igazítás beállítására). A C# két külön deklarációt kér, mert az üzenetek paraméterei eltérő típusúak.
Hibakeresés: te vagy a hibadetektív
Mi a baj, és hogyan javítod?
Gondold végig az okot, és csak utána nyisd le a megoldást.
1. Nem ismeri a StructLayout-ot
// CS0246: The type or namespace name 'StructLayout' could not be foundOk és javítás
Fordítási hiba: hiányzik a using System.Runtime.InteropServices; sor a fájl elejéről. Ebben a névtérben van a StructLayout, a DllImport és a Marshal.
2. Nem történik semmi
A gombra kattintasz, de a bekezdés nem változik. Lehetséges okok: elgépelt szám vagy mező a segédosztályban, vagy a bekezdés egyetlen rövid sor, amelyben a sorkizárt nem látható. Írj be egy hosszabb, több soros bekezdést, és ellenőrizd a kódot a leckében szereplő mintával.Ok és javítás
3. Az utolsó sor nem kitöltött
A sorkizárt bekezdés utolsó sora nem ér el a jobb szélig. Ez helyes viselkedés: a sorkizártnál a bekezdés utolsó sora balra igazított marad, mint a Wordben is.Ok és javítás
4. Nem ismeri a RichTextBoxHelper osztályt
// CS0103: The name 'RichTextBoxHelper' does not exist in the current contextOk és javítás
A segédosztály fájlját nem adtad hozzá a projekthez, vagy az osztály neve eltér a fájlban. Ellenőrizd a Solution Explorerben, hogy a RichTextBoxHelper.cs a projekt része-e, és hogy az osztály neve pontosan RichTextBoxHelper.
5. A megnyitott sorkizárt fájl nem sorkizárt
Egy Wordben sorkizártra állított RTF fájlt nyitsz meg, de a sorok jobb széle egyenetlen. Valószínűleg nem fut le a Ok és javítás
RichTextBoxHelper.EngedelyezSorkizartot(rtbDokumentum); hívás a Form1_Load eseményben. Ellenőrizd, hogy az eseménykezelő létrejött-e és össze van-e kötve az ablak Load eseményével (0.8 lecke).
Mini projekt: négy igazítás a MiniWordben
Állítsd össze a teljes igazító sort:
- Gombok:
btnBalra,btnKozep,btnJobbra,btnSorkizart. - A
RichTextBoxHelper.csfájl a projektben van. - A
Form1_Loadbekapcsolja a speciális megjelenítést. - Írj egy dokumentumot, amelyben mind a négy igazítás szerepel.
- Mentsd el RTF fájlként, nyisd meg újra, és nézd meg a Wordben is.
Ha ez mind működik, a MiniWord szövegformázási része kész a feladat összes pontjához.
Önálló gyakorlófeladatok
Először készíts saját megoldást. A lenyitható rész csak ellenőrzéshez van.
1. Üres dokumentum
Ha a dokumentum üres, a Sorkizárt gomb jelezzen, hogy nincs mit igazítani.Egy lehetséges megoldás
private void btnSorkizart_Click(object sender, EventArgs e)
{
if (rtbDokumentum.Text.Length == 0)
{
MessageBox.Show("Nincs mit igazítani, a dokumentum üres.");
}
else
{
RichTextBoxHelper.Sorkizart(rtbDokumentum);
}
rtbDokumentum.Focus();
}
2. A megnyitott dokumentum
Készíts a Wordben egy sorkizárt RTF dokumentumot, nyisd meg a MiniWordben, és ellenőrizd, hogy a Load beállítás nélkül és vele is hogyan jelenik meg. A Load beállítás nélkül előfordulhat, hogy a megnyitott dokumentum sorkizárása nem látszik, amíg egyszer meg nem nyomod a Sorkizárt gombot. A Load beállítással a megnyitás után azonnal helyesen jelenik meg. Próbáld ki mindkettőt a saját gépeden.Mit tapasztalhatsz?
3. Magyarázd el!
Írd le öt-hat mondatban a saját szavaiddal, mit csinál a A metódus egy üzenetet küld a szövegdoboznak a Windows Sorkizart() metódus: kinek küld üzenetet, mit kér, és miért kellett ehhez a Windows saját függvényét használni.Egy lehetséges válasz
SendMessage függvényével. Az üzenet azt kéri, hogy a kijelölt bekezdés igazítása legyen sorkizárt. Ezt azért kellett így megoldani, mert a .NET RichTextBox SelectionAlignment tulajdonsága nem ismeri a sorkizártat, a mögötte lévő Windows komponens viszont igen.
Gyakorlótár: 6 további feladat
Három szinten gyakorolhatsz: alap, közepes és kihívás. A feladatok a lecke RichTextBoxHelper osztályát használják, ezért előbb másold be a projektbe. Csak a próbálkozás után nyisd le a megoldást.
Alap szint
1. Miért nincs Justify?
A A SelectionAlignment tulajdonságnak a HorizontalAlignment felsorolás értékeit adhatod. Milyen értékeket ismer, és mit jelent ez a sorkizárt igazításra nézve?Megoldás megnyitása
HorizontalAlignment csak három értéket ismer: Left, Center, Right. A sorkizárt (Justify) nincs közöttük, ezért a SelectionAlignment segítségével nem érhető el. A sorkizárt igazítást a RichEdit komponens saját üzenetével kell kérni, ezt végzi el a lecke segédosztálya.
2. Hol engedélyezed?
A lecke szerint a sorkizárt használata előtt egy engedélyező hívás szükséges. Melyik eseménykezelőbe teszed, és miért oda? A Megoldás megnyitása
Form1_Load eseménybe, mert az az ablak megjelenése előtt egyszer fut le, így a RichTextBox már a használat előtt fel van készítve. Ugyanez a szabály más egyszeri beállításokra is igaz.private void Form1_Load(object sender, EventArgs e)
{
RichTextBoxHelper.EngedelyezSorkizartot(rtbDokumentum);
}
Közepes szint
3. Sorkizárt gomb
A A btnSorkizart gomb állítsa sorkizártra a kurzor bekezdését, és a fókuszt adja vissza a szövegdoboznak.Megoldás megnyitása
Focus() azért fontos, mert a gomb megnyomása elvenné a billentyűzet fókuszát a szövegdoboztól, és a felhasználónak újra bele kellene kattintania.private void btnSorkizart_Click(object sender, EventArgs e)
{
RichTextBoxHelper.Sorkizart(rtbDokumentum);
rtbDokumentum.Focus();
}
4. Az egész dokumentum sorkizártra
Egy A segédosztály a kijelölt bekezdésekre hat, ezért előbb mindent kijelölünk. Utána megszüntetjük a kijelölést.btnMindSorkizart gomb állítsa az egész dokumentumot sorkizártra, majd a kurzor kerüljön a szöveg elejére.Megoldás megnyitása
private void btnMindSorkizart_Click(object sender, EventArgs e)
{
rtbDokumentum.SelectAll();
RichTextBoxHelper.Sorkizart(rtbDokumentum);
rtbDokumentum.Select(0, 0);
rtbDokumentum.Focus();
}
Kihívás szint
5. Négy igazító gomb közös kóddal
A balra, középre, jobbra és sorkizárt gomb használjon egy közös, A három hagyományos igazítás a Igazit nevű metódust, amely a fókuszt is visszaadja a szövegdoboznak.Megoldás megnyitása
SelectionAlignment tulajdonságot állítja, a sorkizárt a segédosztályt hívja. A közös rész (a fókusz visszaadása) külön metódusba kerül, hogy ne ismétlődjön.private void Igazit(HorizontalAlignment igazitas)
{
rtbDokumentum.SelectionAlignment = igazitas;
rtbDokumentum.Focus();
}
private void btnBalra_Click(object sender, EventArgs e) { Igazit(HorizontalAlignment.Left); }
private void btnKozep_Click(object sender, EventArgs e) { Igazit(HorizontalAlignment.Center); }
private void btnJobbra_Click(object sender, EventArgs e) { Igazit(HorizontalAlignment.Right); }
private void btnSorkizart_Click(object sender, EventArgs e)
{
RichTextBoxHelper.Sorkizart(rtbDokumentum);
rtbDokumentum.Focus();
}
6. Tesztterv a sorkizárthoz
Írj tesztet (lépésenként), amellyel megbizonyosodsz arról, hogy a sorkizárt működik. Mit kell látnod? (1) Írj be vagy illessz be egy hosszú, többsoros bekezdést (legalább 5–6 sor). (2) Tedd a kurzort a bekezdésbe, és kattints a Sorkizárt gombra. (3) Elvárt: a bekezdés sorai a bal és a jobb szélen is egyenesek, a szóközök szélesebbek. A bekezdés utolsó sora nem nyúlik ki a jobb szélig, mert az mindig balra igazított marad. (4) Húzd szélesebbre vagy keskenyebbre az ablakot: a sorok újratördelődnek, de a két szél egyenes marad. (5) Kattints a Balra gombra: a jobb szél újra szabálytalan lesz. (6) Mentsd RTF-be, nyisd meg újra, és nézd meg, hogy a sorkizárt megmaradt-e. Ha valamelyik lépésnél más történik, a hibát jegyezd fel pontosan.Megoldás megnyitása
Gyors önellenőrzés
Válaszolj fejben, és csak utána nyisd le a választ. Mert a Üzenetet küld egy ablaknak vagy vezérlőnek a Windowsban. Segítségével a C# kód meghívhat egy DLL-ben (például a user32.dll-ben) lévő Windows függvényt. Az ablak azonosítója a Windowsban: ez alapján tudja a rendszer, melyik ablaknak szól az üzenet. Hogy a speciális megjelenítés már az ablak betöltésekor be legyen kapcsolva, így a megnyitott sorkizárt dokumentum is helyesen jelenik meg. Mert a sorkizárt igazítás minden sorra érvényes, kivéve a bekezdés utolsó sorát. A Wordben is így van.1. Miért nem lehet a SelectionAlignment tulajdonsággal sorkizártat beállítani?
HorizontalAlignment felsorolásnak nincs sorkizárt eleme, a .NET nem teszi elérhetővé a RichEdit komponens ezen képességét.2. Mit csinál a SendMessage?
3. Mire való a DllImport?
4. Mi a Handle?
5. Miért kell a Form1_Load eseménybe a EngedelyezSorkizartot hívás?
6. Miért marad balra igazított a sorkizárt bekezdés utolsó sora?
Mit tudsz már?
- Érted, miért hiányzik a sorkizárt a RichTextBoxból.
- Ismered az üzenet, a SendMessage, a DLL és a Handle fogalmát.
- Beépítetted a RichTextBoxHelper segédosztályt.
- Sorkizártra állítasz egy gombbal.
- A megnyitott sorkizárt dokumentum is helyesen jelenik meg.
- A MiniWord mind a négy igazítást tudja.
Következő lecke: szövegkeresés és találatok kiemelése
A formázás kész. A következő leckében a MiniWord megtanul keresni a szövegben, és az összes találatot kiemeli.





