Kurz IDE Visual C++ (3.)


V této lekci najdete návod, jak vytvořit aplikaci pro kurz DirectDraw a najdete zde popis okna obsahující ClassView, ResourceView a FileView.

3.1. Projekt pro DirectDraw

Nejdříve si vytvoříme standardní aplikaci podle MFC AppWizardu. Z menu File vyberte New. V dialogu zvolte následující položky:



Na dalším dialogu zvolte volbu Single Document a odškrtněte políčko Document/View architecture support takto:



Na dialogu č. 2 a 3 nechte vše tak jak je. Na dalším, čtvrtém, dialogu odškrtněte všechny políčka takto:



Zbytek Wizardu odklikejte a dokončete projekt.

Rozbalte ClassView a uvidíte všechny vytvořené třídy:



Nyní každou třídu nějakým způsobem upravíme tak, aby vyhovovala našim požadavkům.

  • CAboutDlg
    Poklepejte v ClassView na tuto třídu. V pravém okně se otevře soubor, kde je umístěna jak deklarace tak i implementace. Smažte obojí: deklaraci i implementaci. Třída by vám měla úplně zmizet z ClassView.

  • CChildView
    Přepněte na kartu FileView:



    Označte soubory ChildView.cpp a ChildView.h a smažte je. Třída CChildView vám zmizí z ClassView.

  • CDirectDrawApp
    Nejprve poklepejte na jméno třídy a vymažte z deklarace třídy CDirectDrawApp tento řádek:
    afx_msg void OnAppAbout();

    Pak poklepejte na funkci InitInstance(). Tím se dostanete do souboru DirectDraw.cpp. Najděte Message map na začátku souboru a vymažte následující řádek:
    ON_COMMAND(ID_APP_ABOUT, OnAppAbout)

    Dále přidejte členskou funkci WinInit() a virtuální funkci Run().
    Kliněte pravým tlačítkem na jméno třídy CDirectDrawApp. Rozbalí se vám následující menu:



    Za prvé vyberte položku Add member function.... Následující dialog vyplňte zhruba takto:



    za druhé vyberte položku Add virtual function.... Na dialogu označte funkci Run() a stiskněte tlačítko Add and edit.



    Tím jste přidali dvě členské funkce Run() a WinInit(). Nyní napište tělo funkce WinInit():

    HRESULT CDirectDrawApp::WinInit()
    {
      WNDCLASSEX wc;
      CBrush brBack;
      HWND hWnd = NULL;
      brBack.CreateSolidBrush(RGB(0, 0, 0));
       // Register the Window Class
      wc.cbSize = sizeof(WNDCLASSEX);
      wc.lpszClassName = "DD Class";
      wc.lpfnWndProc = MainWndProc;
      wc.style = CS_VREDRAW | CS_HREDRAW;
      wc.hInstance = m_hInstance;
      wc.hIcon = LoadIcon(IDI_DD);
      wc.hCursor = NULL;
      wc.hbrBackground = brBack;
      wc.lpszMenuName = NULL;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = 0;
      wc.hIconSm = LoadIcon(IDI_DD);
      //register window class
      if( RegisterClassEx( &wc ) != 0 ) {
        m_pMainWnd = new CFrameWnd;
        if(m_pMainWnd->CreateEx(0, "DD Class", "DirectDraw", WS_POPUP,
                                    CRect(0, 0, 800, 600), NULL, NULL)) {
          m_pMainWnd->ShowWindow(SW_SHOW);
          m_pMainWnd->UpdateWindow();
        }
        else {
          return 1;
        }
      }
      else {
        return 1;
      }

      return 0;
    }

    Funkce vrací hodnotu 0, pokud je úspěšná, v opačném případě vrátí 1. Musíte přidat ikonu do zdrojů vašeho projektu. Identifikátor ikony bude IDI_DD a je celkem jedno, jak bude ikona vypadat, protože nebude vidět. Stačí, když přejmenujete stávající ikonu IDR_MAINFRAME.

    Další velice důležitou věcí je deklarace procedury okna. Tato procedura musí být deklarována v hlavičkovém souboru DirectDraw.h takto:
      LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );

    Poté přidejete tělo funkce do implementačního souboru DirectDraw.cpp. Tělo prozatím bude vypadat následovně:
    LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
    {
        return DefWindowProc(hWnd, msg, wParam, lParam);
    }


    Dále upravíme funkci InitInstance(). Už nechceme žádné okno třídy CMainFrame, ale vlastní, které jsme vytvořili ve funkci WinInit(), takže upravte funkci takto:

    BOOL CDirectDrawApp::InitInstance()
    {
      if(0 == WinInit()) {

        return TRUE;
      }

      return FALSE;
    }

    Nakonec smažte řádek:
    #include "MainFrm.h"
    ze souboru DirectDraw.cpp.

  • CMainFrame
    Odstraňte hlavičkový i implemntační soubor této třídy z FileView. Opět tato třída zmizí z ClassView.

