Pomoc pro ztracené programátory - aplikace s uživatelským rozhraním

Přehled informací

Upozornění - k vysvětlení příkladu

Tvorba aplikace s uživatelským rozhraním byla podrobně vysvětlena v kapitole Tvorba uživatelského rozhraní a příkladu Zobrazení dialogového okna reagujícího s AutoCADem, proto následující výklad bude zkrácen jen na nejnutnější informace.

Postup tvorby příkladu

Vytvoření nového projektu

Tvorba dialogového okna

Vytvoření hlavičkového souboru testovaci2.h a vložení potřebných hlavičkových souborů do souboru testovaci2.cpp

  #include "resource.h" // přidání hlavičkového souboru zdrojů
  
  void vytvorDialog();  // deklarace hlavičky funkce 
                        // pro vytvoření dialogu
  #include "AcExtensionModule.h" // rozšíření knihovny MFC
  #include "testDialog.h"        // soubor s třídou dialog
  #include "testovaci2.h"        // deklarace funkcí projektu

Registrace příkazů nové aplikace

  // inicializace aplikace, zaregistrování
  void InitApplication()
  {
    // zaregistrování nového příkazu
    acedRegCmds->addCommand("Skupina_test_dialog", 
        "_createDialog", 
        "spustDialog", 
        ACRX_CMD_MODAL, 
        vytvorDialog,
        NULL,
        -1,
        Testovaci2DLL.ModuleResourceInstance());
    
    // vypsání informaci jak spustit aplikaci
    ads_printf( "\nAplikaci spustíte příkazem\"spustDialog\".\n" );
  }
  // uvolnění aplikace, odregistrování
  void UnloadApplication()
  {
    // odstranění skupiny příkazů
    acedRegCmds->removeGroup("Skupina_test_dialog");  
  }
  // Vyvolání dialogu
  void vytvorDialog()
  {
    // Při nahrání prostředku z této aplikace ARX
    // vytvoří se lokální instance CAcModuleResourceOverride
    CAcModuleResourceOverride resOverride;
    // vytvářený dialog bude typu modalní dialog
    CZadaniDialog dlg(CWnd::FromHandle(adsw_acadMainWnd()));
                        // vytvoření nového dialogu
    dlg.DoModal();      // nahraje a zobrazí dialog jako modální
  }

Vytvoření členských proměnných a funkcí třídy CtestDialog

ID prveku dialogu
Member variable name:
Category:
Variable type:
IDC_BUTTON_BOD1
m_ctrlBod1Tlacitko
Control
CButton
IDC_BUTTON_BOD2
m_ctrlBod2Tlacitko
Control
CButton
IDC_EDIT_BOD1_X
m_ctrlEditBod1X
Control
CEdit
IDC_EDIT_BOD1_Y
m_ctrlEditBod1Y
Control
CEdit
IDC_EDIT_BOD1_Z
m_ctrlEditBod1Z
Control
CEdit
IDC_EDIT_BOD2_X
m_ctrlEditBod2X
Control
CEdit
IDC_EDIT_BOD2_Y
m_ctrlEditBod2Y
Control
CEdit
IDC_EDIT_BOD2_Z
m_ctrlEditBod2Z
Control
CEdit
Původní jméno
Nové jméno
CDialog
CAcUiDialog
CEdit
CAcUiNumericEdit
CButton
CAcUiPickButton
  void ZadejBod1();
  void ZadejBod2();

obě funkce budou veřejné (public),

    CString m_strXBod1;    // pomocná proměnná x-souřadnice Bodu1
    CString m_strYBod1;    // pomocná proměnná y-souřadnice Bodu1
    CString m_strZBod1;    // pomocná proměnná z-souřadnice Bodu1
    CString m_strXBod2;    // pomocná proměnná x-souřadnice Bodu2
    CString m_strYBod2;    // pomocná proměnná y-souřadnice Bodu2
    CString m_strZBod2;    // pomocná proměnná z-souřadnice Bodu2

Vytvoření obslužných funkcí reagujících na zprávy z dialogových prvků

  #include "stdafx.h"
  #include "resource.h"
  #include "testDialog.h"
  #include "testovaci2.h"
  #include <dbents.h>   // podpora databází

Kód jednotlivých členských funkcí třídy CtestDialog

Funkce ZobrazBod1()

Funkce zobrazí v editovacích polích jednotlivé souřadnice středu kružnice. Souřadnice jsou získány z pomocných proměnných typu CString.

  void CtestDialog::ZobrazBod1()
  { 
    // zobrazení hodnoty souřadnic bodu, uložených v proměnných
    m_ctrlEditBod1X.SetWindowText(m_strXBod1);
        m_ctrlEditBod1X.Convert();
    m_ctrlEditBod1Y.SetWindowText(m_strYBod1);
        m_ctrlEditBod1Y.Convert();
    m_ctrlEditBod1Z.SetWindowText(m_strZBod1);
        m_ctrlEditBod1Z.Convert();
  }

