2019.03.27

ココログの不具合その2

シンタックスハイライターを用いたソースコードの整形が出来ない不具合は解消されたようです。


 

| | コメント (0)

2019.03.25

ココログの不具合

ココログが全面リニューアルに失敗?して不具合が出ているようです。
今まではトップページが最近の記事一覧だったものが最近の記事の中身が表示されるようになっています。
また、現時点では「SyntaxHighlighter Can't find brush for: arduino」とシンタックスハイライターを使用して整形したソースコード部分が正常に表示されない不具合も起きています。
記事が見づらい状態となっていますが、ココログの状態が元に戻るのかどうかをもう少し見て対応を決めたいと思いますので、今しばらくお待ち下さい。

| | コメント (0)

2019.01.11

VSCodeでArduino

Microsoftが作った「Visual Studio Code」arduino拡張機能を使ってみるを参考にしてVSCodeを導入してみました。

Vscode

インテリセンスを利用したコード編集が出来ることに加えて、ボードや書込装置の種類を指定したり、コンパイルしたプログラムをArduinoにアップロードしたり出来て、シリアルモニターも使用出来ますので、快適な開発環境を得ることが出来ます(ただし、Arduino IDEのインストールは必須です。またPyhton2.7Xも必要なようです)。

| | コメント (0) | トラックバック (0)

2019.01.04

ArduinoでIoT

一時期Raspberry piを使ってIoTらしきことを試していましたが、今回(といいますか今更といいますか)Arduinoを使用したIoTらしきことを試してみました。
 
Raspberry pi(3)では「標準でWiFi」が使用出来たり、「様々な開発環境」を選択したり出来るというメリットがありますが、その一方で実用性を考えた時に「処理速度が上がらない」ことや「Linux(Raspbian)上で動かすため何らかの問題が起きた時の対応にある程度の知識が必要」といったデメリットも感じていました。
 
そこで、今更ながらArduinoってどんな感じなのかちょっと試してみたところ、「標準ではWiFiどころかEthernet(有線LAN)も使えない」、開発環境はArduino IDEくらいしか選択肢がなくしかも使いやすいとは言えない」といったデメリットはありますが、「OSを介さないので余計な知識が不要」、「OSを介していないこともあってか処理速度が早い」といったメリットがあることから、メンテナンス性や処理速度から工場内などのちょっとしたIoT化にはRaspberry piよりも向いているのではないかと感じました。
#Raspberry piの場合、故障してボードを入れ替える場合にはOS(Raspbian)のインストールから始めなくてはなりませんが、Arduinoでは新しいボードにArduino IDEで該当するスケッチを書き込むだけで良いので、だいぶ敷居が低いのではと思います。
 
今回は2種類のボードを入手してその実用性を確認してみました。
今回は、アナログ入力4ポートを使用して、光センサー(CDSセル)の信号を入力してその状態をMQTTサーバーに送信する処理を行っています。
設備の操作盤に配置されている運転中や完了ランプ、判定OK/NGランプに光センサーを貼り付けて設備の起動時と完了時の時間と完了時には判定OK/NG値をMQTTサーバーに送信する「設備稼働状態監視」を想定しました。
 
 
まずはWiFi接続が可能なESP8266を使用したWeMos D1 CH340 WiFi 開発ボード ESP8266 ESP-12F
これはアマゾンで810円で購入しました。
Esp8266
#値段は安いのですが、安いなりに技適を取得していない、MACアドレスが登録されていない、ところに注意が必要です。
 
これはWiFi接続も問題なく、ボード本体だけでデータをMQTTサーバーに送信することが出来たのですが、ESP8266を使用しているための制約なのかアナログポートが1つしか使えないことが判明したため実用化は保留判定です。

次に試したのがArduino Uno互換ボードにEthernetシールドHiLetgo W5100を載せたものです
Ethernetシールドはアマゾンで940円でした(現在は1,200円のようです)。
Uno_eth
 
こちらはアナログポートがフルで使用出来、有線LANへの接続も全く問題なく動作しました。まだ長時間の動作確認は出来ていませんが、これであればEthrnetシールドは必要であるものの、充分実用化が可能だと思います。
 