Otevřete si Průzkumníka, najděte adresář vašeho projektu a smažte následující soubory: MainFrm.h, MainFrm.cpp, ChildView.h a ChildView.cpp. Nyní spusťtě ClassWizard z menu View. Okno ClassWizardu vypadá takto:



Vyberte třídu CAboutDlg z menu Class name. CW vás upozorní, že třída neexistuje. Stiskněte OK a v následujícím dialogu stiskněte tlačítko Remove. Tak donutíme CW, aby si třídu vymazal ze své databáze.



Tento postup proveďte pro zbývající odstraněné třídy CMainFrame a CChildView. Až vám v menu zbyde pouze třída CDirectDrawApp stiskněte OK.

ClassView by mělo vypadat nějak takto:



Až do teď jsme pouze mazali, od teď už budeme jen přidávat.

Vložte třídu CControl. Z menu Insert zvolte New class.... Objeví se vám následující dialog.



V ClassView se objeví nová třída CControl. Do této třídy přidejte členskou funkci DDInit(). Funkce má následující prototyp:
HRESULT DDInit(HWND hWnd);

Modifikujte tuto funkci dle návodu z druhého kurzu.

Vraťme se ke třídě CDirectDrawApp. Do hlavičkového souboru této třídy vložte hlavičkový soubor control.h a vložte členskou proměnnou m_theControl typu CControl. Funkci InitInstance() pak upravte tak, aby volala funkci DDInit() třídy CControl a inicializovala systém DirectDraw.

Tak a to je vše. Pokud všechny úpravy provedete správně a přidáte kód z druhého kurzu, aplikace půjde spustit. Po spuštění se přepne rozlišení, ale bude vidět pouze bílá plocha okna. Vytvořený projekt si můžete stáhnout v sekci Downloads.

3.2. ClassView, ResourceView a FileView

Jak už název napovídá, jedná se o jakési pohledy na váš projekt. Každý pohled se programátorovi hodí na něco jiného.

  • ClassView pohlíží na váš projekt ze strany objektového programování, protože vidíte třídy, členské funkce a atributy jednotlivých tříd. Tento pohled se hodí pro přístup k jednotlivým funkcím.

  • ResourceView pohlíží na projekt z pohledu zdrojů tzn. ikon, kurzorů nebo bitmap. Důležité je, že tento pohled je možný jen v projektech MFC. Zde můžete přidávat různé zdroje pro váš projekt. Tyto zdroje budou uloženy v budoucím .exe souboru, takže pokud to přeženete, bude i váš program přehnaně velký. Například bitmapy je lepší načítat z externích souborů, protože bývají větší.

  • FileView je často používaným pohledem, protože vám umožní přístup k jednotlivým souborům projektu. FileView je prakticky rozdělen na několik adresářů podle typu souboru. Pokud chcete přidat nebo vyjmout soubor z projektu, můžete to udělat právě pomocí FileView. Ostatní pohledy na změny ve FileView okamžitě reagují.

Nyní si jednotlivé pohledy rozebereme trochu podrobněji.
3.2.1. ClassView

ClassView vypadá nějak takto:



Vidíte třídy CControl a CDirectDrawApp a jejich členské funkce a proměnné. V adresáři Globals jsou globální prvky projektu (funkce i proměnné).

