アフィリエイト広告を利用しています
ファン
検索
<< 2023年10月 >>
1
2 3 4 5 6 7
8
9 10 11 12 13 14
22
23 24 25 26 27 28
29
30 31
最新記事
写真ギャラリー
最新コメント
タグクラウド
カテゴリーアーカイブ
月別アーカイブ
プロフィール
裏目小僧さんの画像
裏目小僧
日別アーカイブ

広告

posted by fanblog

2023年03月05日

LazarusでprintfDebug

Lazarusにはデバッグコンソールがなく GUIアプリだとprintfデバッグが面倒です。
GUI画面が固まる前ならメモ帳でも張り付けて出力出来るのですけどね。

もちろんGUIからでも windows.AllocConsole;でコンソールは開くのですが
その場合 コンソールを手動で閉じてしまうとアプリも落ちてしまいます。
つい邪魔でデバッグ中にコンソールを閉じたつもりでアプリを終了させてデバッグ失敗をなくすために
コンソール窓の右上の[X]を無効にしてしまいます。
それは2か所からの公開ノウハウの組み合わせです。リンクを示しています。
リンク先に感謝を

var MyConsoleWhd: HWND = 0;
MyConsoleBuf:array [0..0] of AnsiChar;
procedure OpenConsole;
var
OldWindowTitle, NewWindowTitle: ansistring;
mHMENU: HMENU;
begin
AllocConsole(); //false=失敗するのは既に開いている時だけ
if MyConsoleWhd = 0 then //初めて呼ばれた時
begin
System.Assign(System.OutPut, 'CONOUT$');
System.ReWrite(System.OutPut);
System.SetTextBuf(System.OutPut,MyConsoleBuf); //バッファがある間は文字が出力されないので
// System.SetTextCodePage(System.OutPut ,GetOEMCP()) ; //これをしても効果ない

// https://learn.microsoft.com/ja-jp/troubleshoot/windows-server/performance/obtain-console-window-handle
NewWindowTitle := format('OpenConsole%15.10f', [now]);
OldWindowTitle := '';
SetLength(OldWindowTitle, 512);
GetConsoleTitleA(@OldWindowTitle[1], 512 - 1); //タイトル文字を保存して
SetConsoleTitleA(pansichar(NewWindowTitle)); //適当なタイトルを付けて
Sleep(40);
MyConsoleWhd := FindWindowA(nil, pansichar(NewWindowTitle)); // 窓ハンドル得る
SetConsoleTitle(pansichar(OldWindowTitle)); //タイトル文字を復元
// https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/896conclosebtn/conclosebtn.html
// [閉じる]ボタンの無効化
if MyConsoleWhd <> 0 then
begin
mHMENU := GetSystemMenu(MyConsoleWhd, False);
RemoveMenu(mHMENU, SC_CLOSE, MF_BYCOMMAND);
end;
end;
end;
コンソールに出力する時、GUIから開いたコンソールではwriteは出来ません。
どうやら stdoutのファイル型 が初期化されていないようです。
上では'CONOUT$'でファイル変数を開くようにしています。(ただしコンソールアプリモードとは挙動が違うようです)
もともとLazarusはUTF8ですからそのままコンソールにwriteで出力すれば文字化けします。
そこで文字化けしない文字列用の出力コマンドの例を

procedure cPutS(s: ansistring);
var
rdSize: DWORD;
begin
OpenConsole; //コンソールのコードページも変更可能だが
// SetConsoleOutputCP(StringCodePage(s));//こうやってもUTF8は文字化けするので
SetCodePage(RawByteString(s),GetOEMCP() ,true); //文字列のコードページを変更する
//せっかく変更しても s+#13#10 と文字列の加算するだけでUTF8に戻るから2行に分ける
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), @s[1], length(s), rdSize, nil);
s := #13#10;
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), @s[1], length(s), rdSize, nil);
//rdSizeは見てない。まあ出力出来なかったらどうしろというのか判らないし
end;
のような関数を別に用意してやります
posted by 裏目小僧 at 08:24| Comment(0) | TrackBack(0) | Lazarus
この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

この記事へのトラックバックURL
https://fanblogs.jp/tb/11891392

この記事へのトラックバック
×

この広告は30日以上新しい記事の更新がないブログに表示されております。

Build a Mobile Site
スマートフォン版を閲覧 | PC版を閲覧
Share by: