|
KoncepceProgram FR4.exe (jádro) obsahuje všechny nezbytné části zajišťující připojení a obsluhu přídavných DLL modulů (tzv. plug-ins), jednotný souborový systém (nazývaný též projekt) pro všechny moduly, systém globálních parametrů a podporu grafiky. Modulární uspořádání umožňuje konfigurovat program FR4 dynamicky pomocí popisu konfigurace v souboru FR4.ini (adresář WINDOWS). Společný systém správy souborů (a dynamických polí) prováděný jádrem FR4 umožňuje, aby jednotlivé moduly byly volány v libovolném pořadí. Společná data pak slouží ke vzájemné komunikaci mezi moduly a k uchování postupu řešení problému. Při zastavení programu jsou soubory uloženy na disk a dynamická pole automaticky zrušena. Další společnou datovou částí jádra jsou globální parametry, které mohou být čteny i zapisovány ze všech modulů a slouží k jednoduché komunikaci mezi moduly i definování stavových podmínek modulů, případně i k evidenci postupu prací. Popis globálních parametrů, které se váží na práci programu, je ukládán do souboru FR4.fpr. Parametry související jen s projektem pak do souboru project.fr4. V první sekci souboru project.fr4 nazvané "Project parameters" jsou uloženy parametry související s konkrétním projektem. Ve druhé sekci souboru, nazvané "Files", jsou pak popisy všech souborů projektu. Popisy i všechny soubory (tj. kompletní projekt) jsou po zastavení programu uloženy do jednoho souboru s příponou fpr. Podpora grafiky spočívá v možnosti generovat grafické entity do zvolených
stránek (obrazovek). Obrazovky se zobrazují v hlavním okně programu se záložkami,
které umožňují snadné přepínaní obrazovek. Ke každé obrazovce existuje datová struktura
v paměti, která obsah obrazovky popisuje. Popis je členěn do vrstev, se kterými lze dále
pracovat jako s daty (lze je např. editovat 2D grafickým editorem). Podporován je dále
dvojí systém 3D zobrazování. Jeden využívá tzv. generačních funkcí v modulech,
druhý pak obdobný postup s podporou 3D grafiky OpenGL.
|
Konfigurování FR4 - modularita modulůDLL modul může obsahovat značné množství relativně samostatných funkcí, které lze volat přímo, nebo z jiných DLL prostřednictvím zabudovaného mechanizmu volání přes funkce jádra FR4.S výhodou lze použít tzv. aliasy. V modulu, ve kterém potřebujeme volat nějakou "externí" funkci (může to být celý samostatný dialog např. pro definování nějakých konstant) použijeme náhradní název (alias) a k přiřazení konkrétní funkce použijeme konfigurační funkci pro správu DLL z modulu sysl.dll. Např. pro převod obrazovky do souboru v DXF formátu použijeme alias "dxfout" ve všech voláních externí funkce s tímto účelem. Volání aliasu "dxfin" může být součástí obsluhy tlačítka v nově vytvořeném řídícím dialogu. Tento postup umožnuje použít právě dostupný modul, který požadovaný převod provádí. Např. modul dxf.dll obsahuje pro převod obrazovka - DXF funkci číslo 2 (pro opačnou konverzi funkci číslo 1). Pomocí dialogu modulu sysl.dll zapíšeme přirazení dxfout = dxf.dll:2 a pro dxfin = dxf.dll:1. Popsaným postupem si můžeme "vypůjčit" funkce od ostatních DLL. Všechny DLL však musí být zaregistrovány v FR4.ini souboru! FR4.ini obsahuje mimo jiné popis aktuální konfigurace DLL modulů v programu FR4.
Konfigurační pravidla: Sekvence příkazů musí být uvozena klíčem [MENU] .
Příklad sekvence příkazů pro konfiguraci menu, submenu a tool-baru: [MENU] Main=&User,&Test &User=#,test02.dll:1#,test01.dll:1#,sysl.dll:1# &Test=test01.dll:2,test02.dll:2#,*,test02.dll:3#,test02.dll:4# Komentář k příkladu:
|
DLL soubory - správa modulůRelativní nezávislost DLL modulu zajišťují dvě interfejsové C-funkce.
První z nich (Load_Resource) je využívána hlavním programem po startu, kdy je konfigurováno
menu a tool-bar, druhá (Go_Function) je volána po výběru položky v submenu nebo kliknutí
nad ikonou tool-baru a zajistí obvykle aktivaci požadovaného dialogu, který je součástí DLL
modulu. Funkce je třeba deklarovat v definičním souboru "modul.def". Např. pro služební DLL
(sysl.dll) je třeba vytvořit "sysl.def":
; sysl.def : Declares the module parameters for the DLL. LIBRARY "SYSL" DESCRIPTION 'SYSL Windows Dynamic Link Library' EXPORTS ; Explicit exports can go here Go_Function @2 Load_Resource @3 Interfejsová funkce pro konfigurační účely (Load_Resource) obsahuje řadu parametrů,
které umožňují zařadit text položky do submenu pomocí funkce "AppendMenu", zařadit ikonu
do tool-baru pomocí funkce "Register_button" a zaregistrovat text status-baru dialogu.
Každý dialog zařazený do DLL modulu musí být označen číslem a každý dialog musí být
opatřen výše uvedenou sekvencí kódu . Číslování začíná od čísla 1 a musí být nepřetržité
(1,2,3,...). V dále uvedém přikladě obsahuje modul jen jeden dialog. Parametry specifické
pro dialog jsou zvýrazněny:
extern "C" BOOL FAR PASCAL EXPORT Load_Resource(F_dispatch* Fdis, CMenu* menu,UINT fce,UINT ID_f,CToolBar *tbar,BOOL ico) { TRY { // HINSTANCE for this "modul.dll" HINSTANCE hin = Fdis->Get_dll_HINSTANCE("sysl.dll"); HINSTANCE hAppInst = AfxGetResourceHandle(); char buf[100]; switch(fce) { case 1: // function number 1 // load menu item text LoadString(hin, ID_FCE1 ,buf,100); // append item to menu menu->AppendMenu(MF_STRING,ID_f,buf), // add icon into tool-bar if(ico)Fdis->Register_button(hin, ID_f, IDB_SYSDIAL ,tbar,buf); // load text for status bar LoadString(hin, IDS_SYSDIAL ,buf,100); // register menu item ID's Fdis->Add_IDs(ID_f, 1 ,hin,buf); break; // TODO: add another function menu item and ID's default: TRACE0("SYSL - ERROR Load_Resource - unknown function\n"); break; } } CATCH_ALL(e) { TRACE0("SYSL - ERROR Load_Resource\n"); return FALSE; } END_CATCH_ALL return TRUE; } Pozn ID_FCE1 a IDS_SYSDIAL jsou identifikátory textů a IDB_SYSDIAL je identifikátor bitmapy 24 krát 24 bodů (pro ikonu v tool-baru) v lokálních "resources" DLL modulu. Pomocná funkce pro registraci ikony tool-baru: BOOL Register_button(HINSTANCE hin,UINT ID_fce, UINT ID_BITMAP,CToolBar* tbar,char* tbtext) Druhá interfejsová funkce slouží k aktivaci, tj. k vyvolání (zobrazení) dialogu. DLL modul může obsahovat několik navzájem nezávislých dialogů. K výběru dialogu slouží parametr "fce". Dále uvedený příklad obsahuje pouze jeden dialog, a proto parametr "fce" může nabýt pouze hodnotu 1. Řídící třída obsahuje údaje o všech DLL modulech a jejich funkcích. Pro každou funkci je k dispozici parametr "status" prostřednictvím funkce "Get_IDs_status". Bit 1 tohoto parametru je využíván k indikaci, zda dialog je (bit 1 =1) nebo není (bit 1 =0) aktivován. Výchozí stav zajišťuje "hlavní" program. Objekt dialogu je vytvořen konstruktorem s doplňujícím parametrem Fdis typu (F_dispatch*). Tím je umožněn přístup k řídící třídě všem členským funkcím třídy aktivovaného dialogu. Funkcí AfxSetResourceHandle je nastaven přístup k "resources" tak, aby byl dialog hledán v DLL modulu . V uvedeném příkladě je označen identifikátorem "IDD_SYSDIALOG". Hlavní program zajišťuje pozicování dialogu v okně běžící úlohy. K tomuto účelu slouží tzv. "registrování" dialogu pomocí funkce "Register_dialog". V příkladě je pozice dialogu ovlivňována existencí a hodnotou "globálního" parametru. Dialog může být umístěn vlevo nebo vpravo při okraji okna úlohy. Navíc je nastavením druhého parametru funkce "Register_dialog" na hodnotu identifikace funkce nastaven režim, při kterém ikona v tool-baru příslušná k funkci zůstane po kliknutí a aktivaci dialogu ve "stisknutém" stavu a do zrušní dialogu (na cancel) nebo druhého kliknutí nad ikonou. Proto druhý pokus o aktivování dialogu ikonou je směrován do sekce "else", kde je realizována úplná deaktivace a zrušení dialogu (i objektu). Provedeno je nalezení záznamu o dialogu ve strukturách řídící třídy, nulování bitu parametru "status", zrušení registrace dialogu, zrušení objektu funkcí DestroyWindow a výpis hlášení do status-baru. Příklad implementace nemodálního dialogu:
extern "C" BOOL FAR PASCAL EXPORT Go_Function(F_dispatch* Fdis,UINT fce) { TRY { HINSTANCE hin = Fdis->Get_dll_HINSTANCE("sysl.dll"); HINSTANCE hAppInst = AfxGetResourceHandle(); char buf[100]; if(fce==1) { Fdis->Find_IDs_fce_number(1,hin); UINT st = Fdis->Get_IDs_status(); if((st&0x0002)==0) { Sysd* cbl = new Sysd(CWnd::FromHandle(Fdis->Get_mfw_HWND()),Fdis); AfxSetResourceHandle(hin); // create dialog if(cbl->Create(IDD_SYSDIALOG,Fdis->Get_frame_addr())==FALSE) AfxMessageBox("ERROR Create SYSL Dialog"); AfxSetResourceHandle(hAppInst); // only one dialog can be active Fdis->Put_IDs_status(st|0x2); // set bit:1 // window into parent window and must be declared as "transparent" cbl->SetParent(Fdis->Get_frame_addr()); // register dialog LoadString(hin,ID_DPOSITION,buf,100); UINT pos = DP_RIGHT; if(Fdis->Find_param(&CString(buf))) { LoadString(hin,ID_LEFT,buf,100); if(Fdis->Compare_param_value(&CString(buf)))pos=DP_LEFT; } Fdis->Register_dialog((CWnd*)cbl,Fdis->Get_IDs_ID(),pos); LoadString(hin,ID_SCONTROLD,buf,100); Fdis->Status_text(buf); } else { // cancel registered dialog on click tool button Fdis->Find_IDs_fce_number(1,hin); UINT st = Fdis->Get_IDs_status(); Fdis->Put_IDs_status(st&0xFFFD); // reset bit:1 CWnd *wn = Fdis->Get_dialog_addr(Fdis->Get_IDs_ID()); Fdis->Unregister_dialog(wn); wn->DestroyWindow(); // text into status-bar LoadString(hin,ID_SCONTROLDCAN,buf,100); Fdis->Status_text(buf); } } // TODO: add another dialog } CATCH_ALL(e) { TRACE0("SYSL - ERROR Go_Function\n"); return FALSE; } END_CATCH_ALL return TRUE; }Příklad jednoduššího nemodálního dialogu, který není udržován při okraji okna: HINSTANCE hAppInst = AfxGetResourceHandle(); char buf[100]; if(fce==4) { Fdis->Find_IDs_fce_number(4,Fdis->Get_dll_HINSTANCE("test02.dll")); UINT st = Fdis->Get_IDs_status(); if((st&0x0002)==0) { DIAL2* dial = new DIAL2(CWnd::FromHandle(Fdis->Get_mfw_HWND()),Fdis); AfxSetResourceHandle(Fdis->Get_dll_HINSTANCE("test02.dll")); // create dialog if(dial->Create(IDD_DIALOG1,Fdis->Get_frame_addr())==FALSE) AfxMessageBox("ERROR Create Dialog in DLL2"); AfxSetResourceHandle(hAppInst); // only one dialog can be active Fdis->Put_IDs_status(st|0x2); // set bit:1 // register dialog Fdis->Register_dialog((CWnd*)dial,0,DP_FREE); } else { Fdis->Show_registered_dialogs(); Fdis->Status_text("dialog is already active"); } }Pozn. Zrušení registrace, nastavení bitu v parametru "status" i zrušení objektu musí být v kódu funkce obsluhy "cancel" a "ok" např.: void DIAL2::OnCancel() { // TODO: Add extra cleanup here Fdis->Status_text("DIAL2: OnCancel"); Fdis->Find_IDs_fce_number(4,Fdis->Get_dll_HINSTANCE("test02.dll")); UINT st = Fdis->Get_IDs_status(); Fdis->Put_IDs_status(st&0xFFFD); // reset bit:1 Fdis->Unregister_dialog(this); DestroyWindow(); }Příklad implementace modálního dialogu: int i; Modalnidialog dlg(CWnd::FromHandle(Fdis->Get_mfw_HWND()),Fdis); switch(fce) { case 1: // register dialog - necessary if tool button in use Fdis->Register_dialog(NULL, 0 ,DP_FREE); i = dlg.DoModal(); if(i==-1)AfxMessageBox("ERROR DoModal!"); Fdis->Unregister_dialog(NULL); break;atd ... Pozn. Přehled o souborech projektu lze získat pomocí dialogu modulu sysl.dll pro prohlížení souborů. |
Ovládání dialogů |
Globální a projektové parametryPro předávání informací mezi jednotlivýmí DLL moduly jsou určeny globální a projektové parametry. Zpřístupněny jsou prostřednictvím řídící třídy F_dispatch, která je dědicem třídy F_param. Tato třída obsahuje funkce pro obsluhu řetězce zmíněných parametrů. Každý parametr je definován dvěma textovými řetězci (jménem a hodnotou) a jedním stavovým parametrem. Rozdíl mezi globálními a projektovými parametry je pouze v nastavení bitů stavového parametru. Pomocí modulu sysl.dll lze parametry číst i měnit! Oba typy parametrů jsou ve stejném řetězci, a lze je pomocí dále popsaných funkcí programově vytvářet a rušit a také modifikovat jejich hodnoty. Třída F_param obsahuje interní ukazatel do řetězce, který je využíván některými funkcemi. Přidat parametr: BOOL Add_param(CString *name,CString *value) výstup TRUE, pokud je parametr uloen, jinak FALSE. name název parametru value hodnota parametru Nastavit interní ukazatel na první parametr v řetězci: BOOL First_param() výstup TRUE, pokud byl příkaz splněm, jinak FALSE, pokud žádný parametr v řetězci není. Přestavit interní ukazatel na další parametr v řetězci: BOOL Next_param() výstup TRUE, pokud byl příkaz splněn, jinak FALSE, pokud je řetězec prázdný, nebo další parametr není. V tomto případě má interni ukazatel hodnotu NULL! Nalézt parametr zadaného jména: BOOL Find_param(CString *name) výstup TRUE. pokud byl parametr nalezen, jinak FALSE. name název hledaného parametru. Zrušit parametr zadaného jména: BOOL Delete_param(CString *name) výstup TRUE, pokud byl parametr zrušen, jinak FALSE (parametr nebyl např. nalezen, nebo je uzamknut). name nízev parametru, který má být zrušen. Překopírovat (přečíst) jméno parametru, na který je nastaven interní ukazatel: BOOL Get_param_name(CString *name) výstup TRUE, pokud lze název parametru přečíst, jinak FALSE. name přečtené jméno parametru. Změnit hodnotu parametru: BOOL Set_param_value(CString *value) výstup TRUE, pokud byla hodnota parametru změněna, jinak FALSE (je např. "read-only"). value nová hodnota parametru. Překopírovat (přečíst) hodnotu parametru: BOOL Get_param_value(CString *value) výstup TRUE, pokud bylo moné hodnotu přečíst, jinak FALSE. Porovnat zadanou hodnotu s hodnotou parametru, na který je nastaven interni ukazatel: BOOL Compare_param_value(CString *value) výstup TRUE, pokud jsou hodnoty shodné, jinak FALSE. value zadaná hodnota k porovnání Uzamknutí parametru: BOOL Lock_param_name(CString *name) výstup TRUE, pokud je ve stavovem slove parametru nastaven příslušný bit, jinak pokud není parametr nalezen FALSE. name název parametru Odemknutí parametru: BOOL Unlock_param_name(CString *name) výstup TRUE, pokud byl parametr nalezen a příslušný bit nulován, jinak FALSE. name nízev parametru Uzamknutí hodnoty parametru: BOOL Lock_param_value(CString *name) výstup TRUE,pokud byl parametr nalezen a přísluný bit nastaven, jinak FALSE. name název parametru Odemknutí hodnoty parametru: BOOL Unlock_param_value(CString *name) výstup TRUE, pokud byl parametr nalezen a přísluný bit nulován, jinak FALSE. name nízev parametru Dotaz na uzamknutí parametru nebo jeho hodnoty: BOOL Is_param_locked() výstup TRUE, pokud je parametr, na který je nastaven interní ukazatel, uzamknut. Jinak FALSE. Dotaz na uzamknutí parametru: BOOL Is_param_name_locked() výstup TRUE, pokud je parametr, na který je nastaven interní ukazatel, uzamknut. Jinak FALSE. Dotaz na uzamknutí hodnoty parametru: BOOL Is_param_value_locked() výstup TRUE, pokud je hodnota parametru, na který je nastaven interní ukazatel, uzamknut. Jinak FALSE. Zrušení všech parametrů v řetězci: void Delete_all_params(void) Parametry jsou zrušeny bez ohledu na to, zda jsou nějakým způsobem uzamčeny! příklady použití: Další funkce třídy F_params jsou uvedeny v FR4ctrl.h . Pozn. Jedna instance
této třídy je součástí jádra FR4. Lze ji využít pro ukládání tzv. globálních a projektových
parametrů.
// Uložení hodnoty projektového parametru "muj patametr" // (Fdis je ukazatel na řídící třídu jádra F_dispatch): Fdis->Add_param("Project/muj parametr","uloha"); // Přečtení téhož parametru a sestavení jména souboru: String path = (*Fdis)["Project/muj parametr"] + ".xyz"; // "path" bude obsahovat řetězec: uloha.xyz // S výhodou lze použít konverzní funkce k uložení // parametru např. typu "long" (o hodnotě 103) // do projektového parametru "poradi": long poradi = 103; Fdis->Set_param_long("Project/poradi",poradi); // přečíst hodnotu parametru "poradi" a uložit // do parametru "stav" např v jiném DLL modulu: long stav = Fdis->Get_param_long("Project/poradi"); // parametr "stav" má nyní hodnotu 103. |
ProjektProjekt (uložený na disku) je představován souhrnem různých souborů. Soubory příslušející k projektu jsou zapsány v tzv. projektovém souboru "název_úlohy.FR4". V tomto souboru jsou pro každý zapsaný soubor uvedeny i parametry, které soubor blíže popisují. Po otevření (nebo založení) projektu jsou údaje o každém souboru uloženy do třídy typu F_dyn, a tyto třídy jsou zařazeny do "řetězce" těchto tříd v projektu. Přístup k souborům je zprostředkován dále popsanými funkcemi. Položka projektu může být převedena (dle typu) do dynamického pole nebo řetězce záznamů proměnné délky. Uvedené struktury mohou být vytvářeny i jako dočasné součásti projektu, tj. např. dynamické pole nemusí být nutně ukládáno do souboru. Způsob práce se soubory a dynamickými poli závisí na bitech atributů položky projektu: bit: 0 1 FA_CANOPEN 0x0000 - - FA_RONLY 0x0001 soubor pro zápis i čtení soubor jen pro čtení dat FA_TEXT 0x0002 binární soubor textový soubor FA_HEADER 0x0004 soubor bez hlavičky soubor s hlavičkou FA_FR4 0x0008 starý typ (FEM) nový typ (FR4) FA_DYNMEM 0x0010 jen soubor po otevření vytvoř dyn. pole FA_ONLYDYN 0x0020 soubor i dyn. pole jen dyn. pole FA_FILESTAT 0x0040 - (char) status je v souboru FA_FILEATTR 0x0080 - (long) atribut je v souboru FA_CHAIN 0x0100 dyn. pole tabulek řetězec záznamů FA_VARLEN 0x0200 zázn.pevné délky záznamy proměnné délky FA_INDEX 0x0400 - indexový soubor FA_DATINDEX 0x0800 - udržovat index dle klíče Příklady typů souborů: - soubor, který bude pouze zdrojem informací (tj. bude chráněn oproti zápisu), informace jsou uloženy binárně. Vhodný atribut = FA_RONLY. - soubor je textový a bude po otevření editován. Vhodné atributy = FA_TEXT | FA_DYNMEM . Atributy zajistí, že se po otevření položky vytvoří řetězec záznamů jako dynamická struktura v paměti. - dynamické pole s binárními daty. Vhodné atributy = FA_ONLYDYN. Po otevření položky se vytvoří dynamické pole v paměti. Po uzavření položky bude pole zrušeno. Je-li přidán atribut FA_CHAIN, pak je dynamické pole vytvořeno v podobě řetězce záznamů a záznamy nemusí mít konstantní délku. Varianta záznamů s nekonstantní délkou je podporována mechanizmem pro "nové" soubory (FA_FR4). Pozn. Atributy FA_FILESTAT a FA_FILEATTR naznačují, že pomocné parametry záznamu jsou ukládány do souboru. Tyto dva parametry obsahuje každý záznam dynamického pole. Atribut FA_HEADER naznačuje, že data nejsou v souboru uložena s nulovým offsetem. Podrobnosti musí být popsány v parametrech položky! Po otevření souboru je nastaven "status" poloky. Moné jsou následující stavy: bit 0 1 FS_DYNMEM 0x0001 - vytvořena dynam. struktura v paměti FS_DYNCHAIN 0x0002 dynamická dynamický řetězec tabulka záznamů záznamů FS_OPENED 0x0004 - soubor byl otevřen FS_MEMSAV 0x0008 - uložit dynam. strukturu do souboru před uzavřením souboru Přidat položku do projektu: Nové položky se do otevřeného projektu zařazují pomocí funkce "Add_dyn_table". Tato funkce předává mimo jiné i tributy položky projektu. Ke zpřístupnění souboru (dyn. pole) je nutno použít ještě funkci "Open_File". Její činnost je modifikována atributy. Po otevření souboru (dyn. pole) lze měnit pouze atribut "FA_RONLY" voláním funkce "Set_RONLY" a "Set_RW". BOOL Add_dyn_table(CString *name,CString *type, CString *subtype, CString *group, int attrib) výstup TRUE, pokud je poloka přidána do projektu name název položky (souboru) type typ položky (souboru): binary, text subtype podrobnější označení typu pro typ text např. dxf,html,plain, pro binary např. xyz (souřadnice bodu) group vyjádření příslušnosti ke skupině dat např. vstupy,výstupy attrib výše popsané atributy položky (souboru) projektu. Nastavit vnitřní ukazatel na první položku: BOOL First_dyn_table() výstup TRUE, pokud bylo nastavení úspěšné Pozn. Pozici vnitřního ukazatele vyu6ívají "Get" a "Is" funkce.
Nastavit vnitřní ukazatel na další položku v řetězci: BOOL Next_dyn_table() výstup TRUE, pokud bylo nastavení úspěšné Nastavit vnitřní ukazatel na položku (soubor) zadaného názvu: BOOL Find_dyn_table(CString *name) výstup TRUE, pokud byla položka nalezena name název položky (souboru), která má být nalezena Nastavit vnitřní ukazatel na položku (soubor) se zadaným číslem: BOOL Find_dyn_table(UINT file_num) výstup TRUE, pokud byla položka nalezena file_num číslo položky Zrušit položku (soubor) zadaného jména: BOOL Delete_dyn_table(CString *name) výstup TRUE, pokud byla položka nalezena a zrušena name název položky, která má být zrušena (včetně souboru na disku!) Ověřit, zda je vnitřní ukazatel nastaven na položku se zadaným jménem: BOOL Is_dyn_name(CString *name) výstup TRUE, pokud jméno souhlasí name ověřovaný název položky (souboru) Ověřit, zda je vnitřní ukazatel nastaven na položku zadaného typu: BOOL Is_dyn_type(CString *type) výstup TRUE, pokud typ souhlasí type ověřovaný typ položky (souboru) Ověřit, zda je vnitřní ukazatel nastaven na položku zadaného subtypu: BOOL Is_dyn_subtype(CString *subtype) výstup TRUE, pokud subtyp souhlasí subtype ověřovaný subtyp položky (souboru) Ověřit, zda je vnitřní ukazatel nastaven na položku zadané skupiny: BOOL Is_dyn_group(CString *group) výstup TRUE, pokud skupina souhlasí group ověřovaná skupina položky (souboru) Přečíst název položky (souboru), na kterou je nastaven vnitřní ukazatel: BOOL Get_dyn_table_name(CString *name) výstup TRUE, pokud byl název přečten name přečtený název položky (souboru) Přečíst typ položky (souboru), na kterou je nastaven vnitřní ukazatel: BOOL Get_dyn_table_type(CString *type) výstup TRUE, pokud byl typ přečten type přečtený typ položky (souboru) Přečíst subtyp poloky (souboru), na kterou je nastaven vnitřní ukazatel: BOOL Get_dyn_table_subtype(CString *subtype) výstup TRUE, pokud byl subtyp přečten subtype přečtený subtyp položky (souboru) Přečíst skupinu položky (souboru), na kterou je nastaven vnitřní ukazatel: BOOL Get_dyn_table_group(CString *group) výstup TRUE, pokud byla skupina přečtena group přečtený subtyp položky (souboru) Přečíst atributy položky (souboru), na kterou je nastaven vnitřní ukazatel: int Get_dyn_table_attrib() výstup atribut položky (souboru) Přečíst skupinu položky (souboru), na kterou je nastaven vnitřní ukazatel: unsigned char Get_dyn_table_status() výstup aktuální status položky (souboru) Přečíst ukazatel na třídu popisující položku (soubor), na kterou je nastaven vnitřní ukazatel: F_dyn* Get_dyn_table_pointer() výstup ukazatel na třídu popisující položku (soubor) Nastavení hodnot filtru pro vyhledávaní položek: Filtrace se uplatňuje při použití funkcí "First_dyn_table" a "Next_dyn_table". BOOL Set_dyn_filter(CString *type,CString *subtype,CString *group) výstup TRUE, pokud bylo nastavení úspěšné type typ položky subtype subtyp položky group skupina položek Pozn. Pokud je některá položka NULL, pak není do "filtrace" zahrnuta. Vypnout filtr: BOOL Dyn_filter_off() výstup TRUE, pokud bylo nastavení úspěšné Zapnout filtr: BOOL Dyn_filter_on() výstup TRUE, pokud bylo nastavení úspěšné Pozn. Přehled o souborech projektu lze získat pomocí dialogu modulu sysl.dll pro prohlížení souborů. |
Souborový systém projektuDynamická pole Dynamická pole lze použít samostatně i ve spojení se soubory s níže popsanou strukturou. K dispozici jsou dva typy "dynamických polí": - řetězec záznamů proměnné délky. Struktura je vhodná pro práci se záznamy proměnné délky, které je třeba snadno editovat (především rušit a přidávat). - řetězec tabulek se záznamy konstantní délky. Struktura je vhodná pro práci s obsahy záznamů, kdy je měněn nebo často jen čten jejich obsah. Pozn. Každý záznam v obou typech struktur je opatřen dvěma parametry.
První je nazýván "status" a slouží k označování záznamů pro možnost práce jen
s "označenou" částí záznamů, druhý umožňuje přiřadit záznamu číselnou hodnotu
v rozsahu čtyř bajtů (typu long), tzv. atribut.
Typy souborů Projekt může obsahovat čtyři typy souborů:
Hlavička obsahuje: - textový popis souboru (identifikace). Text má konstantní délku 68 znaků a je ukončen znaky - tři identifikační bajty:
Pozn. Pro tento typ souboru je první identifikační bajt nastaven na 'F' a bajt 4. je nevýznamný.
- offset na začátek dat v souboru (čtyři bajty, parametr typu "long")
- záznamy v hlavičce souboru. Každý záznam začíná klíčovým slovem (názvem parametru),
které neobsahuje znak "SP"(mezera je nahrazena znakem "_"). Za ním je jednou mezerou oddělen
řetězec "hodnoty" ukončený bajtem s hodnotou 0. Pole parametrů je ukončeno prázdným
záznamem ukončeným bajtem s hodnotou 0. Mezi koncem seznamu parametrů a začátkem dat
může být nevyužitý prostor (rezerva).
Pozn. Povinné jsou parametry "record_len" a "table_len" pro soubory s pevnou délkou záznamů.
Položky (soubory nebo dynamická pole) projektu Každý záznam souboru, který byl převeden do struktury (tabulky nebo řetězce)
v paměti, je opatřen dvěma dodatečnými položkami tzv. statusem a parametrem.
Status je typu unsigned char. Bit 0 je vyhrazen pro označení záznamu k vymazání
(funkcí Mark_Rec), bit 1 pro tzv. selekci (funkcí Select_Rec). Ostatní bity mohou být
použity k podobným účelům. Při používání funkcí, které pracují se "statusem", je třeba
mít na paměti, že každá položka projektu nemusí být "statusem" vybavena a příslušné
funkce budou v tomto případě neúčinné!
Přehled typů souborů:
Přehled přístupu k datům po otevření "položky projektu" a atributy, které
jsou akceptovány:
práce v dynamických strukturách v paměti Jen soubor na disku Kombinace - soubor převeden z disku do paměti Úvodní část souboru může obsahovat speciální údaje Zapnout filtr:
Filtrace se týká bitů 1 a 7 statusu a má vliv na funkce "First_Rec"
a "Next_Rec". Nastavením filtru funkcí "Set_filter" např. na hodnotu 0x02
a po zapnutí filtru funkcí "Filter_on" lze vyhledat záznamy, které byly
označeny funkcí " Select_Rec".
Vypnout filtr:
Nastavit filtr:
Přečíst nastavení filtru:
Zrušit nastavení všech bitů statusu filtru:
Otevřít soubor nebo dynamické pole
Zavřít soubor nebo dynamické pole
Ověřit, zda je soubor nebo dynamická struktura připravena
k použití (soubor otevřen):
Nastavit přístup k souborům jen pro čtení:
Nastavit přístup k souborům pro čtení i zápis:
Přidat záznam:
Nastavit vnitřní ukazatel na první záznam:
Nastavit vnitřní ukazatel na další záznam:
Přečíst obsah záznamu:
Zapsat pole do záznamu:
Vložit záznam na aktuální pozici (tj. před stávající aktuální
záznam):
UINT Insert_Rec(void* buf,long len)
výstup kód operace
buf pole obsahující data k uložení do záznamu
len délka dat k uložení
Označit záznam ke zrušení (nastavit bit 0 statusu):
Ověřit, zda je záznam označen ke zrušení (tj. bit 0 statusu
je nastaven):
Zrušit vechny záznamy označené ke zrušení (s nastaveným
bitem 0 statusu):
Zrušit označení záznamu ke zrušení (nulovat bit 0 statusu):
Zrušit označení všech záznamů ke zrušení (nulovat bit 0 statusu
všech záznamů):
Nastavit vnitřní ukazatel na záznam zadaného čísla:
Zjistit číslo záznamu, na který je nastaven vnitřní ukazatel:
Označit záznam (nastavit bit 1 statusu):
Označit záznam (nastavit status dle zadání):
Zrušit označení záznamu (nulovat bit 1 statusu):
Ověřit, zda je záznam označen (tj. bit 1 statusu je nastaven):
Nastavit hodnotu parametru:
Přečíst hodnotu parametru:
Zjistit délku záznamu:
Uložit nuly do binárních záznamů a mezery do variabilního
záznamu a řetězce dynamické struktury:
Zapsat textový řetězec (ukončený nulou) na aktuální pozici:
Přidat textový řetězec (ukončený nulou) za poslední záznam:
Přečíst délku hlavičky:
Zapsat do souboru hlavičku:
Přečíst obsah hlavičky ze souboru:
|
Grafika
Geometrické funkce pro manipulace s body a úsečkami - třída DLine
void MoveToPoint(double x1,double y1) Pozn. Přímka je posunuta vpravo, pokud je hodnota dist menší než nula a vlevo, pokud je dist větš než nula. void Move(double dist) Pozn. Kolmice je oproti původní přímce otočena o +90 stupňů (tj. vlevo). void PerpendicularlyToPoint(double x1,double y1) Pozn. Vrácená hodnota: 0 úsečka leží na přímce 1 průsečík je v bodě x1,y1 2 průsečík je v bodě x2,y2 3 průsečík leží uvnitř úsečky 4 průsečík je vně úsečky 5 přímka je rovnoběžná s úsečkou UINT Intersection(double x1,double y1,double x2, double y2,double *xx,double *yy) Pozn. Vrácená hodnota: 0 přímky jsou rovnoběžné 3 průsečík existuje UINT Intersection(class DLine *dline,double *xx,double *yy) void MovePointForward(double *x1,double *y1,double dist) void MovePointBackward(double *x1,double *y1,double dist) Pozn. Platí, pokud je hodnota dist kladná; void MovePointRight(double *x1,double *y1,double dist) Pozn. Platí, pokud je hodnota dist kladná. void MovePointLeft(double *x1,double *y1,double dist) void Reverse(void) void PointProjection(double x1,double y1,double *x2,double *y2) void Rotate(double x1,double y1,double angle) Pozn. Výsledná přímka je osou zadaných přímek. void Axis(class DLine *dl1,class DLine *dl2) Grafika podporovaná jádrem FR4 - třída F_graphics
Základní pojmyZobrazování grafiky v systému FR4 obstarává třída F_graphics. Umožňuje jak práci s grafickými informacemi v hlavním okně programu (jelikož je děděna třídou F_dispatch), tak i zobrazování v dialogu (prostřednictvím třídy F_GraphicsButton).Grafika FR4 je reprezentována řetězcem virtuálních kreslicích ploch - obrazovek (screen). V současné verzi je možno v hlavním okně aplikace zobrazit současně pouze jednu obrazovku, lze však mezi obrazovkami přepínat. Celý tento mechanismus se dá připodobnit ke složce s listy papíru (F_graphics), ve které se dají stránky (screen) otáčet, vždy je však viditelná pouze nejvrchnější stránka. Každá stránka (obrazovka) v FR4 však představuje velkou kreslicí plochu a ne vždy je účelné dívat se na celou tuto plochu najednou. Proto má každá obrazovka definováno aktuální zvětšení a posunutí výřezu - okna - které se zobrazuje. Dále pak každá obrazovka (list ve složce) obsahuje jednu či více vrstev (layer). Vrstvy jsou jako průhledné fólie, na které jde kreslit - umisťovat grafické entity. Vrstvy je možno po jedné dočasně zneviditelnit a opět obnovit jejich zobrazování. Každá vrstva obsahuje libovolné množství entit (body, úsečky, kružnice, elipsy, lomené čáry, vyplněné polygony, text, ...). Každá entita má vlastní barvu a druh čáry, kterým je vykreslována (hraje-li tento parametr u té které entity roli). Entity ve vrstvě uložené jsou dvourozměrné. Pokud se má zobrazit trojrozměrný objekt, obsahuje vrstva vždy jen aktuální dvourozměrný průmět. 2D grafikaZákladem práce s grafikou v FR4 je 2D zobrazení. Zahrnuje ovládání obrazovek vrstev, práci s entitami a manipulaci se zobrazovacím výřezem.Obrazovky a vrstvyAby bylo kam kreslit entity, je potřeba si vytvořit kreslicí plochu. Tato akce sestává ze dvou kroků. Nejdříve vytvoříme obrazovku voláním funkce UINT AddScreen(CString name), např.:
Dalším krokem je přidání alespoň jedné vrstvy, do které budeme kreslit. AddScreen automaticky nastavilo jako aktivní nově přidanou obrazovku, takže přidání vrstvy proběhne do ní:
AddLayer také po přidání nastaví aktivní vrstvu, takže nám už nic nebrání v kreslení entit (viz. podkapitola entity}. Operací nad vrstvami a obrazovkami je však více. Některou z vytvořených vrstev můžeme chtít například zrušit:
Pokud budeme ale do vrstvy i nadále kreslit a chceme pouze vymazat její obsah, zavoláme
Za povšimnutí stojí, že jak u AddLayer, tak i u RemoveLayer se uvádí název vrstvy v rámcí aktivní obrazovky. Většina ostatních funkcí, včetně EraseActiveLayer, však pracuje s aktivní vrstvou. Je proto třeba umět nastavit aktivní vrstvu:
Také pokud máme více obrazovek, lze mezi nimi přepínat:
Jak bylo uvedeno výše, můžeme jednotlivé hladiny dočasně skrývat. K tomu slouží funkce:
Existenci a ev. viditelnost vrstvy jde testovat:
Pozor! Zatímco IsActiveLayerVisible() vrací BOOL (TRUE/FALSE), LayerExists (a většina ostatních funkcí) vrací podrobnější popis výsledku operace (např. STAT_OK, kde STAT_OK != TRUE !!!). Proto pozor při testování (if(LayerExist("xxx")) není totéž jako if(LayerExist("xxx") == STAT_OK))! Nakonec, máme-li vše nastaveno a ve vrstvách jsou umístěny entity, zajistíme si voláním funkce
překreslení grafiky na obrazovce počítače. Překreslení netrvá většinou příliš dlouho, avšak opakuje-li se často, je postřehnutelné. Proto se okno aplikace nepřekresluje automaticky po přidání každé entity (není-li to nastaveno explicitně voláním pCORE->ImmediateDraw(TRUE);), ani při z(ne)viditelnění vrstvy, počítá se s vícenásobnými operacemi. Téměř u všech akcí spojených s vykreslovánim grafiky tedy platí, že sekvence je ukončena voláním UpdateActiveScreen. EntityMáme-li vytvořenou a nastavenou kreslicí plochu, můžeme přistoupit ke kreslení entit. Každá entita ve vrstvě má definovanou vlastní barvu a typ čáry.BarvyBarva entity se udává jako trojice RGB (červená, zelená a modrá), vyjádřená strukturou COLORREF (Windows API). Pro základní barvy jsou též definována makra:
FR4 verze 1.1: další předdefinované barvy:
<Odkaz na tabulku s paletou barev
Typy čarU každé entity je definován typ čáry, kterým je entita vykreslována. Parametr pro typ čáry není u funkcí pro vytváření entit povinný. Není-li uveden, je dosazena hodnota L_DEFAULT, která značí, že se má použít typ čáry nastavený funkcí
Tuto funkci lze použít např. pokud vykreslujeme v sekvenci za sebou několik entit se stejným typem čáry - ušetří explicitní zápis parametru při volání každé funkce pro kreslení entity. Doplňkovou funkcí k SetLineStyle je
která vrací aktuálně nastavenou hodnotu typu čáry. Typ čáry může být jedním z následujících:
Identifikační čísloKe každé entitě lze při zápisu dodat 32bitovou hodnotu. Obsahem může být např. identifikační číslo entity, ukazatel na strukturu nebo pole příznaků. Využití této možnosti je plně na tom kterém modulu, který entitu vytváří.Spolu s tímto identifikačním číslem je též možnost použít další 32bitový parametr, jehož ukládání souvisí s použitím třídy F_dyn pro uchovávání obsahu vrstvy. Před zápisem entity je pro nastavení tohoto parametru potřeba zavolat funkci
Ke každé entitě tedy můžeme přiřadit dva nezávislé parametry. Navíc je s entitou uchovávána informace o výběru a označení ke smazání entity, tyto informace však do uvedených dvou parametrů nijak nezasahují. BodyPrvní ze skupiny entit je bod. Tato entita je mimo jiné bázovou entitou pro všechny ostatní entity. Funkce pro vykreslení bodu je:
První dva parametry udávají polohu bodu. Parametr 'col' ovlivňuje barvu, stejně jako ostatních entit. 'ID' je identifikační číslo entity, viz. výše. 'style' popisuje typ čáry, kterým je entita vykreslena (u bodu je někdy tento parametr bezvýznamný; ovlivňuje však velikost bodu). Poslední tři parametry se objevují i u ostatních entit a mají stejný význam, nebudou už proto v popisech dalších entit znovu vysvětlovány. ČáryPro vykreslení čáry (ůsečky) slouží funkce:
Oproti bodu přibyly dva parametry pro koncový bod úsečky. Chceme-li vykreslit lomenou čáru, můžeme použít funkce:
Parametr 'numPoints' udává počet bodů čáry, 'points' pak ukazuje na pole dvojic x,y proměnných typu double se souřadnicemi jednotlivých bodů. Kružnice a elipsyDvourozměrné kružnice a elipsy se vykreslují funkcemi:
Parametry 'x' a 'y' udávají střed kružnice, 'r' u kružnice pak poloměr, 'rx' a 'ry' u elipsy poloměry pro jednotlivé osy. Funkce pro elipsu umí vykreslovat elipsy pouze s osami rovnoběžnými se souřadným systémem, ne v obecné poloze. PolygonyDalší entitou podporovanou v FR4 je vyplněný polygon:
Není-li koncový bod shodný s počátečním, je polygon automaticky uzavřen. Parametry jsou stejné jako u lomené čáry. TextyPosledním druhem entit je text. V FR4 jsou rozeznávány dva druhy textů: Prvním druhem je informační text. Je vykreslován standardním fontem systému Windows a jeho velikost je nezávislá na zvětšení. Hodí se např. pro popisy čísel uzlů konstrukce:
Parametry 'x' a 'y' definují vztažný bod, 'txt' pak řetězec s vypisovaným textem. Oproti ostatním entitám je doplněn parametr 'align' udávající polohu vztažného bodu vůči textu:
Druhým druhem textu je text vektorový:
Tento text obsahuje znaky vykreslené z jednotlivých čar. Jeho velikost na obrazovce se mění s aktuálním zvětšením. Hodí se např. pro popisy kót na výkrese. Kromě parametrů shodných s informačním textem je navíc ovlivněn i dalšími funkcemi:
Nastaví, ev. přečte aktuálně nastavenou výšku textu. Hodnota se udává v jednotkách platných pro celou kreslicí plochu (tedy ve stejných, v jakých je kreslen zbytek konstrukce). Obdobně
ovlivňuje šířku výsledného textu. Úhel linky, podél které je text vypisován, se nastaví funkcemi:
Posledními funkcemi, ovlivňujícími vzhled vektorového textu, jsou funkce pro nastavení zkosení (náklonu) písma:
Úhel u obou posledních funkcí je v radiánech. Pro převod stupňů na radiány můžeme použít makra RAD(x). Opačný převod (z radiánů na stupně) zajišťuje makro DEG(x). Je-li potřeba z jakýchkoli důvodů zjistit velikost vykreslovaného řetězce při použití vektorového písma, pak lze s výhodou použít funkce:
Tato funkce zapíše do pole zaslaného parametrem 'rect' souřadnice čtyř vrcholů čtyřúhelníka ohraničujícího text uvedenýc parametrů. V úvahu je přitom brán i sklon a zkosení písma. Mezi entitami je někdy vhodné zařadit poznámku, která není zobrazována, ale může být užitečná při práci s obsahem vrstvy. Poznámka se zapíše funkcí:
Parametr 'txt' odkazuje na řetězec s obsahem poznámky. Ostatní parametry nemají praktický význam a jsou uvedeny pouze z důvodu zařazení mezi entity. Zvětšení a posunPro zobrazování detailů kresby slouží funkce zajišťující posun a zvětšování výřezu plochy, který je v okně aplikace (či v dialogu) vykreslen. Základními funkcemi jsou:
Umožňují posun počátku souřadné soustavy v rámci okna a nastavení násobku zvětšení. Jejich doplňkem pak funkce:
Zvětšení 1 značí, že jedna jednotka virtuální zobrazovací plochy odpovídá jednomu pixelu na obrazovce. Posun a zvětšení obvykle nastavuje uživatel. Daleko častěji je však z kódu výhodné nastavit takové zvětšení a posun, aby byl celý obrázek vidět a optimálně zabíral plochu okna. To se provede funkcí:
Požadujeme-li, aby byl v okně zobrazen přesně zadaný výřez kleslicí plochy, použijeme funkci:
Neodpovídají-li poměry stran zadaného výřezu oknu na obrazovce počítače, je zobrazení provedeno tak, aby byly vidět všechny části zvoleného okna.
Vnitřní reprezentaceGrafiku v FR4 tvoří seznam obrazovek. každá obrazovka obsahuje seznam vrstev v ní uložených. Obsah vrstvy se nachází v tabulce (viz. třída F_dyn), jejíž jméno je složeno z názvu obrazovky a názvu vrstvy odděleného lomítkem, v našem příkladu tedy 'papir/cmaranice'. Typ tabulky je 'graphics', podtyp 'layer' a skupina je shodná s názvem obrazovky. Tabulka je tvořena záznamy s proměnnou délkou.Každý záznam v tabulce reprezentuje jednu grafickou entitu. Všechny entity mají stejný začátek záznamu:
Společnou číst záznamu popisuje též struktura gr_item (viz. FR4Ctrl.h). Od tohoto společného základu jsou odvozeny jednotlivé grafické entity podle hodnoty položky 'type':
Příznaky výběru entity, parametr a ev. příznak smazání entity jsou uchovávány způsobem standardním u tabulek FR4 (viz. funkce F_dyn). 3D grafikaNadstavbou 2D grafiky FR4 je grafika trojrozměrná. Použijeme-li funkci
k oznámení, že aktuálně nastavená obrazovka má 'obsahovat' trojrozměrná data, pak lze navíc oproti 2D u obrazovky specifikovat úhel pohledu a u vrstev začne být nezbytné použití regenerátorů, viz. dále. Entity ve 3DPro kreslení ve 3D nabízí grafika FR4 nadstavbové funkce. U bodů, úseček, lomených čar, polygonů a infotextu jde o pouhé přidání třetí souřadnice:
Vektorový text nemá ve 3D svou obdobu. Elipsy a kružnice se ve 3D objevují ve formě značek. Takovéto objekty mají definován střed ve třech rozměrech, avšak poloměr(y) je (jsou) vztažen(y) k zobrazovací rovině. Nejde tedy o plnohodnotné trojrozměrné entity.
Pro definici kružnice či oblouku v obecné poloze ve 3D se používají funkce, které tyto entity popisují pomocí tří bodů na jejich obvodu:
Po zadání těchto posledních dvou entit je proveden jejich průmět ve 2D ve formě lomené čáry. RegenerátoryVrstvy v grafice FR4 nesou informaci pouze o dvourozměrných entitách. Pokud je vykreslován trojrozměrný objekt, je uchováván pouze jeho průmět za nastaveného úhlu pohledu. Změní-li uživatel úhel pohledu, je třeba průměty aktualizovat. Pro tuto činnost existují v FR4 tzv. regenerátory. Jsou to běžné funkce DLL modulů, které volají funkce pro zápis 3D entit uvedené výše (funkce pro entity provádějí přepočet na průmět samy). Regenerátor se registruje pro každou '3D' vrstvu po jejím vytvoření:
Parametrem je název modulu a číslo funkce, např. 'mydll:4'. Dojde-li ke změně pohledu, jádro zavolá regenerátor postupně pro každou vrstvu obrazovky. Úkolem regenerátoru je pak smazat stávající obsah vrstvy a znovu vrstvu naplnit. Regenerace celé obrazovky proběhne také po zavolání funkce RegenerateActiveScreen. Následující příklad demonstruje obsah regenerátoru, který zobrazí osový kříž a to tak, že je uprostřed obrazovky a optimálně zvětšený: OtáčeníNastavení úhlu pohledu na konstrukci ovlivňuje zpravidla svou volbou uživatel programu. Pokud úhel pohledu změní (dojde k volání některé z níže popsaných funkcí), je pro každou 3D vrstvu volán její regenerátor (po konci nastavení, funkcí RegenerateActiveScreen). Příslušný DLL modul vrstvu naplní voláním funkcí pro zápis 3D entit, přičemž jádro zajistí, aby byl vykreslován průmět odpovídající nově nastavenému úhlu.Nastavení úhlu pohledu je v FR4 omezeno na zadání poledníku a rovnoběžky pohledu. Rotace podle zbývající osy není podporována (nemá při zobrazení konstrukce praktické použití). Poledník a rovnoběžku můžeme zadat buď společně funkcí
nebo zvlášť délku a šířku funkcemi
Aktuální polohu lze zjistit funkcemi
Pro přesné nastavení pohledu podél os slouží funkce
jejímž parametrem je kód zvoleného pohledu:
Předchozí nastavení pohledu (ale i zvětšení a posunu) je v grafice FR4 zapamatováno, takže ho můžeme funkcí
obnovit. Grafika FR4 má též podporu pro technická zobrazení (vybrané druhy axonometrických zobrazení). Nastavení použití těchto zobrazení a čtení aktuálního stavu dosáhneme voláním funkcí
Význam parametru je následující:
Práce s myšíJádro FR4 řeší použití vstupu z myši registrací zpětných volání několika obecných funkcí zahrnujících stisk a uvolnění tlačítka myši a pohyb kurzoru. Těmito funkcemi je možno plně definovat chování kurzoru - zobrazovat nitkový kříž, reagovat na stisk tlačítek (výběr entit) nebo simulovat tažení entit po ploše obrazovky.KurzorPokud uživatel vybírá akci programu v menu nebo nástrojové liště, zobrazuje se kurzor ve formě malé šipky (standardní kurzor Windows). Při výběru entit je však vhodné, aby se kurzor nad zobrazovací plochou měnil v nitkový kříž, jak je tomu zvykem u jiných systému pracujících s vektorovou grafikou. Dosáhneme toho voláním funkce:
První parametr popisuje typ nitkového kurzoru a může mít jednu z následujících hodnot:
Druhý parametr (clip) značí 'uvěznění' kurzoru uvnitř zadávacího okna (běžně se nepoužívá, proto FALSE). Vykreslování nitkového kurzoru se vypne po zavolání funkce:
Zavěšované funkce#define REGISTER_LB_HANDLER(thatclassname, thisclassname, thisfcename, recStat, retValNam) #define REGISTER_RB_HANDLER(thatclassname, thisclassname, thisfcename, recStat, retValNam) #define REGISTER_LD_HANDLER(thatclassname, thisclassname, thisfcename, recStat, retValNam) #define REGISTER_RD_HANDLER(thatclassname, thisclassname, thisfcename, recStat, retValNam) #define REGISTER_LU_HANDLER(thatclassname, thisclassname, thisfcename, recStat, retValNam) #define REGISTER_RU_HANDLER(thatclassname, thisclassname, thisfcename, recStat, retValNam) #define REGISTER_MM_HANDLER(thatclassname, thisclassname, thisfcename, recStat, retValNam) #define GO_GET_LINE(thatclassname, thisclassname, thisfcename, recStat, retValNam) {\ void DeregisterHandlers(void *Othis=NULL); Zachytávání kurzoru a mřížkazobrazovat (bodovou) mřížku UINT ShowGrid(BOOL show); stav zobrazování mřížky BOOL GetGridStatus(); nastavit krok mřížky v ose x UINT SetGridXStep(double x); nastavit krok mřížky v ose y UINT SetGridYStep(double y); zjistit krok mřížky v ose x double GetGridXStep(); zjistit krok mřížky v ose y double GetGridYStep(); Příklad použití grafiky v dialoguPři práci s FR4 grafikou je třeba mít na paměti, že všechny grafické entity definované pomocí popisovaných funkcí, jsou nejdříve ukládány do struktur, a teprve na povel je možné je vykreslit (pozn. ve zvláštním režimu grafiky dochází k okamžitému vykreslování generovaných entit). Po vykreslení jsou 2D entity stále uloženy ve strukturách a lze je proto zobrazit nezávisle na generujících algoritmech s jiným zvětšením a v jiné poloze. Uložené entity lze měnit nebo rušit. Dělení obrázků do vrstev usnadňuje dodatečnou manipulaci s entitami. Základní postup vytvoření kresby je popsán v následujícím příkladě: 1. Vytvoříme obrazovku Fdis->AddScreen("obrazovka"); 2. Vytvoříme vrstvu Fdis->AddLayer("prvni vrstva"); Pozn. Každá vrstva je reprezentována jednou položkou v projektu.
Typ položky projektu je 'graphics', podtyp 'layer', skupina je stejná
jako název obrazovky, do které vrstva náleží. Nazev položky je
3. Ukládáme grafické entity do vrstvy, např. úsečku: Fdis->Line(0, 0, 10, 10, RGB(255,0,0)); Tento příaz vykreslí čáru z bodu [0,0] do bodu [10,10] barvou (255,0,0) (červená). Identifikační číslo a typ jsou ponechány na přednastavených hodnotách. Identifikační číslo (ID) je unikátní číslo, identifikující jednoznačně
entitu ve vrstvě (v obrazovce). Je používáno při výběrech entit uživatelem.
Typ čáry je jednou z možných přednastavených hodnot (plná, čárkovaná,
čerchovaná,... viz. popis fce. Line).
Můžeme přidávat další entity (třeba do další vrstvy): Fdis->AddLayer("druha vrstva"); Fdis->Point(5,0,RGB(0,0,0)); Uložené entity můžeme zobrazit. 4. Nastavime parametry zobrazení, např. výřez obrazovky tak, aby bylo nastaveno zvětšení a posunutí tak, aby bylo zobrazeno všechno, co je ve vrstvách umístěno: Fdis->SetActiveScreenZoomAll(); 5. Dáme povel k zobrazení uložených entit: Fdis->UpdateActiveScreen(); III. Práce s 3D objektyJádro FR4 podporuje přímo pouze 2D grafiku (pozn. s výjimkou režimu práce s OpenGL 3D grafikou). Trojrozměrné objekty jsou převáděny na 2D grafické entity (průměty do 2D) a ukládány stejným způsobem jako entity 2D grafiky. Ke generování musí být připraveny generační funkce, které používají 3D grafické funkce jádra FR4 a jsou upraveny tak, aby je bylo možné kdykoliv volat. Volání generačních funkcí je nutné vždy po rotaci 3D objektu, kdy se vytváří nový průmět objektu. Generační funkce proto musí být v FR4 grafice "registrovány" pomocí funkce: UINT SetActiveLayerRegen(CString regen); Pozn. Pokud je třeba zobrazovat stěny těles se správnou viditelností, pak lze doporučit režim OpenGL. V režimu OpenGL jsou grafické entity ukládány s 3D parametry a pomocí funkcí grafiky OpenGL lze definovat i tělesa. IV. Reference k funkcím grafiky1. práce s obrazovkou nastaví vnitřní ukazatel na první obrazovku 'grafiky' UINT First_screen(); vraci: STAT_OK - nastavena první obrazovka STAT_ENDCHAIN - v seznamu není žádná obrazovka nastaví vnitřní ukazatel na dalši obrazovku 'grafiky' UINT Next_screen(); vraci: STAT_OK - nastavena další obrazovka STAT_ENDCHAIN - konec řetězce obrazovek přidá obrazovku do seznamu UINT AddScreen(CString name); parametry: name - jméno obrazovky vraci: STAT_OK - obrazovka přidána STAT_CANTCREA - nelze přidat - jméno už existuje Pozn. vytvoří obrazovku bez vrstev, posunutí na [0,0], zvětšení 1, axonometrie VT_KOSDIM, pohled +Y, 3D. odstraní obrazovku daného jména UINT RemoveScreen(CString name); parametry: name - jméno obrazovky vraci: STAT_OK - obrazovka odebrana STAT_NOTFOUND - nelze zrušit - neexistuje vrátí jméno aktivní obrazovky CString GetActiveScreenName(); vraci: jméno obrazovky nebo CString(""), pokud žádná obrazovka neexistuje. nastaví aktivní obrazovku UINT SetActiveScreen(CString name); parametry: name - jmeno obrazovky vraci: STAT_OK - obrazovka nastavena STAT_NOTFOUND - nelze nastavit - neexistuje zjistí existenci obrazovky UINT ScreenExists(CString name = ""); parametry: name - jméno obrazovky bez parametru: dotaz, zda existuje alespoň jedna obrazovka vraci: STAT_OK - obrazovka existuje STAT_NOTFOUND - neexistuje zajistí zobrazení aktivní obrazovky v zobrazovacím okně void UpdateActiveScreen(BOOL bErase = TRUE); parametry: bErase - smazat stavající obsah 2. práce se zvětšením a posunutím vrací posun v ose X double GetActiveScreenXPan(); vrátí x pozici středu zobrazení nebo 0, pokud obrazovka neexistuje vrací posun v ose Y double GetActiveScreenYPan(); vrátí y pozici středu zobrazení nebo 0, pokud obrazovka neexistuje vrátí nastavený faktor zvětšení double GetActiveScreenZoom(); vraci: faktor zvětšení nebo 1, pokud obrazovka neexistuje. nastaví x pozici středu zobrazení UINT SetActiveScreenXPan(double pan); parametry: pan - x pozice středu vraci: STAT_OK - pozice nastavena STAT_NOTFOUND - obrazovka neexistuje nastaví y pozici středu zobrazení UINT SetActiveScreenYPan(double pan); nastavi y parametry: pan - y pozice středu vraci: STAT_OK - pozice nastavena STAT_NOTFOUND - obrazovka neexistuje nastaví faktor zvětšení zobrazení UINT SetActiveScreenZoom(double zoom); parametry: zoom - faktor zvětšení vraci: STAT_OK - zvětšeni nastaveno STAT_NOTFOUND - obrazovka neexistuje nastaví zvětšení a střed tak, aby byla zobrazena celá kresba v okně grafiky UINT SetActiveScreenZoomAll(); vraci: STAT_OK - posun a zvětšení nastaveno STAT_NOTFOUND - obrazovka neexistuje nastaví zvětšení a střed tak, aby byl zobrazen daný výřez kresby UINT SetActiveScreenWindow(double x1, double y1, double x2, double y2); parametry: x1,y1,x2,y2 - souřadnice rohu výřezu vraci: STAT_OK - posun a zvětšení nastaveno STAT_NOTFOUND - obrazovka neexistuje 3. práce s vrstvami nastaví vnitřní ukazatel na první vrstvu 'obrazovky'. UINT First_layer(); vraci: STAT_OK - nastavena prvni vrstva STAT_ENDCHAIN - v seznamu neni žádná vrstva nastaví vnitřní ukazatel na další vrstvu 'obrazovky'. UINT Next_layer(); vraci: STAT_OK - nastavena další vrstva STAT_ENDCHAIN - konec řetězce vrstev nastavení aktivní vrstvy. UINT SetActiveLayer(CString layer); vraci: STAT_OK - vrstva nastavena STAT_NOTFOUND - nelze nastavit - neexistuje vratí jméno aktivní vrstvy CString GetActiveLayerName(); vraci: jméno vrstvy nebo CString(""), pokud žádná vrstva neexistuje. vrátí status aktivní vrstvy long GetActiveLayerStatus(); vraci: status vrstvy nebo 0, pokud vrstva ci obrazovka neexistuje. nastavi status aktivni vrstvy UINT SetActiveLayerStatus(long stat); parametry: stat - status vrstvy (viz. Dodatek A) vraci: STAT_OK - status nastaven STAT_NOTFOUND - nelze nastavit - vrstva ci obrazovka neexistuje přidá novou vrstvu k aktualní obrazovce UINT AddLayer(CString name, long stat=FL_VISIBLE); parametry: name - jméno vrstvy stat - status vrstvy (viz. Dodatek A) vraci: STAT_OK - vrstva vytvořena STAT_CANTCREA - vrstva daného jména už existuje STAT_NOTFOUND - obrazovka neexistuje jiný STAT_ - viz.F_dyn::Open_File(). zruší vrstvu daného jména UINT RemoveLayer(CString name); parametry: name - jméno vrstvy vraci: STAT_OK - vrstva vytvořena STAT_NOTFOUND - obrazovka či vrstva neexistuje Pozn. pokud je vrsva vytvořena funkcí DisplayLayer, není tabulka s entitami vrstvy smazána. zjistí existenci vrstvy daného jména UINT LayerExists(CString name = ""); parametry: name - jméno vrstvy bez parametru: existuje alespoň jedna vrstva v obrazovce? vraci: STAT_OK - vrstva existuje STAT_NOTFOUND - vrstva neexistuje smaze obsah aktivni vrstvy UINT EraseActiveLayer(); vraci: STAT_OK - vrstva existuje STAT_NOTFOUND - vrstva neexistuje STAT_CANTCREA - vrstvu nelze vytvořit jiny STAT_ - viz.F_dyn::Open_File(). Pozn. nevolejte tuto funkci na vrstvu vytvořenou pomocí DisplayLayer. Používejte ve funkcích zavěšených na překreslení 3D, raději než RemoveLayer(). nastavií status aktivní vrstvy na viditelnou UINT ShowActiveLayer(); vraci: STAT_OK - status nastaven STAT_NOTFOUND - nelze nastavit - vrstva či obrazovka neexistuje zneviditelní aktivní vrstvu (vypne její zobrazovaní) UINT HideActiveLayer(); vraci: STAT_OK - status nastaven STAT_NOTFOUND - nelze nastavit - vrstva či obrazovka neexistuje status viditelnosti aktivni vrstvy BOOL IsActiveLayerVisible(); vraci: TRUE - vrstva je viditelna FALSE - vrstva neni viditelna povolí výběr v aktivní vrstvě UINT EnableActiveLayerSelect(); vraci: STAT_OK - status nastaven STAT_NOTFOUND - nelze nastavit - vrstva či obrazovka neexistuje zakáže výběr v aktivní vrstvě UINT DisableActiveLayerSelect(); vraci: STAT_OK - status nastaven STAT_NOTFOUND - nelze nastavit - vrstva či obrazovka neexistuje status selekovatelnosti aktivní vrstvy BOOL IsActiveLayerSelectable(); vraci: TRUE - vrstva je selekovatelná FALSE - vrstva není selekovatelná 4. práce s 3D UINT RegenerateActiveScreen(BOOL erase = TRUE); UINT SetActiveScreenViewpoint(double lon, double lat); UINT SetActiveScreenLon(double lon); UINT SetActiveScreenLat(double lat); double GetActiveScreenLon(); double GetActiveScreenLat(); UINT SetActiveScreenViewpoint(UINT vp); UINT SetActiveLayerRegen(CString regen); CString GetActiveLayerRegen(); UINT SetActiveScreenAxo(UINT axo); UINT GetActiveScreenAxo(); UINT RecalcActiveScreenVisibleBounds(BOOL repaint = FALSE); UINT SetActiveScreenToBe3D(BOOL be3D = TRUE); 5. práce s entitami (2D) převod fyzických souřadnic polohy myši do souřadnic 2D průmětu (obrazovky) BOOL TransformMouseTo2D(CPoint p,double *xx, double *yy); převod fyzických souřadnic polohy myši do siuřadnic 2D přůmetu (obrazovky) se zaokrouhlenim souřadnic do mžížky BOOL TransformSnappedMouseTo2D(CPoint p,double *xx,double *yy); převod souřadnic 2D (obrazovky) do fyzických souřadnic myši BOOL Transform2DtoMouse(CPoint *p, double x, double y); nastavení stylu čar UINT SetLineStyle(UINT style); přečtení nastaveného stylu čar UINT GetLineStyle(); 2D bod UINT Point(double x, double y, COLORREF col, long ID=0, UINT style=L_DEFAULT); 2D úsečka UINT Line(double x1, double y1, double x2, double y2, COLORREF col,long ID=0, UINT style=L_DEFAULT); 2D kružnice UINT Circle(double x, double y, double r, COLORREF col, long ID=0, UINT style=L_DEFAULT); 2D elipsa s osami rovnoběžnými s osami x a y obrazovky UINT Ellipse(double x, double y, double rx, double ry, COLORREF col, long ID=0, UINT style=L_DEFAULT); 2D polyline UINT PolyLine(UINT numPoints, double *points, COLORREF col,long ID=0, UINT style=L_DEFAULT, BOOL filled = FALSE); 2D polygon (nemusí být uzavřený) UINT Polygon(UINT numPoints, double *points, COLORREF col,long ID=0, UINT style=L_DEFAULT); informační text konstantní velikosti bez ohledu na zvětšení obrázku UINT InfoText(double x, double y, const char *txt , COLORREF col, long ID=0, UINT style=L_DEFAULT); zjistit hodnotu parametru pro nastavení výšky textu double GetTextHeight(); nastavit parametr určující výšku textu void SetTextHeight(double h); zjistit hodnotu parametru pro nastavení šířky textu double GetTextWidth(); nastavit parametr určující šířku textu void SetTextWidth(double w) {twidth = w;}; zjistit hodnotu parametru pro nastavení směru textu double GetTextAngle(); nastavit parametr určující směr textu void SetTextAngle(double a); zjistit hodnotu parametru pro nastavení sklonu textu double GetTextSlant(); nastavit parametr určující sklon textu void SetTextSlant(double s); nastavení parametru grafické entity void SetEntParam(long i); výpočet obdélníka, ve kterém se nachází zadaný text void CalculateTextRect(double rect[8], UINT align, char *txt, int numCh, double x, double y, double angle, double slant, double height, double width); 2D text UINT Text(double x, double y, const char *txt , COLORREF col = 0L, long ID=0, UINT style=L_DEFAULT, UINT align=T_DEFAULT); poznámka, které není v obrázku viditelná UINT Note(const char *txt, COLORREF col = 0L, long ID=0, UINT style=L_DEFAULT); 6. práce s entitami (3D) transformace bodu (x,y,z) do souřadnic obrazovky (xx,yy) void Transform3Dto2D(double x,double y,double z, double *xx,double *yy); bod o souřadnicích x,y,z UINT Point3D(double x, double y, double z, COLORREF col, long ID=0, UINT style=L_DEFAULT); úsečka z bodu x1,y1,z1 do bodu x2,y2,z2 UINT Line3D(double x1, double y1, double z1, double x2, double y2, double z2, COLORREF col = 0L, long ID=0, UINT style=L_DEFAULT); oblouk v prostoru z bodu x1,y1,z1 přes bod x2,y2,z3 do bodu x3,y3,z3 UINT Arc3D(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, COLORREF col = 0L, long ID=0, UINT style=L_DEFAULT); kružnice v prostoru z bodu x1,y1,z1 přes bod x2,y2,z3 do bodu x3,y3,z3 UINT Circle3D(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, COLORREF col = 0L, long ID=0, UINT style=L_DEFAULT);
UINT PolyLine3D(UINT numPoints, double *points, COLORREF col = 0L,long ID=0, UINT style=L_DEFAULT, BOOL filled = FALSE);
UINT Polygon3D(UINT numPoints, double *points, COLORREF col,long ID=0, UINT style=L_DEFAULT); v prostoru umístěný text UINT Text3D(double x, double y, double z, const char *txt , double lon = 0.0, double lat = 0.0, COLORREF col = 0L, long ID = 0L, UINT style = L_DEFAULT, UINT align = T_DEFAULT); kružnice jako značka ( v rovině obrazovky ) UINT CircleMark3D(double x, double y, double z, double r, COLORREF col = 0L, long ID=0, UINT style=L_DEFAULT); elipsa jako značka ( v rovině obrazovky ) UINT EllipseMark3D(double x, double y, double z, double rx, double ry, COLORREF col = 0L, long ID=0, UINT style=L_DEFAULT); text jako značka ( v rovině obrazovky ) UINT InfoText3D(double x, double y, double z, const char *txt ,COLORREF col, long ID=0, UINT style=L_DEFAULT); 7. práce s kurzorem zobrazit kurzor void ShowCrossHair(UINT chType = CH_CROSSHAIR, BOOL clip=FALSE); zrusit zobrazení kurzoru void HideCrossHair(); levé tlačítko - dolů UINT RegisterLBHandler(void *LBt, FRBCB addr, BOOL recStat = FALSE); pravě tlačítko - dolů UINT RegisterRBHandler(void *RBt, FRBCB addr, BOOL recStat = FALSE); levé tlačítko - dvakrát UINT RegisterLDHandler(void *LBt, FRBCB addr, BOOL recStat = FALSE); pravé tlačítko - dvakrát UINT RegisterRDHandler(void *RBt, FRBCB addr, BOOL recStat = FALSE); levé tlačítko - nahoru UINT RegisterLUHandler(void *LBt, FRBCB addr, BOOL recStat = FALSE); pravé tlačítko - nahoru UINT RegisterRUHandler(void *RBt, FRBCB addr, BOOL recStat = FALSE); pohyb myši UINT RegisterMMHandler(void *RBt, FRMCB addr, BOOL recStat = FALSE); definování úsečky UINT GoGetLine(void *Lt , FRLCB addr, BOOL recStat = FALSE); zrušení registrace zadaného objektu void DeregisterHandlers(void *Othis=NULL); 8. geometrické funkce long GetNearestIDinLayer(double x, double y, double r); double DistPoint2Point(double x1, double y1, double x2, double y2); double DistPoint2Line(double x, double y, double x1, double y1, double x2, double y2); double DistPoint2Circle(double x, double y, double x1, double y1, double r1); BOOL DoLinesIntersect(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4); BOOL LineIntersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double *x, double *y); BOOL IsPointProjectOnLine(double x, double y, double x1, double y1, double x2, double y2); Dodatek A - konstantyKonstanty a makra EPS - epsilon PI - Ludolfovo cislo RAD(x) - prevod cisla x ze stupnu na radiany DEG(x) - prevod cisla x z radianu na stupne Status vrstvy (lze kombinovat) FL_VISIBLE - vrstva je viditelna FL_SELECTABLE - ve vrstve lze vybirat entity funkcemi pro vyber FL_READONLY - obsah vrstvy je pouze pro cteni (viz. fce. DisplayLayer) Druhy axonometrii (nelze kombinovat) VT_NONE - bez axonometrie VT_KOSDIM - kosouhla dimetrie (default) VT_ITAAXO - italska axonometrie VT_KAVALAXO - kavalirni axonometrie Předdefinované pohledy ze směru os (nelze kombinovat) VP_XPLUS - pohled z X+ VP_XMINUS - pohled z X- VP_YPLUS - pohled z Y+ VP_YMINUS - pohled z Y- VP_ZPLUS - pohled z Z+ VP_ZMINUS - pohled z Z- Druhy čar (nelze kombinovat) L_DEFAULT - standardni (viz. fce. Line) L_SOLID - plna cara _________________ L_DASH - carkovana _ _ _ _ _ _ _ _ _ L_DOT - teckovana ................. L_DASHDOT - cerchovana _._._._._._._._._ L_DBLDOT - dvojteckovana _.._.._.._.._.._. L_PHANTOM - neviditelna L_THICK - tlusta ================= L_VERYTHICK - velmi tlusta EEEEEEEEEEEEEEEEE FR4 verze 1.1 : // ISO/DIS 12011-1 line types L_ISO_01_1 1 L_ISO_01_1B 9 -----------v^--------- L_ISO_01_2 7 L_ISO_01_3 8 L_ISO_02_1 10 ---- ---- ---- ---- L_ISO_02_2 11 ==== ==== ==== ==== L_ISO_02_3 12 EEEE EEEE EEEE EEEE L_ISO_07 13 . . . . . . . . . . . . . L_ISO_08_1 14 --- - --- - --- - --- - --- L_ISO_08_2 15 === = === = === = === = === L_ISO_08_3 16 EEE E EEE E EEE E EEE E EEE L_ISO_09_1 17 --- - - --- - - --- - - --- L_ISO_09_2 18 === = = === = = === = = === L_ISO_09_3 19 EEE E E EEE E E EEE E E EEE Předdefinované typy kurzoru CH_NONE - kurzor vypnut (není stejné jako CH_PHANTOM) CH_CROSSHAIR - nitkový kříž ----|---- CH_CIRCLE - kříž s kroužkem ----o---- CH_BOX - kříž se čtverečkem ----[]--- CH_PHANTOM - neviditelný kurzor (zapnutý) FR4 verze 1.1 : CH_SIZE 5 no crosshair, size arrow all directions CH_ROT 6 no crosshair, rot arrow all directions Dodatek B - vnitřní funkce grafiky (pokud možno nepoužívat)F_graphics(); ~F_graphics(); void OnDrawFromBuffer(CDC* pDC); // public draw function void OnEraseGraphicsBkgrnd(); void SetDisplayWindow(CWnd *wnd); void DestroyGraphics(); void OnTrackMouseMove(UINT nFlags, CPoint point); void OnLBDown(UINT nFlags, CPoint point); void OnRBDown(UINT nFlags, CPoint point); void OnLBDouble(UINT nFlags, CPoint point); void OnLBUp(UINT nFlags, CPoint point); void OnRBDouble(UINT nFlags, CPoint point); void OnRBUp(UINT nFlags, CPoint point); UINT DisplayLayer(CString name, long stat=FL_VISIBLE); Dodatek C - formát ukladaných entit ve vrstvě2D grafické entity: struct gr_item { char type; long ID; COLORREF color; UINT style; }; struct gr_point : public gr_item { double x,y; }; struct gr_line : public gr_item { double x1,y1,x2,y2; }; struct gr_circle : public gr_point { double r; }; struct gr_ellipse : public gr_point { double rx,ry; }; struct gr_polyline : public gr_item { UINT numPoints; // the array of x-y pairs of double follows }; struct gr_infotext : public gr_point { UINT numChars; // the array uf characters follows }; Dodatek D - prototypy callback funkcítypedef void (CALLBACK *FRBCB)(F_dispatch* dis,UINT nFlags, CPoint p, double x, double y, BOOL finish); typedef void (CALLBACK *FRMCB)(F_dispatch* dis,CDC *pDC, CPoint p, BOOL finish); typedef void (CALLBACK *FRLCB)(F_dispatch* dis,double x1, double y1, double x2, double y2, BOOL finish); Zbytek (pro úplnost):chain of layers struct F_layer_chain { struct F_layer_chain *chain; F_dyn *layer; visible, selected, locked, grayed,... UINT lstyle; current line style long status; CString regenerator; }; chain of graphs struct F_graph_chain { struct F_graph_chain *chain; struct F_layer_chain *layers; struct F_layer_chain *layers_A; CString name; 2D position and magnitude: double PX,PY,ZV; 2D boundary: double XMAX,YMAX,XMIN,YMIN; 3D param.: sines and cosines of longitude/latitude double Slon,Clon,Slat,Clat; type of axonometry/isometry UINT axo; BOOL viewIs3D; }; chain of views struct F_view_chain { struct F_view_chain *chain; CView *view; CString name; }; |
atd . . . |