Budeme pokračovat ve vývoji komponenty z předchozí kapitoly a umožníme
editovat připojenou datovou položku. Protože se jedná o editační ovladač
musíme implicitně nastavit jeho vlastnost ReadOnly na false
(v konstruktoru i v definici vlastnosti).
__fastcall TDBCalendar::TDBCalendar (TComponent*
Owner) : TSampleCalendar(Owner) { FReadOnly = false;
// set the default value ... } Nás ovladač musí reagovat na zprávy Windows týkající se myši (WM_LBUTTONDOWN,
WM_MBUTTONDOWN a WM_RBUTTONDOWN) a zprávy klávesnice (WM_KEYDOWN). K umožnění,
aby ovladač reagoval na tyto zprávy, musíme zapsat obsluhy reagující na
tyto zprávy.
Chráněná metoda MouseDown je metoda pro událost ovladače OnMouseDown.
Ovladač sám volá MouseDown v reakci na zprávu stisknutí tlačítka
myši od Windows. Když přepisujeme zděděnou metodu MouseDown, můžeme
vložit kód, který poskytuje ostatní reakce voláním události OnMouseDown.
Do třídy TDBCalendar přidáme metodu MouseDown:
class PACKAGE TDBCalendar : public TSampleCalendar { protected: virtual void __fastcall MouseDown(TMouseButton
Button,
TShiftState Shift, int X, int Y); }; a do souboru CPP tuto metodu zapíšeme:
void __fastcall TDBCalendar::MouseDown(TMouseButton
Button,
TShiftState Shift, int X, int Y) { TMouseEvent MyMouseDown; if (!FReadOnly && FDataLink->Edit()) TSampleCalendar::MouseDown(Button,
Shift, X, Y); else { MyMouseDown = OnMouseDown; if (MyMouseDown != NULL)
MyMouseDown(this, Button, Shift, X, Y); } } Když MouseDown reaguje na zprávu myši, pak zděděná metoda MouseDown
je volána pouze, jestliže vlastnost ReadOnly ovladače je nastavena
na false a jestliže objekt datového spoje je v editačním režimu
(položka může být editována). Jestliže položka nemůže být editována, pak
je provedena obsluha události OnMouseDown (existuje-li).
Metoda KeyDown je chráněná metoda pro událost OnKeyDown
ovladače. Ovladač sám volá KeyDown v reakci na zprávu stisknutí
klávesy od Windows. Obdobně jako MouseDown přepíšeme i KeyDown:
class PACKAGE TDBCalendar : public TSampleCalendar { protected: virtual void __fastcall KeyDown(unsigned
short &Key,TShiftState Shift); }; Zapíšeme metodu KeyDown do souboru CPP:
void __fastcall TDBCalendar::KeyDown(unsigned
short &Key,TShiftState Shift) { TKeyEvent MyKeyDown; Set<unsigned short, 0, 8> keySet; keySet = keySet << VK_UP <<
VK_DOWN << VK_LEFT << VK_RIGHT << VK_END <<
VK_HOME << VK_PRIOR << VK_NEXT; if (!FReadOnly && (keySet.Contains(Key))
&& FDataLink->Edit()) TCustomGrid::KeyDown(Key,
Shift); else { MyKeyDown = OnKeyDown; if (MyKeyDown != NULL)
MyKeyDown(this, Key, Shift); } }
Jsou dva typy datových změn: změna v hodnotě položky, která musí být zohledněna
v ovladači a změna v ovladači, která musí být provedena v datové položce.
Komponenta TDBCalendar má metodu DataChange, která zpracovává
změny v hodnotě položky a tak první typ změn je již ošetřen. Třída položky
datového spoje má událost OnUpdateData, která nastane, když uživatel
modifikuje obsah ovladače. Ovladač kalendáře má metodu UpdateData,
kterou můžeme použít k obsloužení této události. Přidáme tedy metodu UpdateData
do deklarace třídy formuláře:
class PACKAGE TDBCalendar : public TSampleCalendar { private: void __fastcall UpdateData(TObject
*Sender); }; do souboru CPP zapíšeme metodu UpdateData:
void __fastcall TDBCalendar::UpdateData(TObject
*Sender) { FDataLink->Field->AsDateTime = CalendarDate; } a v konstruktoru TDBCalendar přiřadíme metodu UpdateData
události OnUpdateData __fastcall TDBCalendar::TDBCalendar(TComponent*
Owner) : TSampleCalendar(Owner) { FDataLink = new TFieldDataLink(); FDataLink->OnDataChange = DataChange; FDataLink->OnUpdateData = UpdateData; }
Když je nastavena nová hodnota, pak je volána metoda Change ovladače
kalendáře.
Change volá obsluhu události OnChange (pokud existuje). Uživatel
komponenty může zapsat kód obsluhy události OnChange k reagování
na změnu datumu. Musíme tedy přidat novou metodu Change do komponenty
TDBCalendar
class TDBCalendar : public TSampleCalendar { protected: virtual void __fastcall Change(); }; a zapsat metodu Change, volající metodu Modified, která
informuje datový spoj, že datum bylo změněno a potom volá zděděnou metodu
Change:
void __fastcall TDBCalendar::Change() { if (FDataLink != NULL) FDataLink->Modified(); TSampleCalendar::Change(); }
Posledním krokem při vytváření editovatelného ovladače je aktualizace datového
spoje na novou hodnotu. To nastává, když změníme hodnotu v ovladači a ovladač
opustíme (klinutím mimo ovladač nebo stiskem klávesy Tab). VCL má definovány
zprávy pro operace s ovladačem. Např. zpráva CM_EXIT je zaslána, když uživatel
ovladač opustí. Můžeme zapsat obsluhu zprávy, která na zprávu bude reagovat.
V našem případě, když uživatel opustí ovladač, metoda CMExit (obsluha
zprávy pro CM_EXIT) reaguje aktualizací záznamu v datovém spoji na změněnou
hodnotu. Do komponenty přidáme obsluhu zprávy:
class PACKAGE TDBCalendar : public TSampleCalendar { private: void __fastcall CMExit(TWMNoParams
&Message); BEGIN_MESSAGE_MAP MESSAGE_HANDLER(CM_EXIT, TWMNoParams,
CMExit) END_MESSAGE_MAP(TSampleCalendar) }; a do souboru CPP zapíšeme:
void __fastcall TDBCalendar::CMExit(TWMNoParams
& Message) { try { FDataLink->UpdateRecord(); } catch(...) { SetFocus(); throw; } } Tím je vývoj editovatelné komponenty hotov.
Pokud se chcete s vytvářením komponent dále seznamovat, pak si můžete stáhnout
tento
soubor. Obsahuje zdrojové kódy několika komponent. Jedná se o komponenty,
které jsou nainstalované na stránce Sample Palety komponent. Můžete
se v nich seznámit s registrací ovladače, implementací editoru vlastnosti
a registrací editoru vlastnosti.