Funkce OnInitDialog()

Funkce je vyvolána při inicializaci dialogu. Ve funkci jsou nastaveny rozsahy platných hodnot pro dialogové prvky. V případě překročení rozsahu dojde k jeho opravení na standartní hodnotu. Je-li aplikace vyvolána vícekrát, jsou v ní zobrazeny hodnoty z předešlého vyvolání (hodnoty jsou získány z registrů, kde jsou uloženy). Na konec funkce OnInitDialog jsou zavolány funkce pro zobrazení hodnot v prvcích dialogu (ZobrazBod a ZobrazPolomer).

  BOOL CtestDialog::OnInitDialog() 
  {
    SetDialogName("testovaciDialog:testDialog");
       
    // inicializace dialogu
    CAcUiDialog::OnInitDialog();
    
    // nastavení rozsahu hodnot prvků dialogu
    m_ctrlEditBod1X.SetRange(-5000.0, 5000.0);
    m_ctrlEditBod1Y.SetRange(-5000.0, 5000.0);
    m_ctrlEditBod1Z.SetRange(-5000.0, 5000.0);
    m_ctrlEditBod2X.SetRange(-5000.0, 5000.0);
    m_ctrlEditBod2Y.SetRange(-5000.0, 5000.0);
    m_ctrlEditBod2Z.SetRange(-5000.0, 5000.0);

    // přiřazení titulku dialogu
    SetWindowText("Testovací dialog");

    // získání a zobrazení dat z registrů
    if (!GetDialogData("BOD1X", m_strXBod1))
        m_strXBod1 = "0.0";
    if (!GetDialogData("BOD1Y", m_strYBod1))
        m_strYBod1 = "0.0";
    if (!GetDialogData("BOD1Z", m_strZBod1))
        m_strZBod1 = "0.0";
    if (!GetDialogData("BOD2X", m_strXBod2))
        m_strXBod2 = "1.0";
    if (!GetDialogData("BOD2Y", m_strYBod2))
        m_strYBod2 = "1.0";
    if (!GetDialogData("BOD2Z", m_strZBod2))
        m_strZBod2 = "1.0";

    ZobrazBod1();        // zobrazení hodnot souřadnic
    ZobrazBod2();        // zobrazení hodnot souřadnic
    
    return TRUE;
  }

Funkce OnButtonBod1()

Funkce OnButtonBod je vyvolána při stisknutí tlačítka Zadej Bod. Funkce musí zajistit skrytí dialogu, aby bylo možné pohodlně zadat bod středu kružnice. Skrytí dialogu se uskuteční pomocí tří funkcí:

Je-li funkce vyvolána, je skryt dialog a zavolána funkce pro získání souřadnic bodu. Jsou-li souřadnice zadány vpořádku je dialog znovu ukázán, do pomocných proměnných jsou přiřazeny jednotlivé souřadnice středu a je zavolána funkce pro zobrazení jednotlivých souřadnic v odpovídajících editovacích polích. V opačném případě je příkaz zrušen příkazem CancelEditorCommand().

  void CtestDialog::OnButtonBod1() 
  {
    // skrytí dialogu a předání řízení editoru AutoCAD
    BeginEditorCommand();
    // deklarace proměnné typu bod
    ads_point bod;

    // získání bodu
    if (acedGetPoint(NULL, "\nZadej bod: ", bod) == RTNORM)
    {
      // je-li bod zadán v pořádku dokonči příkaz v editoru
      CompleteEditorCommand();
      m_strXBod1.Format("%g", bod[X]);
      m_strYBod1.Format("%g", bod[Y]);
      m_strZBod1.Format("%g", bod[Z]);
      ZobrazBod1();
    }
    else
    {
      // v opačném případě zruš příkaz
      CancelEditorCommand();
    }
  }

Funkce OnKillfocusEditX()

Funkce je vyvolána při změně v editovacím poli x-ové souřadnice. Funkce nejprve přečte hodnotu z textového pole, následně ji zkontroluje, zda je zadaná hodnota platná. Pokud je zadaná hodnota mimo rozsah, hodnota je opravena na inicializační hodnotu, která je poté znovu zobrazena.

  void CtestDialog::OnKillfocusEditBod1X() 
  {
    // získání hodnoty z textového pole
    m_ctrlEditBod1X.Convert();
    m_ctrlEditBod1X.GetWindowText(m_strXBod1);
    // kontrola správnosti zadané hodnoty a případná oprava
    if (!m_ctrlEditBod1X.Validate())
    {
      m_strXBod1 = "1";
      ZobrazBod1();
    }	
  }