尚、MQTTサーバーはWindows版のMosquittoをサービスで動かして、ScriberはLazarusを用いで作成したもので全体の動作確認を行いました。
Iotmonitor
 
 
以下が確認用のスケッチです。


/*
設備操作盤の各種ランプの点灯/消灯を光センサ(CDSセル)で読み取って、その状況を
MQTTサーバーに送信するためのプラットホーム

MQTT送信データ形式:経過時間(X.XXX秒), 完了ランプ, OKランプ, NGランプ, 運転中
ランプ, 各ランプのアナログ入力値...
各ランプは点灯=1, 消灯=0で表現する

MQTT Publisher by Ethernet shield
PubSubClientライブラリをインストールしたフォルダ内のサンプルを参考に修正

光センサ(CDSセル)の扱いについてはo0e0oさんの以下の情報を参考にしました
https://matome.naver.jp/odai/2142568740959927501

*/

#include
#include
#include

#define SGN_DONE 0 // (A0)完了ランプ
#define SGN_OK 1 // (A1)OKランプ
#define SGN_NG 2 // (A2)NGランプ
#define SGN_RUN 3 // (A3)運転中ランプ:完了ランプがない場合は代わりに使用する
#define LIGHT_ON 500 // ランプ点灯判定しきい値:実際の条件に合わせて変更が必要

// MQTTサーバーアドレス:実際の接続条件に合わせて修正が必要
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 11, 60); // デバイスの固定IPアドレス・・・端末毎に設定する
IPAddress gateway(192,168, 11, 1); // ゲートウェイ(WiFiターミナルのIPアドレス)
IPAddress subnet(255, 255, 255, 0); // サブネットマスク
IPAddress DNS(192, 168, 11, 1); // DNS

const char* mqtt_server = "192.168.11.18";
// MQTTサーバー接続識別子:何でも良いが会社毎や工場毎で設定することを推奨
const char* clientId = "Publisher-001";
// トピック名(何でも良いが端末が増えた際に識別が容易になるようにすべき)
// 組織名や製品等でiotを変更し、端末毎にdev001を連番で変更することを推奨
const char* mqtt_id = "iot/dev001";

EthernetClient ethClient;
PubSubClient client(ethClient);

char msg[128]; // メッセージ作成バッファ

long lasttm = 0; // Publish時間計測用
long ledfrq = 0; // 内蔵LED点滅タイミング計測用
bool led = false; // 内蔵LED点滅用フラグ

int sgnl_done = 0; // 完了ランプ
int sgnl_ok = 0; // OKランプ
int sgnl_ng = 0; // NGランプ
int sgnl_run = 0; // 運転中ランプ

int done_on = 0; // ランプ点灯=1, 消灯=0
int ok_on = 0;
int ng_on = 0;
int run_on = 0;

int done_prev = 0; // 直前のランプ点灯/消灯状態(1 or 0)
int ok_prev = 0;
int ng_prev = 0;
int run_prev = 0;


// WiFi接続処理
void setup_eth() {
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);

// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}

digitalWrite(LED_BUILTIN, HIGH); // WiFiが接続されたら内蔵LEDをONにする

randomSeed(micros());

Serial.println("");
Serial.println("Ethernet connected");
Serial.println("IP address: ");
Serial.println(Ethernet.localIP());
}

// MQTTのSubScriber データ受信時にコールされる
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}

// MQTTサーバー接続処理
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(clientId)) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outTopic", "hello world");
// ... and resubscribe
client.subscribe("inTopic");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 1 seconds before retrying
delay(1000);
}
}
}

// Arduino初期化
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); // 内蔵LEDポートの初期化
digitalWrite(LED_BUILTIN, LOW); // 内蔵LEDをOFFにする

setup_eth();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}

