Moravské přístroje, a. s., zdroj: https://www.mii.cz/art?id=653&lang=405, vytištěno: 29.04.2024 10:17:06
Hlavní stránka▹Podpora▹FAQ | 25.4.2022 |
---|
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; 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ů. 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. |