【Delphi互換!?】FreePascal/Lazarus その2【GPL】
(クロス)オープンソースコンパイラ FreePascal [i386/68K/PPC/ARM/SPARC]
http://www.freepascal.org/
オープンソース開発ライブラリ等 [IDE/GUI環境 Lazarus]
http://www.lazarus.freepascal.org/
FreePascal/Lazarusのメーリングリスト(Pascalにホエロ!)
ttp://www.freeml.com/lazarus
Q:これで作ったソフトは自動的にGPLになるの?
A:制限付き LGPL だから、自分が作ったソースは GPL にする必要は無い
例え FreePascal 付属のライブラリにリンクしていても GPL にはしなくて良い
http://www.freepascal.org/faq.html#general-license 俺は逆にCをPascalに移植するの好きだけどな。
変にマニュアルとか読むよりも仕様がよくわかるし
何よりもPascalの便利さがわかる。 それはケースバイケースで、CでDLLを作るという手もあるよ。
いずれにせよCでできることはObjectPascalでもほぼできるわけで
慣れれば困るということはないよ。
僕の経験上で今までObjectPascalでできなかったのは
デバイスドライバ開発時のメモリアドレスの絶対指定ぐらいかな。 Delphi3でデバイスドライバーを作ってる人見たが
VCと混合だったかな
うろおぼえ ツールのDelphi Conversionで簡単なDelphiプロジェクトをLazarusに変換したんだけど
コンパイルしようとすると「プロジェクトにメインソースファイルがありません」って出ちゃう
どこをいじったらいいでしょう? >>626
試したけどそのようなエラーは出なかったよ >>626
コンバートで失敗はなかったけど、コンパイルする時に4つエラーが出た
lazarusにはない記述だから仕方ないけど >>628
>>629
レスありがとうございます
もう一度試してだめなら
手作業で変換することにします Shift_JIS漢字を含む文字列をUTF-8文字列に変換したいのですが
AnsiToUtf8関数は見当違いですか?
試してみましたがうまくいきませんでした >>632
>>633
OSはWindows7 64Bitです
うまくいかないのは何かコンパイラ指示とか足りないのでしょうか
他にShift_JISからUTF-8に変換できる関数とかないでしょうか 15年ぶりぐらいでプログラミングを
Lazarus で復帰し、半年ほど前からさわってるけどこうやって変換してるよ。Ver1.6
ただしLConvertEncode Unitの半角カナの扱いにバグがありConverterEncode() で半角カナが消える。
全角とANSIなら問題ない。
LConvertEncodeのasiancodepagefunctions.inc のDBCSToUTF8() のソースコードを少し修正すればOk。
uses
LazUTF8Classes,LazUTF8,.....,LConvEncording;
中略
SL:=TStringList.Create;
try
LoadStringsFromFileUTF8(SL, filename);
for i := 0 to SL.Count - 1 do begin
if GuessEncoding(SL[i]) = 'cp932' then
Memo.Lines.Add(ConvertEncoding(SL[i], 'cp932', 'utf8')) // SJIS to UTF8コード変換
else
Memo.Lines.Add(SL[i]);
end;
finally
FreeAndNil(SL);
end; >>636
C:\lazarus\components\lazutils\lconvencoding.pasのConvertEncoding(SL[i], 'cp932', 'utf8')で半角カナ が消える件
asiancodepagefunctions.inc の下記ルーチンがCP932 SJISの半角カナを正しくハンドリングできていない
function DBCSToUTF8(const s: string; CodeP: integer): string;
:
:
repeat
c := Src^;
Inc(Src);
if Ord(c) < 128 then begin
if (c=#0) and (Src-PChar(s)>=len) then break;
Dest^ := c;
Inc(Dest);
end
else begin
code := Byte(c) shl 8; <---- Ord(c) > $80 の時は無条件に2Byte文字にしているのがNG
c:=Src^;
if (c=#0) and (Src-PChar(s)>=len) then break;
code := code + Byte(c);
Inc(Src); >>636 以下 修正したコードだけど、参考まで。
function DBCSToUTF8(const s: string; CodeP: integer): string;
:
const // 半角カナ 対応
HankakuKanaUTF8Code:array[$A1..$DF] of array[1..3] of Byte
=(($EF,$BD,$A1),($EF,$BD,$A2),($EF,$BD,$A3),($EF,$BD,$A4),($EF,$BD,$A5),($EF,$BD,$A6),($EF,$BD,$A7),($EF,$BD,$A8),
($EF,$BD,$A9),($EF,$BD,$AA),($EF,$BD,$AB),($EF,$BD,$AC),($EF,$BD,$AD),($EF,$BD,$AE),($EF,$BD,$AF),($EF,$BD,$B0),
($EF,$BD,$B1),($EF,$BD,$B2),($EF,$BD,$B3),($EF,$BD,$B4),($EF,$BD,$B5),($EF,$BD,$B6),($EF,$BD,$B7),($EF,$BD,$B8),
($EF,$BD,$B9),($EF,$BD,$BA),($EF,$BD,$BB),($EF,$BD,$BC),($EF,$BD,$BD),($EF,$BD,$BE),($EF,$BD,$BF),($EF,$BE,$80),
($EF,$BE,$81),($EF,$BE,$82),($EF,$BE,$83),($EF,$BE,$84),($EF,$BE,$85),($EF,$BE,$86),($EF,$BE,$87),($EF,$BE,$88),
($EF,$BE,$89),($EF,$BE,$8A),($EF,$BE,$8B),($EF,$BE,$8C),($EF,$BE,$8D),($EF,$BE,$8E),($EF,$BE,$8F),($EF,$BE,$90),
($EF,$BE,$91),($EF,$BE,$92),($EF,$BE,$93),($EF,$BE,$94),($EF,$BE,$95),($EF,$BE,$96),($EF,$BE,$97),($EF,$BE,$98),
($EF,$BE,$99),($EF,$BE,$9A),($EF,$BE,$9B),($EF,$BE,$9C),($EF,$BE,$9D),($EF,$BE,$9E),($EF,$BE,$9F));
// ここまで
begin
:
repeat
:
begin
if (c=#0) and (Src-PChar(s)>=len) then break;
Dest^ := c;
Inc(Dest);
end
else if (CodeP = 932) and (Ord(c) >= $A1) and (Ord(c) <= $DF) then begin // 半角カナ 対応
Dest^ := Char(HankakuKanaUTF8Code[Ord(c)][1]);
Inc(Dest);
Dest^ := Char(HankakuKanaUTF8Code[Ord(c)][2]);
Inc(Dest);
Dest^ := Char(HankakuKanaUTF8Code[Ord(c)][3]);
Inc(Dest);
end // ここまで >>635
ありがとうございます
APIを探してみます
>>636
>>637
>>638
サンプルコードまで書いてくれてすみません
早速試してみます >>636
コードページを使うってことがまったく頭にありませんでした
DelphiならAnsiToUtf8ExとかUtf8ToAnsiExあたりが使えそうですがLazarusにはなさそうで…
>>635
Win32APIを探してみたらMultiByteToWideCharというのが使えそうですね
コードページはCP_OEMCPあたりでしょうか
WideCharからUTF-8はWideStringにしてStringに代入で変換できそうですね
このあたりを使ってコードを書いて見ます >>640
素直に SetStringCodePage を使えば? >>640
あと1.6以降でのUTF16、UTF8の自動相互変換は思わぬところで嵌まることがあるので
1.4以前みたくUtf8EncodeやUtf8Decodeを噛ませておいたほうがいいよ >>640
636だけど良い方法分かったらレポよろしく。
10数年前にDelphi 7を使ったのが最後だったんでLazarusで半角カナ混じりのSJISテキストファイル表示するのに試行錯誤したよ。
知らなかっただけかもしれないが当時はUnix がEUC主流でUTFなんて無かったような。 delphi7は、一応utf-8に変換する関数は用意されてるね。
基本面のみなので、サロゲートペアを適切に扱ってはくれないけど。 一応こんな感じで今のところうまくいっています
1.uses節にWindowsを追加
2.varはこんな感じ
var
SJStr, U8Str: String;
WStr: WideString;
Wlen: Integer;
3.ShiftJIStoUTF8内
WLen:=MultiByteToWideChar(CP_OEMCP,MB_PRECOMPOSED,PChar(SJStr),
Length(SJStr),PWideChar(WStr),0);
SetLength(WStr,WLen);
MultiByteToWideChar(CP_OEMCP,MB_PRECOMPOSED,PChar(SJStr),
Length(SJStr),PWideChar(WStr),WLen);
U8Str:=String(WStr);
//半角Spaceを全角Space ni置き換えています
SJStrはShift_JIS String
U8StrはUTF-8 String
APIを2回Callしているのは1回目で変換後のサイズを取得して2回目で実際に変換しているからです
API出力のUTF-16をPWideChar(array of WideChar)とかで受けて
String(PWideChar(…とかするとうまく変換してくれませんでした
(コンパイルは通るけど)
String(WideString(PWideChar(…なら変換してくれました
なので最初からAPIの出力はWideStringで受けています
しばらくこんな感じで使ってみて不具合が出たらまた考えて見ます
皆さんいろいろな助言をありがとうございました 難しく考え過ぎじゃない?
LazUTF8 か SetCodePage じゃだめなの?
procedure TForm1.Button1Click(Sender: TObject);
var
s, s1, s2: string;
sl: tstringlist;
begin
s:= 'ABCDEFGあいうえおアイウエオ';
s1:= UTF8ToWinCP(s);
Label1.Caption:= LazUTF8.WinCPToUTF8(s1);
s2:= s;
SetCodePage(RawByteString(s2), 932{SJIS}, true);
Label2.Caption:= LazUTF8.WinCPToUTF8(s2);
end; >>648
LazUTF8というのがまったくの初耳でした
WinCPToUTF8であっさりできてしまうんですね
ありがとうございます >>650
テストでテキストファイルに書き出してたのだが
その名残り。削除し忘れた SysUtilsのFileCreate,FileOpen,FileRead,FileWriteは使わないほうがいいですか?
Byteの動的配列をSetlengthしてFileReadに食わせたらFileReadはエラーが出ないけれど
それ以降の動的配列のアクセスすべてで例外が発生します。 >>653
こういう質問のときはエラーになるコードも書いてよ
まぁ状況から察するには
×FileRead(FileHandle, a, Count)
○FileRead(FileHandle, a[0], Count) >>654
すみませんでした。
まさにお察しのとおりでしたありがとうございます。 自分で使う用にリネームツールを作ってたんだけど
もしかしてFileExistsとかRenameFileって2バイトコード対応してないのですかね? 質問するならせめて用語くらいは正しく使おうよ。
2バイトコードがSJISのことだと仮定すると
(なぜならUTF8の日本語は3バイトなので)
Lazの文字コ−ドは標準がUTF8なのでUTF8-SJIS変換をかませる必要がある。
なお、Laz v1.6以降のFileExistsやRenameFileはUTF8にフル対応してる。
Laz v1.4以前は FileExistsUTF8 などを使う必要がある。 >>658
勉強になりました
ありがとうございます これってdelphiで作ったプロジェクトをコンパイルできますか? コンバートできるものとできないものがある。
さすがに修正することが多いですね。 Ubuntu on Windowsでもlazarus動くようになったな >>663
Ubuntu on Windowsってbashがうごくだけじゃないの? WideStringではまってしまった
procedure TForm1.Button8Click(Sender: TObject);
var
str: string;
wstr: widestring;
begin
str:='stringテスト';
wstr:=widestring('stringテスト');
Label22.Caption:=IntToStr(Length(widestring(str))); //9と表示された
Label23.Caption:=IntToStr(Length(widestring(wstr))); //15と表示された
end;
label23は9と表示されてほしかったのに… 予想通りの答えだと思うけど
StringをWideStringでキャストしている意図がわからない >StringをWideStringでキャストしている意図がわからない
バイト数でなく文字数を出すため
Delphi 6で試してみたところ
Length(widestring(str))
Length(widestring(wstr))
は両方とも9になった
Length('stringテスト')=12
Length(widestring('stringテスト'))=9
だった WideString型の値をWideStringにキャストしたら文字数が9 -> 15になったって話か。
裏で走る組み込みの型変換の関数で変換元と先が同じ型かどうかのチェックをサボってるとかかな? str:='stringテスト';
wstr1:='stringテスト'; //15
wstr2:=widestring('stringテスト'); //15
wstr3:=widestring(str); //9
wstr4:=widestring(wstr3); //9
だったから、リテラル→widestring が期待する動作じゃないな
const
str: string = 'stringテスト';
wstr: widestring = widestring(str);
をやってみたら、
ユニコードをAnsiStringにすることはコンパイル時にはできません
なぜなら実行時の文字コードを知らないからです
みたいなエラーが出た
widestringはansistringと同じ扱いなのか? 文字列系は1.6(FPC3.0)で大きく変わったので
まずはバージョンを書こうぜ 多分1.6を使ってるとして返事するけど、
1.6でも、WideString(=UnicodeUtring=UTF16)と
String(=UTF8)を相互に代入するときは1.4以前と同じく
UTF8Decode()やUTF8Encode()を噛ませたほうがいいよ。
理由は詳しくは書かないけど。 バージョンは1.6です
いろいろ試してみたけれどやはりUTF8Decodeが確実でした
あとなぜかWidestring(PChar())のキャストも9になります
Label1.Caption:=InttoStr(Length(Widestring('stringテスト')));//15
Label2.Caption:=InttoStr(Length(Widestring(String('stringテスト'))));//15
Label3.Caption:=InttoStr(Length(Widestring(PChar('stringテスト'))));//9
Label4.Caption:=InttoStr(Length(Widestring(PWideChar('stringテスト'))));//15
Label5.Caption:=inttostr(length(UTF8Decode('stringテスト')));//9 いずれにせよFPC3.0では
文字列のキャストはコードページ付き文字列の導入に伴って
よう分からんことになってるので
1.4以前のようにきちんと文字列型のコードページを把握しつつ
UTF8Decode UTF8Encode その他をきちんと使うのがおすすめ。
なお、UTF16のバイト長の取得は
i:=Length(UTF8Decode('あいうえお')) * 2;
でいいと思う。 気になって、ちょっと古いけどUnicode対応のDelphi XE5で試してみた
おかしな結果にならない模様
ttps://gist.github.com/anonymous/8636175cf9340234cfa452f492b074ee 文字列定数のコードページの初期値が違うので
違う結果になるのは当然。
文字列定数のコードページを同じにすれば同じ結果になるはず。
これ以上深入りしても無駄だと思うけど 10年ぶりにDelphi 無償版リリース!
Delphi / C++Builder 10.1 Berlin Starter Edition が無料でダウンロード可能
注意事項
・無料ダウンロードは2016年8月22日から9月9日までの期間限定
・1回の登録/申請で1ライセンス入手可能
・1つのEメールアドレス/アカウントごとに1ライセンスのみ入手可
[Delphi 10.1 Berlin Starter Edition]
https://www.embarcadero.com/jp/products/delphi/starter/promotional-download
[C++Builder 10.1 Berlin Starter Edition]
https://www.embarcadero.com/jp/products/cbuilder/starter/promotional-download >>679
全部入力したのに[今すぐダウンロード]を押してもダウンロードが開始しない場合は、
Japanを他の国(例えばJamaica)を選択して、またJapanに戻せば、
[今すぐダウンロード]を押せるようになるぞ! >>679 >>681
これはひどいwebフォームだな
テストくらいしてからリリース汁
firefoxだとフォームの項目が一つ少ないな
一番上の性のところでshift+tabを押すと
見えないフォームにフォーカス移動するので
適当にaとか文字打つとダウソ可能になる >>679 >>681
無料Delphiをダウンロードできない場合は、
キャッシュをクリアしてみると良いかもしれない。
ChromeやFireFoxならシークレットウィンドウで開く。 飛び込みでスマソ。Lazarusをダウンロードして使ってみたが、StringGridの最上部の固定行に漢字を入力すると漢字が縦書きで90度左に寝転んでしまう?
可動セルはフォントをメイリオで指定してうまくいった。 固定行のフォントがメイリオなどの横書き可のフォントが設定されていないためだと思うが、解決方法がわかる人教えてください >>679
DelphiとC++の2個いける?
それともどっちか1個? 両方一緒やろ?
儂は Iceweasel で落とした。 >>684
プロパティのColumsで増やすと個別のフォントになってしまう
Colcountで増やせばStringgrid全体でひとつのフォントになる どうしてもColumsで増やしたければオブジェクトインスペクタで該当するTgridcolumnをクリックして
Titleプロパティのフォントを変えていくしかない >>690
さんくす
StringGrid1
Colcount =5
FixedCols =0
FixedRows =1
Font = メイリオのレギュラー
でしているが、最上部の固定行だけは、漢字が縦書きで左90度で寝転んでしまう?
StringGridの2行目以降は漢字の横書きで正常です。 >>693
TitleFontが@付になってるとか… >>695
私の環境では、@MS Pゴシックなどの@付きのフォントを設定すると「サンプル」フォントのプレビューでで漢字横書きになってしまいますし、
2行目以降可動セルの漢字も縦書きになってしまします。
いろいろフォントを変えて試したのですが、「メイリオ」「游ゴシック」「游明朝」が2行目以降の可動セルで漢字の横書きが可能かと思われます。
Lazarusは最新バージョンの1.6です。
また、1行目の固定セルと2行目以降の可動セルのフォントを別々に設定するとは、オブジェクトインスペクタでは出来ないように思います。 訂正
フォントのプレビューでで漢字横書き → フォントのプレビューでで漢字縦書き >>696
自分で書いたプログラム?
OnDrawCellイベントとか使ってない?
再現する短いプログラムとかスクリーンショットとかUPしてくれないとどうも状況がつかめないんだけど… >>698
StringGridのイベントは使ってないのですが、新規にStringGridを作ってみたら、最上部の固定行の横書きが成功しました。
Delphiで作っていたプログラムを移植しようしていたのですが、何かが悪さしているようです。
これが、うまくいっていない画像です。
http://s1.gazo.cc/up/207658.jpg
いろいろ有難うございます。解決の糸口が掴めそうです。 >>699 訂正
新規にStringGridを作ってみたら
→ 新規にStringGridだけのプログラムを作ってみたら >>679
これ電話番号とか入れるの嫌なんだけど。 >>679
これって2個とも同じexeじゃね?
どういうこと? まだインストールしてないけど
インストールキーで機能が決まるんじゃないかな Windows.Beep(p1, p2);
これ使えないのか? どうして?
Buttonが今日は、真っ白の文字無しで表示? 昨日までは何ともなかったのに?
分かる方教えて? >>708
Windows.beep(P1,P2)
うちでは使えてますがねえ
周辺のソース晒したら? こんちには
lazarusのwindows32bit版1.6を使っているのですが
1.codeeditorでマウスクリックすると
その位置までにスペースとかを補って文字入力カーソルを位置設定してまう機能をoffにしたい
2.タブで半角スペース4文字分インデントしたい(pascalは2文字分が伝統?)
3.行末でenterすると次の行が同じ数だけタブで補われて入力開始が出来る様にしたい
tool-option-editor
辺りにありそうな気がするのですが
適当にクリックして設定しても1.2.3.みたいに上手く設定出来ません
何処を設定すれば出来るのか教えてもらえませんでしょうか? 1.ツール→オプション→エディタ→一般→行末までスクロールをオフ
2.ツール→オプション→エディタ→一般→タブとインデント→タブ幅
3.は自動インデントの場合はタブにしたいの? 今月のTips
case 文字列型 of
文字列定数1: ほにゃらら;
文字列定数2: ほにゃらら;
文字列定数3: ほにゃらら;
end
が最新のLazarus(FPC3.0)でできるようになったって知ってた? >715さんどうもです
1.2.は言われた方法で上手くいきました
3.は715さんの言われた通りです
tab tab readln();
みたいに入力した後にenterを押した後
次の行が
tab tab 入力カーソル
みたいな状態にしたい
という事です
今はenter後の次の行が
space space space space space space space space 入力カーソル
みたいにスペースで補われてしまいます
新規行が常にタブで段落を構成するか
前の行に倣うようにしたい
という感じです
それとコンパイルエラーが出た時に表示されるmessagebox欄で
4.表示されるコンパイルエラー説明文字が切れて表示されてしまうのですが
これは環境によるみたいな感じなのでしょうか?
IDE自体は日本語設定に切り替えてフォントはMS 明朝にしているのでその辺りで上手くいって無いのでしょうか?
5.コンパイルエラー内容が切れて見えないので
エラー表示箇所にマウスカーソルを当ててツールチップでエラー内容を見るのですが
表示時間が短いので長くしたいのですが
何処かに設定が有りますか?
お願いします。 3.って「タブをスペースへ」のチェック外さないかぎり無理っぽいよな
タブキー入力したやつは全部タブ文字になるんだろうけど Lazarus 1.6.2 出たのに話題になっていないのね