// メイン
void loop() {
double sec;
char s[16];

if (!client.connected()) {
reconnect();
}
client.loop();

// 現在時間取得
long now = millis();
// MQTTサーバー接続が成功して正常に可動している時は内蔵LEDを点滅させる
if (now - ledfrq > 1000) {
if (led) {
digitalWrite(LED_BUILTIN, LOW); // 内蔵LEDをOFFにする
led = false;
} else {
digitalWrite(LED_BUILTIN, HIGH); // 内蔵LEDをOFFにする
led = true;
}
ledfrq = now;
}
// 光センサ値読み込み
sgnl_done = analogRead(SGN_DONE);
sgnl_ok = analogRead(SGN_OK);
sgnl_ng = analogRead(SGN_NG);
sgnl_run = analogRead(SGN_RUN);

// 光センサの入力値によって点灯ON/OFFを判定する
if (sgnl_done < LIGHT_ON){
done_on = 1;
}else{
done_on = 0;
}
if (sgnl_ok < LIGHT_ON){
ok_on = 1;
}else{
ok_on = 0;
}
if (sgnl_ng < LIGHT_ON){
ng_on = 1;
}else{
ng_on = 0;
}
if (sgnl_run < LIGHT_ON){
run_on = 1;
}else{
run_on = 0;
}
// いづれかのランプが変化(点灯or消灯)したらPublishする
if ((done_on != done_prev) | (ok_on != ok_prev) | (ng_on != ng_prev) | (run_on != run_prev)){
// Publish用のデータ文字列を作成して送信(実際の入力値も確認出来るように後ろに追加する)
sec = (now - lasttm) / 1000.0;
dtostrf(sec, -1, 2, s); // secを小数点以下2桁で文字列にする(unoでは%fが使えない)
snprintf(msg, sizeof(msg), "%s, %d, %d, %d, %d, %d, %d, %d, %d", s, done_on, ok_on, ng_on, run_on, sgnl_done, sgnl_ok, sgnl_ng, sgnl_run);
client.publish(mqtt_id, msg);
Serial.println(msg);

lasttm = now;
done_prev = done_on;
ok_prev = ok_on;
ng_prev = ng_on;
run_prev = run_on;
}
//delay(10); // delayを入れない場合は私が確認したunoの場合2~5msでループします
}

| | コメント (3) | トラックバック (0)

2018.10.02

Lazarusでの日本語文字コード処理その2

先日の記事について追加情報です。
先日の記事ではCharEncStreamが一番のような表現をしていましたが、この関数とCP932ToUTF8には重大な欠陥があることが判りました。
 
実はこれらの関数では「半角カタカナ」を処理出来ないため、UTF-8からShift-JISコードに変換する時点で半角カタカナ文字が欠落してしまいます。
 
ここからテスト用の文字列です。
 
CharEncStreamとCP932ToUTF8では半角カタカナ文字コードが変換されずに欠落してしまう。
アイウエオカキクケコサシスセソ アイウエオカキクケコサシスセソ
 
CP932ToUTF8・・・半角カタカナが欠落したり文字化けしたりしています
Cp932toutf82
 
 
CharEncStream・・・同じです。
Charencstream2
 
 
WinCPToUTF8
Wincptoutf82
 
 
このように半角カタカナを含むShift-JISコードのテキストを変換する場合、半角カタカナも含めて正しく文字コード変換出来るのはWinCPToUTF8関数だけのようです。
 
 

| | コメント (0) | トラックバック (0)

2018.09.30

Naro2Mobi ver1.7

本文、前書、後書内の「行番号」タグを処理していなかったため、前書や後書内の文章や挿絵がうまく取り込めなかった不具合を修正しました。
 
 
「n2mobi170.zip」をダウンロード
 
 

| | コメント (0) | トラックバック (0)

2018.09.28

Lazarus用のレポートコンポーネントについて

過去にDelphiで作成した計測データから判定値とグラフをレポートにするアプリケーションを、今後のメンテナンスのためにLazarusに移植したのですが、レポートコンポーネントでちょっと苦労したもののうまく解決出来たので情報を共有しておきます(実は前の2つのLazarusの記事も、この作業の中で出てきた課題を解決した結果を書いています)。
 
