9. Další příklady komponent
  1. 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).

  2. __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);
      }
    }
  3. 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:

  4. 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;
    }
  5. 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

  6. 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();
    }
  7. 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:

  8. 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.
  9. 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.
9. Další příklady komponent