Funkce OnOk()

Funkce je vyvolání při zmáčknutí tlačítka Vložit. Po jejím vyvolání jsou nejprve hodnoty z editovacích polí uloženy do registrů pomocí funkce SetDialogData(). Dále jsou ve funkci vytvořeny tři pomocné proměnné:

Do proměnné střed přiřadíme jednotlivé souřadnice středu z proměnných m_strXBod, m_strYBod, m_strZBod. Hodnoty musíme převést z typu řetězec na typ reálné číslo. Do proměnné polomer převedeme hodnotu poloměru z proměnné m_strPolomer.

Následuje blok kódu, v kterém přidáme do modelového prostoru výkresu novou entitu typu kružnice. Nejprve si vytvoříme nový objekt kružnice. Otestujeme zda je nový objekt vytvořený.

Dále si musíme vytvořit proměnné pro ukazatele na tabulku bloků, na záznam tabulky bloků a proměnou pro uložení ID objektu kružnice. Poté musíme otevřít tabulku bloků výkresu pro čtení. Pomocí tabulky bloků otevřeme záznam modelový prostor a uložíme si ukazatel na něj. Jakmile máme ukazatel na modelový prostor můžeme zavřít tabulku bloků. Do modelového prostoru přidáme novou kružnici a uložíme si ukazatel na ni. Zavřeme záznam modelový prostor. Zavřeme objekt kružnice.

  void CtestDialog::OnOK() 
  {
    CAcUiDialog::OnOK();

    // uložení dat z dialogu do registrů
    SetDialogData("BOD1X", m_strXBod1);
    SetDialogData("BOD1Y", m_strYBod1);
    SetDialogData("BOD1Z", m_strZBod1);
    SetDialogData("BOD2X", m_strXBod2);
    SetDialogData("BOD2Y", m_strYBod2);
    SetDialogData("BOD2Z", m_strZBod2);

    AcGePoint3d bod1;  // počáteční bod
    AcGePoint3d bod2;  // koncový bod

    acdbDisToF(m_strXBod1, 2, &bod1[X]);
        // převedení řetězce z dialogového prvku na číslo
    acdbDisToF(m_strYBod1, 2, &bod1[Y]);
        // převedení řetězce z dialogového prvku na číslo
    acdbDisToF(m_strZBod1, 2, &bod1[Z]);
        // převedení řetězce z dialogového prvku na číslo
    acdbDisToF(m_strXBod2, 2, &bod2[X]);
        // převedení řetězce z dialogového prvku na číslo
    acdbDisToF(m_strYBod2, 2, &bod2[Y]);
        // převedení řetězce z dialogového prvku na číslo
    acdbDisToF(m_strZBod2, 2, &bod2[Z]);
        // převedení řetězce z dialogového prvku na číslo

    // vytvoření nové kružnice
    AcDbLine* pCara = new AcDbLine(bod1, bod2);

    if (!pCara)
    {
      acedAlert("Málo paměti pro vytvoření čáry!");
    }

    AcDbBlockTable *pBlockTable;
        // vytvoření ukazatele na objekt AcDbBlockTable
    AcDbBlockTableRecord *pZaznamBlockTable;
        // vytvoření ukazatele na objekt AcDbBlockTableRecord
    AcDbObjectId IDCara;    
        // vytvoření proměnné pro uchování ID čáry

    acdbHostApplicationServices()->workingDatabase()
        ->getBlockTable(pBlockTable, AcDb::kForRead);
        // otevření tabulky bloků výkresu pro čtení a 
        // předání ukazatele na ní

    pBlockTable->getAt(ACDB_MODEL_SPACE, 
                       pZaznamBlockTable, AcDb::kForWrite);
        // otevření záznamu tabulky bloků výkresu pro zápis
        //  a předání ukazatele na ní
    pBlockTable->close();       // zavření tabulky bloků

    pZaznamBlockTable->appendAcDbEntity(IDCara, pCara);
        // přidání entity čára do modelového prostoru

    pZaznamBlockTable->close();
                             // uzavření modelového prostoru
    pCara->close();          // uzavření objektu čára
  }

Zdrojový kód projektu

Zdrojový kód projektu je možné nahrát v zabaleném souboru testovaci2.zip. Nahraný kód musíte rozbalit a ve vývojovém prostředí Visual C++ otevřít soubor pracovního prostoru nebo projektu (testovaci2.dsw nebo testovací2.dsp). Visual C++ poté načte celý projekt.

Doporučujeme Vám vyzkoušet si alespoň tvorbu projektu pomocí pomocníka a napsání několika řádek kódu, abyste poznali vývojové pomůcky prostředí Visual C++.