もともとDelphi(7)ではレポート作成にLightReportコンポーネントを使用しており、その後Delphi XE2でDEKOさんのところのLightReport2コンポーネントに置換して使用していました。
一方、Lazarus1.8でのレポート作成用コンポーネントは「パッケージをインストールもしくはアンインストール」で表示されるLazReportがあるのですが、これが使いづらくて(と言いますか、使い方がよくわからない)、LightReport2からの置換が出来ませんでした。そこで何か良いレポート作成コンポーネントがないかと探したところ、Fortes Reportコンポーネントを見つけました。
このコンポーネントはLazarusだけではなくDelphiにも対応しています。配布アーカイブを解凍したフォルダ内のpackagesフォルダ内にあるfrce.lpkがLazarus用、frce.dpkがDelphi用です(Delphiでの動作確認は未実施)。
 
このFortes Reportの各コンポーネントを用いることで、今回の場合に置いてはLightReport2の必要な全てのコンポーネントを置換することが出来ました。また、レポートのデザインもLightReport2と同じ感覚で行うことが出来ますので、LazarusでLightReport2と同じようなことを実現したい方には良いのではと思います。
 
レポートデザインの様子
Designwd
 
動作状態
Sample
 
 
プロジェクトサンプル
「fortesreport.zip」をダウンロード
 
 

| | コメント (0) | トラックバック (0)

2018.09.26

Lazarusでの日本語文字コード処理について

Delphiでは文字列の入力の際に文字コードの違いを自動的に吸収(変換)してくれるのですが、Lazarusでは文字列はUTF-8前提での処理を行うため、日本語を扱う際には多少の工夫が必要になってきます。
例えば、Windows上で蓄積されてきたテキストファイルはまだまだShift-JISコードで保存されたのものが多いと思いますが、残念ながら文字コードがUTF-8前提となっているLazarusでこれらのファイルを普通に読み込むと当然のことながら文字化けを起こします。
私も実際に保存された測定データをLazarusで読み込む処理を書いたのですが、ちょっとハマってしまったので整理してみます。
 
ネット上にはShift-JISコードの文字列は、AnsiToUTF8またはSysToUTF8でUTF-8コードに変換するとの情報があるのですが、実際に試してみると現在のLazarusではShift-JISコードをUTF-8コードに変換してくれません。
 
AnsiToUTF8
Ansitoutf8
 
SysToUTF8
Systoutf8
 
そこで更に情報を探したところ2つの方法を見つけました。ひとつめはLazUTF8ユニットにあるWinCPToUTF8、もうひとつはLConvEncodingユニットにあるCP932ToUTF8です。どちらを使用しても正常にShift-JISからUTF-8にコード変換してくれます。
 
WinCPToUTF8
Wincptoutf8
 
CP932ToUTF8
Cp932toutf8
 
更に、https://torum.jp/2018/01/27/lazarus_unicode-loading-saving-utf-16-files/でCharEncStreamユニットの情報を見つけました。
このユニットを使用すると、読み込んだファイルの文字コードを自動的にUTF-8変換してくれます。Shift-JIS, Unicode(UTF-16) Big Endian/Little Endianは文字コードを自動変換してくれますし、もちろんUTF-8/UTF-8Nも読み込めます。残念ながらEUC-JPやJIS78/83コードは認識してくれませんが、現状これらの文字コードにお目にかかることはほとんどないと思いますので、機能としては十分かと思います。

CharEncStream
Charencstream
 
 

unit Encunit;
 
{$mode objfpc}{$H+}
 
interface
 
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
StdCtrls, LConvEncoding, LazUTF8, CharEncStreams;
 
type
 
{ TForm1 }

TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
OpenDialog1: TOpenDialog;
Panel1: TPanel;
ConvertBy: TRadioGroup;
procedure Button1Click(Sender: TObject);
private
 
public
 
end;
 
var
Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
var
line: TStringList;
enc: TCharEncStream;
begin
with OpenDialog1 do
if Execute then
begin
if ConvertBy.ItemIndex = 4 then
begin
// CharEncStreamを使用する
enc := TCharEncStream.Create; // CharEncStreams
try
enc.LoadFromFile(FileName);
Memo1.Lines.Text := enc.UTF8Text;
finally
enc.Free;
end;
end else begin
line := TStringList.Create;
line.LoadFromFile(FileName);
try
case ConvertBy.ItemIndex of
0: Memo1.Lines.Text := AnsiToUTF8(line.Text); // System
1: Memo1.Lines.Text := SysToUTF8(line.Text); // LazUTF8
2: Memo1.Lines.Text := WinCPToUTF8(line.Text); // LazUTF8
3: Memo1.Lines.Text := CP932ToUTF8(line.Text); // LConvEncoding
end;
finally
line.Free;
end;
end;
end;
end;
 