U pohledů často používáme kontextové menu. I ClassView má své kontextové menu, které používáme pro upravu tříd. Vždy upravujete tu třídu, na kterou jste klepli pravým tlačítkem.
Kontextové menu vypadá takto:



  • Go to definition - přejde na deklaraci třídy tzn. ke klíčovému slovu class v hlavičkovém souboru třídy. Stejnou funkci provedete poklepaním na jméno třídy.

  • Add member Function... - přidá členskou funkci do třídy. Zobrazí se tento dialog:



    Vyplníte návratovou hodnotu (Function type), jméno (Function declaration) a přístupové práva funkce (Access). Dále můžete zvolit, zda-li je daná funkce virtualní (virtual) či statická (static). Po stisknutí tlačítka OK se do deklarace třídy přidá deklarace funkce a v implementačním souboru se vytvoří prázdné tělo funkce.

  • Add member Variable... - přidá členskou proměnnou. Princip je stejný jako u funkce.

  • Add virtual Function... - přidá virtuální funkci třídy MFC. Pokud je třída odvozená od nějaké MFC třídy měla by mít tato třída k dispozici tuto volbu pro přidání virtuálních funkcí, které lze takto přetížit.

  • Add Window Message Handler... - přidá obslužnou funkci pro smyčku zpráv. Opět je tato položka přístupná jek pokud pracujete s MFC třídou. Funkce je přidána do třídy (do speciálního bloku v deklaraci třídy), dále je přidán odkaz v Mapě zpráv (Message map) a samozřejmě vytvoří tělo funkce, které většinou obsahuje jeden či dva řádky.

    Ostatní položky jsou pro nás celkem nepodstatné.
Pokud vyvoláte kontextové menu u funkce či proměnné, zjistíte, že není úplně stejné jako u třídy. Například funkci takto můžete smazat, pak je deklarace funkce smazána a tělo funkce je zakomentováno.
3.2.2. ResourceView

ResourceView vypadá nějak takto:



Vidíte všechny zdroje, které používá váš projekt prakticky roztříděné podle typu (např. ikony, bitmapy nebo kurzory). ResourceView umožňuje importovat existujicí soubory nebo vytvářet vlastní. Pokud přidáváte nějaky standardní typ jako třeba soubor .bmp, ResourceView ho automaticky vloží to adresáře Bitmap. Pokud se pokusíte importovat nestandarní zdroj jakým je i zvukový soubor .wav, budete požádáni o vytvoření zcela nového adresáře. V ResourceView mužete zdroje upravovat, ale jen omezeně, protože například interní bitmapový editor nedokáže zobrazit bitmapu, které má více jak 256 barev.

Každému zdroji přiřazujete unikátní (pouze ve vašem projektu) ID čili identifikátor, který je pak používán v programu. Všechny id jsou definovány v souboru resource.h a informace o samotných zdrojích je uložena v souboru s příponou .rc.

Jak už bylo zmíněno výše, ResourceView je dostupný pouze z projektů MFC, jinak se zdroje musí vkládat zvenčí a ručně. Toto je další výhoda MFC. Na druhou stranu vám tento systém může přinést řadu nepříjemností, protože tak můžete snadno a rychle vytvořit výsledný program veliký a tím i pomalý. Doporučuji vkládat do zdrojů pouze soubory malé jako jsou ikony nebo kurzory a zdroje, které jinak vložit nejdou anebo jdou, ale s mnohem větším usilím. Rozhodně bitmapy načítejte z externích souborů.

3.2.3. FileView

FileView vypadá nějak takto:



Vidíte adresář Header Files, který obsahuje hlavičkové soubory vašeho projektu. Dále vidíte adresář Source Files, který obsahuje implementační soubory s příponou .cpp. Adresář Resource Files obsahuje soubory, které souvisí se zdroji (například obsahuje soubor *.rc, který byl popsán výše).

Přes FileView můžete vkládat konkrétní soubory do vašeho projektu. Můžete je samozřejmě mazat či editovat.

Třídy, zdroje a soubory můžete vkládat i přes menu. Třídu vložíte příkazem New Class... z menu Insert. Stejně tak vložíte i zdroj příkazem Resource... z menu Insert. Soubory do projektu vkládáte přes menu Project a Add to project. Zde můžete vložit buďto čisté soubory (New...) anebo soubory vytvořené předem(Files...).

Jiří Formánek