Moravské přístroje, a. s., zdroj: https://www.mii.cz/art?id=653&lang=405, vytištěno: 30.04.2025 14:20:43
Hlavní stránka▹Podpora▹FAQ | 25.4.2022 |
---|
Obsah sekce:
Univerzální MessageBoxPotřebujete zobrazovat různá hlášení za běhu aplikace, na které musí obsluha zareagovat? Příklad MessageBox ukazuje jak na to. Download: MessageBox.zip Tip na efektivní zálohování (backup) hodnotPříklad BackupOnChange.cw ukazuje jak automaticky aktivovat zálohování hodnot (backup) při změně hodnoty datového elementu. settings ... backup method = on_demand; end_backup; ... end_settings; ... data var X {backuped = true}; b1 : boolean; b2 : boolean {backuped = false}; r1 : real; r2 : real {backuped = false}; procedure OnScalarLogicalChange( var DataElement : boolean ); begin (* Procedura je vyvolána vždy, když dojde ke změne skalárního booleanovského datového elementu. Backup() se volá jen pro datové elementy, které mají nastaven atribut backuped na true. *) if DataElement:backuped then Backup(); end; end_procedure; procedure OnScalarNumericalChange( var DataElement : real ); begin (* Procedura je vyvolána vždy, když dojde ke změne skalárního numerického datového elementu. Backup() se volá jen pro datové elementy, které mají nastaven atribut backuped na true. *) if DataElement:backuped then Backup(); end; end_procedure; end_var; end_data; Poznámka: Pokud mají být zálohovány všechny datové elementy definované v datové sekci, není třeba testovat atribut backuped. Zápis procedury se zjednoduší jen na zavolání OCL procedury Backup(). procedure OnScalarNumericalChange( var DataElement : real ); begin Backup(); end_procedure; Download: BackupOnChange.cw Archivace změn hodnot (journal) pomocí datové sekce archivePříklad Journal.cw ukazuje možnost archivace změn hodnot (obdoba přístroje journal) pomocí datové sekce archive a událostních procedur datových sekcí. Výhodou tohoto řešení je možnost sdílet tyto události v distribuovaných aplikacích a jejich prohlížení pomocí přístroje data_viewer. Aplikace využíva uživatelských atributů user0 a user1, kde v atributu user0 je uložen text, popisující událost a atribut user1 slouží pro uchování původní hodnoty datového elementu. Pro vyhodnocení změn hodnot datových elementů jsou použity událostní procedury datových sekcí On*Change. archive Journal; Message : string {comment = 'Message'}; NewValue : string {comment = 'New value'}; OldValue : string {comment = 'Old value'}; Operator : string {init_value = 'none'; comment = 'Operator'; user0 = 'User changed'}; DataElement : string {comment = 'Data element'}; procedure Notify( DE, Msg, OldVal, NewVal : string ); begin DataElement = DE; Message = Msg; OldValue = OldVal; NewValue = NewVal; Archive(); end_procedure; procedure On_Operator_Change(); begin Notify( 'Operator', Operator:user0, Operator:user1, Operator:value_string ); Operator:user1 = Operator:value_string; end_procedure; end_archive; var LogVars; b : boolean {user0 = 'Boolean value changed'}; r : real {user0 = 'Real value changed'}; s : string {user0 = 'String value changed'}; procedure OnScalarLogicalChange( var DataElement : boolean ); begin Journal.Notify( DataElement:long_name, DataElement:user0, DataElement:user1, DataElement:value_string ); DataElement:user1 = DataElement:value_string; (* Save current value to user1 atribute *) end_procedure; procedure OnScalarNumericalChange( var DataElement : real ); begin Journal.Notify( DataElement:long_name, DataElement:user0, DataElement:user1, DataElement:value_string ); DataElement:user1 = DataElement:value_string; (* Save current value to user1 atribute *) end_procedure; procedure OnScalarStringChange( var DataElement : string ); begin Journal.Notify( DataElement:long_name, DataElement:user0, DataElement:user1, DataElement:value_string ); DataElement:user1 = DataElement:value_string; (* Save current value to user1 atribute *) end_procedure; end_var; Download: Journal.cw Proměnné časování přístrojePotřebujete-li u přístroje měnit periodu časování, můžete to vyřešit tak, že parametr period nastavíte na hodnotu infinite a přepíšete událostní proceduru OnActivate příslušného přístroje tak, jak je uvedeno v následujícím příkladu: var Period : real {init_value = 1}; end_var; procedure OnActivate(); begin pause Period; send self; end_procedure; Download: VariableTiming.cw Vícerozměrná poleControl Web umožňuje pracovat pouze s jednorozměrným polem. Pokud potřebujete vícerozměné pole, můžete se inspirovat následujícím příkladem, který ukazuje práci s dvourozměrným polem. var Array; A1 : array[ 0..49 ] of real {comment = 'array [0..9][0..4] of real'; user0 = '9'; user1 = '4'}; A2 : array[ 0..39 ] of real {comment = 'array [0..19][0..1] of real'; user0 = '19'; user1 = '1'}; procedure idx( Array : array of real; x, y : integer ): cardinal; var i : cardinal; lindex : integer; SizeX : integer; SizeY : integer; begin lindex = loindex(Array); SizeX = val(Array[ loindex(Array)]:user0, 10); SizeY = val(Array[ loindex(Array)]:user1, 10); if (x >= 0) and (x <= SizeX) and (y >=0 ) and (y <= SizeY) then return x + y * SizeX; else core.DebugOutput( 'ERROR: Index out of range. ' + Array[lindex]:name + '[' + x:s + ', ' + y:s + '] (' + Array[lindex]:name + ' : ' + Array[0]:comment + ')' ); core.StopApplication(); end; end_procedure; procedure GetItem( Array : array of real; x, y : cardinal ): real; begin return Array[ idx(Array, x, y ) ]; end_procedure; procedure SetItem( Array : array of real; x, y : cardinal; Value : real ); begin Array[ idx(Array, x, y ) ] = Value; end_procedure; end_var; ... procedure xy(); var r : real; begin Array.SetItem( Array.A1, 1, 2, 10 ); r = Array.GetItem( Array.A2, 9, 1, 10 ); end_procedure; Jak automaticky odhlásit uživatele?Aplikace AutoLogout.cw ukazuje, jak lze vyřešit automatické odhlášení přihlášeného uživatele do aplikace v systému Control Web po definované době nečinnosti. Jak omezit počet vybraných položek v přístroji multi_switch v módu check_box.Jednoduchá aplikace demonstrující omezeni počtu vybraných položek v přístroji multi_switch v módu check_box. var ba : array[ 1..5 ] of boolean; end_var; multi_switch switch_1; const maxSelected = 3; end_const; static NoOfSelected : cardinal; end_static; owner = background; position = 35, 35, 59, 77; mode = check_box; item output = ba[1]; text = ' Item 1'; end_item; item output = ba[2]; text = ' Item 2'; end_item; item output = ba[3]; text = ' Item 3'; end_item; item output = ba[4]; text = ' Item 4'; end_item; item output = ba[5]; text = ' Item 5'; end_item; procedure OnIndexOutput( Index : longint; Output : boolean ); begin if Output <> ba[Index] then if Output then if NoOfSelected = maxSelected then Output = false; Update(false); else NoOfSelected = NoOfSelected + 1; end; (* if *) else NoOfSelected = NoOfSelected - 1; end; (* if *) end; (* if *) end_procedure; end_multi_switch; Download: CheckBoxRestriction.cw Jak měnit barvy pro jednotlivé stavy v přístroji multi_label.Pokud potřebujete zobrazovat texty a pozadí jednotlivých položek v přístroji multi_label různými barvami, můžete to udělat pomocí OCL procedur přístroje například takto: multi_label mlbl; gui owner = pSample; position = 100, 40, 60, 20; window disable = zoom, maximize; end_window; end_gui; justify = center; item expression = BoolArray[0]; text_list font = font_caption; text = 'Text 1'; end_text_list; end_item; item expression = BoolArray[1]; text_list font = font_caption; text = 'Text 2'; end_text_list; end_item; item expression = BoolArray[2]; text_list font = font_caption; text = 'Text 3'; end_text_list; end_item; item expression = BoolArray[3]; text_list font = font_caption; text = 'Text 4'; end_text_list; end_item; procedure OnStartup(); begin send self; end_procedure; procedure OnIndex( Index : longint ); begin switch Index of case 1; SetColor( 'ink', 'white' ); SetColor( 'paper', 'lred' ); case 2; SetColor( 'ink', 'lyellow' ); SetColor( 'paper', 'lgreen' ); case 3; SetColor( 'ink', 'lcyan' ); SetColor( 'paper', 'lblue' ); case 4; SetColor( 'ink', 'lred' ); SetColor( 'paper', 'black' ); end; (* switch *) end_procedure; end_multi_label; Download: multi_label_ChangeColor.cw Převod bitové reprezentace reálného čísla s jednoduchou přesností na shortrealBitová reprezentace reálného čísla s jednoduchou přesností ve formátu definovaném podle IEEE 754 je následující: Pro reprezentovanou hodnotu reálného čísla R platí: Příklad převodu: procedure BytesToFloat( b0, b1, b2, b3 : shortcard ): shortreal; var b, e, m, s : longcard; E, M : real; i : integer; begin b = bitshl( b3, 24 ) + bitshl( b2, 16 ) + bitshl( b1, 8 ) + b0; m = bitand(b, val('7FFFFF', 16 )); e = bitshr(bitand(b, val('7F800000', 16 )), 23); s = bitget(b, 31); for i = 0 to 7 do E = E + bitget( e, i ) * pow( 2, i ); M = M + bitget( m, 23 - i ) * pow( 2, -i ); end; for i = 8 to 23 do M = M + bitget( m, 23 - i ) * pow( 2, -i ); end; if (E >= 1) and (E <=254) then return pow(-1, s) * pow( 2, E-127) * (1 + M); (* basic format *) elsif (E = 0) and (M <> 0) then return pow(-1, s) * pow( 2, -126) * M; (* denormalized number *) elsif (E = 0) and (M = 0) then return 0; elsif (E = 255) and (M = 0) then if s = 0 then return MaxShortReal; (* plus infinity *) else return MinShortReal; (* minus infinity *) end; else (* (E = 255) and (M > 0) *) core.DebugOutput( 'ERROR: Invalid number mask' ); core.StopApplication(); end; end_procedure; Download: Float to-from Four Bytes Conversion (IEEE754 format).cw Jak zapsat hodnotu z přístroje s jedním výstupem (control, switch, apod.) na více datových elementů?Tyto přístroje mají událostní proceduru OnOutput, která je vyvolávána vždy po zadání hodnoty. Do této procedury je v parametru Output předávána právě zadaná hodnota, kterou pak můžeme jednoduše přiřadit na příslušné datové elementy. Příklad: control MyControl; procedure OnOutput( Output : real ); begin data_element1 = Output; data_element2 = Output; data_element3 = Output > 50; ... data_elementN = k1 + Output * k2; end_procedure; end_control; Jak je vidět na příkladu, lze takto na datové elementy přířadit i hodnotu získanou vyčíslením výrazu. Jak nastavit počítání čísla týdne v roce podle českých zvyklostíPokud potřebujete prohlížet archivy sledovaných veličin v přístroji data_viewer, máte možnost nastavit počátek časové osy dialogem. Datum a čas lze zadat ručně vepsáním do editačních polí, nebo lze otevřít pomocný dialog s kalendářem pro výběr dne. Možná Vás zarazilo, že v zobrazeném kalendáři nesedí čísla týdnů. Problém je v tom, že kalendář respektuje nastavení operačního systému a pokud toto není pro dané národní prostředí správné, nesouhlasí číslování týdnů. Číslování týdnů není podle všeobecně užívaného pravidla Sjednat nápravu nelze prostřednictvím okna regionálních nastavení. Ačkoliv máte nastaveno české prostředí, číslování týdnů v roce nemusí odpovídat. Příčinou je chybně nastavená položka LOCALE_IFIRSTWEEKOFYEAR tzv. locale nastavení (více informací viz MSDN ). Opravit nastavení lze např. pomocí programu Regedit, kdy v klíči HKEY_CURRENT_USER\Control Panel\International nastavíte položku iFirstWeekOfYear na hodnotu 2. Od tohoto okamžiku bude výpočet proveden podle běžných českých zvyklostí a bude stejný jako např. v tištěných kalendářích. Číslování podle českých zvyklostí |