end.


 
 
「lazcode.zip」をダウンロード
 
 


| | コメント (0) | トラックバック (0)

2018.09.25

Lazarusでの多言語化

Lazarusでの多言語化ですが、ネット上にであまり詳しい情報が見つけられませんでしたので、私が確認した結果を簡単にまとめで見ます。
 
結論から言うと、一部注意しなければならないところはあるものの、意外と簡単に多言語化を実装することが出来ます。
 
多言語化するプロジェクトのオプションダイアログの国際化にある「国際化を有効にする」をチェックし、「PO出力ディレクトリ」に言語翻訳定義ファイルであるPOファイルを保存するためのフォルダを指定します(ここではLanguageを指定)。
Projoption
 
あとは「.lfmを保存する際に~」をチェックしておけば、フォームを保存するタイミングでPOファイルがPO出力ディレクトリ内に自動的に作成されます。
ここで作成されるPOファイル名はプロジェクト名.POとなります。
 
次に、作成されたPOファイルをPOEdit等の編集アプリケーションを使用して他の言語に翻訳します(編集の仕方はネット上を検索してみて下さい)。
尚、準備したPOフォルダファイルはファイル名を「プロジェクト名.PO」から「プロジェクト名.言語名.PO」に変更する必要があります。
例えば、元の名前がProject1.POで翻訳言語が英語の場合には、Project1.en.POとします。
Poediten
  
プロジェクト多言語化のための翻訳ファイルの準備が整ったら、言語を切り替えるための処理をプログラムソース内に記述していきます。
 
手順は簡単で、
・uses節にLCLTranslator世ニットを追加する。
・言語切替イベント処理を追加する。
・必要に応じて、終了時に現在の言語情報を保存する処理や、起動時に言語情報を読み込んで切替える処理を追加する。
となります。
 
言語の切替はSetDefaultLang(言語(, POファイルフォルダ名(, 強制的に書き換えるか)))を使用します。尚、2つ目以降の引数は省略可能です。
 
実際に言語を切替える処理ですが、言語定義ファイルが英語でサブフォルダLanguageにある場合は、
SetDefaultLang('en', ExtractFilePath(Application.ExeName) + 'Language');
の一行で表示言語が英語に切り替わります。
 
以下は注意が必要な点です
 
多言語化したアプリケーションを一旦日本語以外の言語に切り替えた後に日本語に戻そうとして、
SetDefaultLang('ja', ExtractFilePath(Application.ExeName) + 'Language');
としたり、
SetDefaultLang('');
としても日本語には戻りません。

他の言語に切り替えた後に日本語に戻す場合には、アプリケーションを終了して再起動する必要があります。
または、どうしてもリアルタイムで日本語に戻したい場合は、日本語の言語定義ファイル(Project1.ja.PO)を準備して、
SetDefaultLang('ja', ExtractFilePath(Application.ExeName) + 'Language');
を実行するようにします。
POファイルから日本語の定義を作成するのは面倒ですが、POEditを使用する場合は翻訳元の項目を選択してCtrl+Bを押すと、ソーステキストが翻訳後にそのままコピーされるので効率よく作業できます。
とはいっても、翻訳元の情報量が多いと大変なので、その場合には日本語に切替えた際にはダイアログボックスで「日本語表示は再起動後に有効になります」などとメーッセージを表示するだけにしたほうが楽かもしれません。
Poeditja
 
  
プログラムソース中に埋め込まれた文字列はPOファイルに反映されず、言語切替の対象にも出来ません。
対応ですが、ソース中に埋め込む文字列はresourcestring節を追加して、

resourcestring
 Str001 = 'ほにゃらら';
 Str002 = 'ほげほげ';

などと宣言することで作成されるPOファイル内にこれらの定義が保存されますので、後はPOEdit等で翻訳・保存すれば言語切替の対象にすることが出来ます。
尚、これらの宣言はプログラムの中で
 
 Label1.Caption := Str001:
 ShowMessage(Str002);
 
などと通常の変数のように使用できます。
 
 
 
フォームに配置するコンポーネントでTStringsで格納されている文字列はPOファイルに反映されず、言語切替の対象にも出来ません。
対応ですが、上記と同様にコンポーネントに格納するTStringsをコンマテキスト形式でresourcestring内で宣言して、
 
FormCreate等のイベント内でコンポーネントに動的に追加することで、言語切替の対象にすることが出来ます。
 
resourcestring
 RadioGroup1Str = '一番,二番,三番';
 
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
 // 言語切替の初期化
 RadioGroup1.Items.CommaText := RadioGroup1Str;
end;
 
 
DelphiもCommunityEditionが公開されて、無償でほぼフル機能を使用することが出来るようになり、GnuGetTextの出番も無くなるかもしれませんが、Lazarusでも多少注意するところはあるものの、その辺りを克服すると手軽に多言語化が出来るということがわかりました。
自動的に作成されるPOファイルも、既に翻訳済みの部分を保持したまま変更点だけを更新してくれますので、メンテナンス性も高くて好感が持てます。
 
Lazarusも日本語の扱いがこなれつつあるとは言うものの、まだ文字コード処理には癖があるようですので、この辺りももう少し何とかなるといいなと思う次第です。

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus,
  ExtCtrls, StdCtrls,
  LCLTranslator; // 言語切替ユニット
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    MainMenu1: TMainMenu;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    RadioGroup1: TRadioGroup;
    RadioGroup2: TRadioGroup;
    ToggleBox1: TToggleBox;
    ToggleBox2: TToggleBox;
    procedure FormCreate(Sender: TObject);
    procedure MenuItem4Click(Sender: TObject);
    procedure RadioGroup1Click(Sender: TObject);
    procedure ToggleBox1Change(Sender: TObject);
    procedure ToggleBox2Change(Sender: TObject);
  private
 
  public
 
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
// 文字列をそのままプログラムソース内に埋め込むとPOファイルに反映されないので
// resourcestringで文字列を定義して、プログラムソース内で使用する
resourcestring
  Str1 = 'これはプログラムソース中の文字列です。';
  // コンポーネント内にTStringsで格納されている文字列もPOファイルに反映されない
  // のでresourcestringで定義しておいて、コンポーネントに動的に反映させる
  // RadioGroup1はアイテムを静的に設定しているのでPOファイルに反映されず、言語
  // 切替で変更できない
  Str2 = '日本語(&J),英語(&E)';
 
 
procedure TForm1.MenuItem4Click(Sender: TObject);
begin
  Close;
end;
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  // RadioGroup内のアイテムを動的に追加する
  RadioGroup2.Items.CommaText := Str2;
end;
 
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
  inherited;
 
  case RadioGroup1.ItemIndex of           // サブフォルダLanguageを指定
    0: SetDefaultLang('ja', ExtractFilePath(Application.ExeName) + 'Language');
    1: SetDefaultLang('en', ExtractFilePath(Application.ExeName) + 'Language');
  end;
  RadioGroup2.Items.CommaText := Str2;
  RadioGroup2.ItemIndex := RadioGroup1.ItemIndex;
end;
 
procedure TForm1.ToggleBox1Change(Sender: TObject);
begin
  Edit1.Text := Str1;
end;
 
procedure TForm1.ToggleBox2Change(Sender: TObject);
begin
  ShowMessage(Str1);
end;
 
end.

「project1.zip」をダウンロード
 
 
 


| | コメント (0) | トラックバック (0)

2018.09.23

Naro2Mobi ver1.6

N2m

クリップボードを監視して、URLがコピーされたら自動でダウンロードリストに追加する機能を搭載しました。なにげに便利です・・・何でもっと早く気付かなかったのかと今更ながらに思いました。
 
 
「n2mobi160.zip」をダウンロード


| | コメント (0) | トラックバック (0)

«Naro2Mobi ver1.51