[Intro]
[distorted electric guitar riff, driving drums, bass enters]
[Verse 1]
[male vocals]
冷えきったコンクリートの壁にもたれて [palm-muted guitar]
きみは泣いてる
きゃしゃな肩 ふるわせたまま きみはいつまでもないてる
きみの見ている風景は どこまでもすべてが涙色
きみを悲しませるもの そのわけはもうきかないよ
[Pre-Chorus]
[strings enter, restrained emotion, building toward chorus]
ボアコートで包んであげることしか
いま 出来ることはないけど
[Chorus]
[full band energy, open hi-hats]
A Girl 泣かないで 僕がずっとそばにいてあげる
A Girl 抱きしめて きみを離さないでいてあげる
涙が止まるまで いてあげる
笑顔が戻るまで いてあげる
[Instrumental Break]
[syncopated guitar stabs, drum fills]
[Verse 2]
[bass-driven rhythm, light guitar]
e-Mailにつめこまれてるきみの心を 僕は読んでる
震えながらボタン押してる きみの小さな指が浮かぶ
伝えきれないおもいだけ いま きみの心を満たしてる
涙にかえた祈りだけ 文字のむこうがわに見える
[Pre-Chorus]
[strings swell, intensity rising, held back energy]
キーボードにおもい 叩きつけることしか
出来ることはないけど
[Chorus]
[distorted power chords]
A Girl きしんでゆく 胸の痛み 僕が消してあげる
A Girl 壊れそうな きみを離さないで いてあげる
きみがまどろむまで いてあげる
きみがほほえむまで いてあげる
[Bridge]
[guitar solo, high-energy drumming]
[Final Chorus]
[most expressive, full dynamic, emotional peak]
A Girl 泣かないで 僕がずっとそばにいてあげる
A Girl 抱きしめて きみを離さないでいてあげる
涙が止まるまで いてあげる
笑顔が戻るまで いてあげる
[Outro]
[final guitar chord ring out, drum crash]
【Styles】
実際に指定した Styles です。
Eurobeat with an exhilarating, high-speed driving energy in 4/4 time at 160 BPM in the key of A Major. The arrangement features pounding four-on-the-floor kick drums, rapid hi-hat patterns, and punchy snare hits on beats 2 and 4. Bright synthesizer leads carry the melodic lines with shimmering arpeggiated synth layers and driving bassline pulses, with occasional overdriven guitar accents. Male tenor vocals are delivered with a passionate, high-energy tone, soaring into the upper register during the chorus with an anthemic, euphoric quality. The track builds with relentless momentum, featuring dramatic synth breakdowns and explosive chorus drops. Faithful melodic interpretation, preserve original melody.
重要 Cursor とは異なり、Claude Code は基本的に有料です(私は Pro プランに加入しました)。
任意の作業フォルダを指定して、実際のコードの編集まで AI にお任せしたい場合は、ブラウザ版ではなく、デスクトップアプリ版を使う必要があるようです。ですので、私は My PC にデスクトップアプリ版をインストールしてあります。以下、デスクトップアプリ版に限定した機能のご紹介であることを念頭にお読みください。
Claude Code の自動モードを指定してコードの修正作業まで行いますので、作業対象フォルダの内容を任意の別フォルダに全てコピーし、バックアップを作成します。この作業さえきちんと行っておけば、もし、期待通りの結果が得られなくても、書き換え元としたコードはそのまま残るので安心です。
Claude Code のタブも Code をクリックして切り替えておきます。
さらに、作業対象とする(Delphi のプロジェクトファイルがある)フォルダを指定しておきます。
赤い枠の中をクリックして任意のフォルダを指定します。
フォルダを指定する際、次の確認画面が表示されます。
Claude Code を信じて「ワークスペースを信頼する」をクリックしました!
3.プロンプトを書く
Claude Code を起動し、直接、プロンプトを入力してもよいのですが、私はどうしても入力途中で(半角英数字を入力している際など)余計に Enter キーを押し下げてしまうことが多く、他の AI を使用している時もそうなのですが、プロンプトを入力している最中にまだそれが未完成のまま、AI に渡してしまいがちです。
Claude Code が優秀であるため、(私の経験した範囲では)これまで問題が発生したことなどただの1回もありませんが、そこは慎重を期して「コードの修正は実行しない」よう、プロンプトで明示しておきます。私はどんな作業でも、このように「まずプログラムをチェックして、修正案を提示してもらう」ことから始めています。
また、私に Claude Code を教えてくれた職場の仲間は、作業内容に合わせて使用するモデルも変更していると言っていました。ハイレベルな作業ほど、高性能のモデルを使うのだそうです。ただ、知能が低レベルな私には「ハイレベルな作業」といった場合の「ナニ」が「ハイレベル」なのかがわかりませんので、常に、いちばん上位のモデルのまま実行しています。
良い機会なので調べて見ました。
あとどれくらいそのモデルを使えるか、その残量を知るには Claude Code で /usage を実行すればよいと Claude Code 自身に案内されたので、早速実行してみました。現在の使用状況・リセットまでの目安が表示されました。それが唯一確実な「あとどれくらい使えるか?」の情報源なのだそうです。
プロンプト入力欄に /usage を入力して Enter キーを押し下げます。今回の Checked プロパティ修正作業での状況です。
Claude Code 自身から「Pro で Opus を使う場合は消費が速いので、普段の実装は Sonnet、影響調査や難所の判断だけ Opus に切り替える運用にすると、限られた Opus 枠を有効に使えます」というアドバイスをいただきました。
つまり・・・ 私は、もったいない使い方をしている・・・ ということなのかな?
5.実装と実装結果
【実装】ただ待つだけです!
【結果】以下の通りです!
配点チェックボックスをチェックして、配点等入力モードにします。
余白が広いのはご愛敬
Q01 の観点を「2」に変更してみます。
配点チェックボックスの Enabled は自動的に False になりました!
期待した通り、変更を保存しないと採点モードには戻れません。なので、保存してみます。
(保存ボタンをクリックしました!)
上書き確認のメッセージが表示されます。デフォルトは「いいえ」に設定。
「はい」をクリックします。データが上書き保存され・・・
配点チェックボックスの Enabled は自動的に True になりました!
実際のプログラムでは、続けて次のメッセージが表示されます。
「はい」をクリックすると配点等入力モードから、採点モードへ切り替わります。
採点モードに戻りました。配点チェックボックスのチェックも外れています。成功です。
6.まとめ
Claude Code (有料)のデスクトップアプリ版を利用すれば、Delphi のコードエディターの画面を1回も表示せずに、コードの修正が可能でした。
[Intro]
[clean electric guitar arpeggios, bright piano melody]
[Verse 1]
[male tenor vocals, bass and light percussion enter]
目が覚めて一番最初に思い出すのは君さ
どんな朝も
俯いてるその横顔だけ
いつも心のどこかにある
[Pre-Chorus]
[strings enter, building intensity]
悲しませてしまったことばかり
君は微笑みだけ返し続けて
ここで流した涙の数だけ
君が幸せになれるように
[Chorus]
[full band, distorted guitar power chords]
It's you 見つめてるよ いつも君の面影を抱いて
どんなときも
[Instrumental Break]
[piano and clean guitar melody]
[Verse 2]
[drums drop to light kick and hi-hat]
気が付いてた 君がいることに
あのフロアーに満ちた君の香り
少し甘く どこか切なくて
きしむ胸に抱きしめて 離せない
[Pre-Chorus]
[strings swell]
朝の眩しさの向こう側で
振り返る君をただ見つめてた
素直な気持ち いつも隠したまま
涙浮かべて 俯かないで
[Chorus]
[driving drums, layered vocal harmonies]
It's you 見つめてるよ いつも君の面影を抱いて
どんなときも
[Bridge]
[half-time feel, piano focus]
今振り返れば 言葉を失くして
ただ胸に浮かぶよ 君の微笑み
瞳閉じたまま ゆっくり歩いてく
君を待てなかった 僕のせいさ
[Final Chorus]
[most expressive, full dynamic, emotional peak, English lyrics sung with passionate clarity]
It's you 見つめてるよ いつも君の面影を抱いて
I'm never without you
[Instrumental Solo]
[clean electric guitar melody with delay]
[Outro]
[drums and bass drop out, clean guitar arpeggios and piano]
目が覚めて一番最初に思い出すのは君さ
どんなあさも
[final piano chord]
・歌詞の表記方法について
歌詞の末尾が「どんな朝も」でないことには理由があります。漢字で「朝」と表記すると、SUNO は「朝」を「とき」と読んで(発声して)しまうことが複数回ありました。日本語には、古語でも「朝(あさ)」を「とき」と読む文化はないはずだと不思議に思い調べて見ると、やはりこれは音楽生成 AI の誤読のようです。音楽生成 AI の内部表現では、「朝」と「時」が似ているのでしょうか? 誤読理由の詳細はわかりませんが、誤読を避ける対策として歌詞の表記を「どんな朝も」ではなく、「どんなあさも」とした次第です。(この Blog の本来の目的は、このような Tips の紹介・メモでした!)
J-Pop power ballad. Clean electric guitar arpeggios and a bright piano melody lead the arrangement. A male tenor vocal delivers a melodic performance with light vibrato. The drums feature a standard rock kit with a prominent snare and steady eighth-note hi-hats. A melodic electric bass follows the kick drum patterns. Distorted electric guitar power chords enter during the chorus to provide harmonic density. The track is in the key of G Major with a tempo of 74 BPM. The arrangement alternates between sparse, guitar-driven verses and full-band choruses with layered vocal harmonies. Orchestral string pads provide sustained harmonic support in the background.
High-energy Eurobeat with relentless rhythmic drive and dazzling synth textures.
Four-on-the-floor kick with pulsing synth bass. Bright saw-wave synth leads carry
the melody with syncopated hooks and arpeggiated runs. A second synth adds staccato
chord stabs on offbeats. Sixteenth-note hi-hats throughout, snappy snare on beats
two and four, crash accents on transitions. A filter rise builds into each chorus, releasing into layered synths and driving percussion. Tenor male vocals
deliver a luminous, velvet-husky tone, transparent at the surface with smoky depth
beneath. The vocal drives forward with urgent, breathless phrasing that never
settles, chasing the beat as if each moment is already slipping away. A bittersweet
ache runs beneath every note, fragile and fleeting, like light caught briefly on
broken glass. In the choruses, the voice soars with airy, glass-like clarity,
pouring out a desperate tenderness that burns brightest just before it fades.
175 BPM, A Major, 4/4.
[Intro]
[solo piano, soft arpeggios, gentle and reflective]
[Main Section]
[Verse]
くじけそうな あのふゆのよるにきみとみた
やさしい でかいほしは いま どこにかがやくんだろう
ねがいごとは まるでかなわなかったけれど
だれよりも やさしいきみの えがおはあのひのままさ
[Pre-Chorus]
[bridge melody leading into chorus, building tension]
ふたりのゆめ かなえるために とおいとおいまちへいったきみ
でもね きみと わかれるのは なによりもつらすぎて
[Chorus]
[full dynamic, powerful and soaring, emotional release]
くじけそうな時は 空への階段をかけあがり
君の手紙を読むんだ 涙をこらえたまま
こわれそうな夜は 星への階段をかけのぼり
君の名前叫ぶんだ 涙をこらえたまま
[Bridge]
[piano solo, sparse and introspective, breathing space]
[Main Section]
[Verse]
なにもかもなくしたけど まだ かこにはできないけど
きみだけはしんじてくれた ぼくのなかのほんとのこと
とどかなかったおもいも かえらなかったきもちも
すべてを このうたにして いま ぼくはここでいきてる
[Pre-Chorus]
[bridge melody leading into chorus, building tension]
うらぎりとごかいのまんなかで ゆかにてをついたぼくだけど
あのたまらなかったしゅんかんも いまはかがやいてる
[Chorus]
[full dynamic, piano surging, passionate and soaring, emotional release]
くじけそうな時は 空への階段をかけあがり
君の手紙を読むんだ 涙をこらえたまま
こわれそうな夜は 星への階段をかけのぼり
君の名前叫ぶんだ 涙をこらえたまま
[Interlude]
[piano solo, reflective]
[spoken-word style, hushed and intimate]
すべてはひげきにむかったけど しんじつはあのこのむねのなかに
かれらのいうことのまちがいが いまならわかるはずさ
[Final Chorus]
[most expressive, full dynamic, emotional peak]
くじけそうな時は 空への階段をかけあがり
君の手紙を読むんだ 涙をこらえたまま
こわれそうな夜は 星への階段をかけのぼり
君の名前叫ぶんだ 涙をこらえたまま
[Outro]
[piano solo, sparse and delicate, decrescendo]
[final single piano note, long sustain, fade out]
【Styles】
Japanese ballad with a pure, intimate atmosphere. Solo piano is the sole
accompaniment throughout, opening with gentle arpeggios and soft pedal tones
that establish a fragile, tender mood. The piano delivers the main melody with
expressive rubato phrasing and shifts dynamically from delicate whispers in the
verses to fuller, resonant chords in the choruses. No other instruments are
present. Female vocals are pure and crystalline, with a luminous, glass-like
clarity that floats effortlessly above the piano. The voice carries a quiet
emotional depth, transparent on the surface with a gentle ache beneath each note.
Phrasing is unhurried and deeply expressive. In the choruses, the voice opens
with warm, radiant intensity while retaining its pristine clarity. A brief
interlude features hushed piano and a whispered vocal passage before the final
chorus rises to an emotional peak. The piano returns alone in the outro, fading
to silence on a single sustained note. 58 BPM, A Major, 4/4.
J-Pop rock track with a driving, upbeat arrangement. Features bright, overdriven electric guitars playing rhythmic power chords and melodic lead lines. A clean electric guitar provides arpeggiated textures in the verses. The bass guitar follows the kick drum with a consistent eighth-note pulse. Drums consist of a standard rock kit with a prominent snare on beats 2 and 4 and active hi-hat patterns. Male vocals are delivered with a passionate, melodic tone, occasionally reaching into a higher register during the chorus. The arrangement includes subtle synthesizer pads and occasional piano accents. Tempo is 180 BPM in the key of A Major.
赤い枠囲み部分をクリック(ショートカットを利用するなら Ctrl + Shift + X を実行)して、検索バーを表示し、Japanese Language pack と入力するだけで自動的に検索が実行され、表示された検索結果の上のほうにある Japanese Language Pack for VS Code をクリックすると、その右側に Install ボタンが表示されるので、こちらをクリックしてインストールを実行します。
下記の不具合は、5月29日現在、修正し、解消されています。マークシート側で「配点」を1回クリックして Check を ON にして採点データを読み込んでいただければ、マークシートの採点結果と手書き答案の採点結果の両方を表示した採点結果通知シートが印刷できると思います。ご迷惑をおかけした皆さま、誠に申し訳ありませんでした。
一般的に使用されている複合機のスキャナーでスキャンした PDF ファイルは、Jpeg 画像のコンテナのような形式で作成されていることが多いと聞き、MS_Reader V3 には、そのような PDF ファイルであった場合、Jpeg 画像を抽出する機能も搭載しましたが、様々なスキャナーで作成されたPDF ファイルを入手し、必要十分な動作テストを行うことは私の環境では不可能でありますので、この PDF ファイルから Jpeg 画像を抽出しての処理は、その可否をご確認の上、可の場合でも必要十分な動作テストを実施後にご利用ください。
なお、筆者の職場にあります E 社製複合機のスキャナーで解像度 200 dpi、カラー、PDF を指定して読み込んだデータを用いた動作検証を行い、プログラムが意図した通りに動作することを確認しましたことを申し添えます。
一般的に使用されている複合機のスキャナーでスキャンした PDF ファイルは、Jpeg 画像のコンテナのような形式で作成されていることが多いと聞き、MS_Reader V3 には、そのような PDF ファイルであった場合、Jpeg 画像を抽出する機能も搭載しましたが、様々なスキャナーで作成されたPDF ファイルを入手し、必要十分な動作テストを行うことは私の環境では不可能でありますので、この PDF ファイルから Jpeg 画像を抽出しての処理は、その可否をご確認の上、可の場合でも必要十分な動作テストを実施後にご利用ください。
なお、筆者の職場にあります E 社製複合機のスキャナーで解像度 200 dpi、カラー、PDF を指定して読み込んだデータを用いた動作検証を行い、プログラムが意図した通りに動作することを確認しましたことを申し添えます。
Windows の OpenCV は Visual C++ でビルドされており、そのビルドに使われた特定バージョンのVisual C++ ランタイム DLL がシステムフォルダに存在しない場合、OpenCV が起動できないため、vcredist でその DLL を所定の場所にインストールする必要があります。
同梱のマークシートメーカーは PDF ファイルの出力に Skia を使用しています。Skia のライセンスは MIT ライセンスです。このライセンスの詳細につきましては、マークシートメーカーのフォルダに同梱した Skia4Delphi_and_Skia_LICENSE.txt をご覧ください。マークシートメーカーの使い方の詳細については、当 Blog の過去記事をご参照ください。
AI にコードを書いてもらって、それを試してみる時など、「絶対に動く」保証などどこにもありませんから「現在、不満を抱えつつも or 不備を内包しつつも、捨てるに捨てられない procedure / function はとりあえずコメント化」して、その上か下に(私は下ですが) AI が書いてくれたコードを貼り付けて試す・・・みたいなことを、どなた様も普通におこなっていらっしゃる今日この頃のではないかと思うのですが、その際問題になるのがコメント化の方法です。Delphi のコメント化の場合、もちろん使用するのは、それが1行、2行なら // で、それが複数行にわたる場合は皆さま { } だと思うのですが、
タイトル名でマークシート設定を管理( INI ファイルに保存&呼び出し)しますので、教科 or 科目の名称、考査の時期、日付等を入れておくと管理しやすいのではないかと思います。Edit コントロールへ入力すると同時にマークシートの描画も更新されます。入力確定後、再度 Enter キー押し下げで、次のコントロールへフォーカスが移動します。
新しく作成中のマークシートリーダーでも、もちろん、この大語群対応マークシートが読めるようにしてありますが、まだ実際の試験で使用して問題がないかどうかの確認を行っていませんので、現時点での公開はできませんが、この Blog で過去に公開してきたマークシートリーダーより、読み取り速度は比較にならないくらい高速化することに成功しています。設定によりますが、輪郭検出を最初の1枚のみに限定した場合で、私の PC では、1秒間に約47,500マークを読み取り可能です。
設定の保存ボタンをクリックすると、現在表示されているマークシートの設定が exe と同じ場所に自動的に作成される INI ファイル内に「タイトル名をセクション名として」保存されます。次回、プログラムを起動する際、プログラムは自動的に INI ファイル内のセクション名を取得して、タイトルを表示する ComboBox の選択肢に設定します。
セクションの削除と、画面の表示は、『連動しない仕様』としてある点にご注意願います。
例えば、「情報Ⅰ」と「情報Ⅱ」の2種類のマークシート設定があり、「情報Ⅱ」を表示している状態で「情報Ⅱ」のセクションを INI ファイルから削除したとします。
上のリンク先『ダウンロードとプロダクト キー』へ行き、表示される画面の左側の『Developer Tools』に『Visual Studio 2022』(リンク)をクリック。
表示されたページの中ほどに「Visual C++ Redistributable for Visual Studio 2022」があるので、その右側の ComboBox みたいな部分で x64 を x86 に変更して『ダウンロード』ボタンをクリック。
「Visual C++ Redistributable for Visual Studio 2022」は「VC_redist.x86.exe」で保存されました。これをインストールすると、2015 以降のランタイム(2015, 2017, 2019, 2022)は統合されているため、「Visual C++ 2015 Redistributable」も含まれてインストールされるようです。
private
{ Private 宣言 }
FBitmap: TBitmap;
// Rubber band
FRubberBandActive: Boolean;
・・・(省略)・・・
function ScreenToImagePoint(X, Y: Integer): TPoint;
で、次のように記述。
function TForm1.ScreenToImagePoint(X, Y: Integer): TPoint;
begin
Result.X := Round(X / FZoom);
Result.Y := Round(Y / FZoom);
end;
次は、PointInRectInclusive 関数を作成。まず宣言して、
private
{ Private 宣言 }
・・・(省略)・・・
function ScreenToImagePoint(X, Y: Integer): TPoint;
function PointInRectInclusive(const R: TRect; const P: TPoint): Boolean;
Shift+Ctrl+C して、次のように記述する。
function TForm1.PointInRectInclusive(const R: TRect; const P: TPoint): Boolean;
begin
Result :=
(P.X >= R.Left) and (P.X <= R.Right) and
(P.Y >= R.Top) and (P.Y <= R.Bottom);
end;
function TForm1.GetHandleAtPosImg(const P: TPoint): THandlePos;
const
HSIZE = 8;
var
cx: Integer;
begin
Result := hpNone;
// Top
cx := (FRubberRect.Left + FRubberRect.Right) div 2;
if Abs(P.Y - FRubberRect.Top) <= HSIZE then
begin
if Abs(P.X - FRubberRect.Left) <= HSIZE then Exit(hpLeftTop);
if Abs(P.X - FRubberRect.Right) <= HSIZE then Exit(hpRightTop);
if Abs(P.X - cx) <= HSIZE then Exit(hpTop);
end;
// Bottom
if Abs(P.Y - FRubberRect.Bottom) <= HSIZE then
begin
if Abs(P.X - FRubberRect.Left) <= HSIZE then Exit(hpLeftBottom);
if Abs(P.X - FRubberRect.Right) <= HSIZE then Exit(hpRightBottom);
if Abs(P.X - cx) <= HSIZE then Exit(hpBottom);
end;
//Left /Right
if Abs(P.X - FRubberRect.Left) <= HSIZE then Exit(hpLeft);
if Abs(P.X - FRubberRect.Right) <= HSIZE then Exit(hpRight);
end;
次は、CursorFromHandle 関数を宣言。
private
{ Private 宣言 }
・・・(省略)・・・
function CursorFromHandle(H: THandlePos): TCursor;
こちらも Shift+Ctrl+C して、次のように記述する。
function TForm1.CursorFromHandle(H: THandlePos): TCursor;
begin
case H of
hpLeft, hpRight:
Result := crSizeWE;
hpTop, hpBottom:
Result := crSizeNS;
hpLeftTop, hpRightBottom:
Result := crSizeNWSE;
hpRightTop, hpLeftBottom:
Result := crSizeNESW;
else
Result := crDefault;
end;
end;
procedure TForm1.UpdateRubberCursor;
begin
if FRubberBandActive then
PaintBox1.Cursor := crCross
else
PaintBox1.Cursor := crDefault;
end;
次は、PaintBox の OnMouseMove 手続きを作成。
オブジェクトインスペクタの OnMouseMove をダブルクリックする。
こちらは、次のように記述する。
procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
curImg: TPoint;
screenPt: TPoint;
dx, dy: Integer;
H: THandlePos;
begin
if not FRubberBandActive then Exit;
curImg := ScreenToImagePoint(X, Y);
//ドラッグ中のみ自動スクロール
if FDragging then
begin
screenPt := PaintBox1.ClientToScreen(Point(X, Y));
AutoScrollIfNeededFromScreen(screenPt);
end;
//矢印キーの形状をより適切に
if not FDragging then
begin
if FHasRubber and PointInRectInclusive(FRubberRect, curImg) then
begin
H := GetHandleAtPosImg(curImg);
if H <> hpNone then
PaintBox1.Cursor := CursorFromHandle(H)
else
PaintBox1.Cursor := crSizeAll; //内部=移動
end
else
PaintBox1.Cursor := crCross; //ラバーバンド描画モード
Exit;
end;
dx := curImg.X - FStartPointImg.X;
dy := curImg.Y - FStartPointImg.Y;
if FModeMoveSize then
begin
FRubberRect.Offset(dx, dy);
end
else
begin
case FDragHandle of
hpLeftTop:
begin
FRubberRect.Left := curImg.X;
FRubberRect.Top := curImg.Y;
end;
hpTop:
FRubberRect.Top := curImg.Y;
hpRightTop:
begin
FRubberRect.Right := curImg.X;
FRubberRect.Top := curImg.Y;
end;
hpRight:
FRubberRect.Right := curImg.X;
hpRightBottom:
begin
FRubberRect.Right := curImg.X;
FRubberRect.Bottom := curImg.Y;
end;
hpBottom:
FRubberRect.Bottom := curImg.Y;
hpLeftBottom:
begin
FRubberRect.Left := curImg.X;
FRubberRect.Bottom := curImg.Y;
end;
hpLeft:
FRubberRect.Left := curImg.X;
hpNone:
begin
FRubberRect.Right := curImg.X;
FRubberRect.Bottom := curImg.Y;
end;
end;
end;
FStartPointImg := curImg;
NormalizeRect(FRubberRect);
//画像エリアを超えないよう制限
if FRubberRect.Left < 0 then FRubberRect.Left := 0;
if FRubberRect.Top < 0 then FRubberRect.Top := 0;
if FRubberRect.Right > FBitmap.Width then FRubberRect.Right := FBitmap.Width;
if FRubberRect.Bottom > FBitmap.Height then FRubberRect.Bottom := FBitmap.Height;
PaintBox1.Invalidate;
end;
procedure TForm1.EnsureRubberVisible;
var
R: TRect;
p: TPoint;
begin
R := ImageToScreenRect(FRubberRect);
p := PaintBox1.ClientToScreen(Point(R.Left, R.Top));
AutoScrollIfNeededFromScreen(p);
end;
procedure TForm1.UpdateRubberInfo(const Prefix: string);
var
R: TRect;
begin
if not FHasRubber then Exit;
R := FRubberRect;
if Memo1.Lines.Count = 0 then
Memo1.Lines.Add('')
else
Memo1.Lines[Memo1.Lines.Count - 1] := ''; //最終行を書き換える
Memo1.Lines[Memo1.Lines.Count - 1] :=
Format('%sL:%d T:%d W:%d H:%d',
[Prefix, R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top]);
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if not (FRubberBandActive and FHasRubber) then Exit;
case Key of
VK_LEFT:
if ssShift in Shift then Dec(FRubberRect.Right)
else FRubberRect.Offset(-1, 0);
VK_RIGHT:
if ssShift in Shift then Inc(FRubberRect.Right)
else FRubberRect.Offset(1, 0);
VK_UP:
if ssShift in Shift then Dec(FRubberRect.Bottom)
else FRubberRect.Offset(0, -1);
VK_DOWN:
if ssShift in Shift then Inc(FRubberRect.Bottom)
else FRubberRect.Offset(0, 1);
end;
NormalizeRect(FRubberRect);
PaintBox1.Invalidate;
//ラバーバンドの座標を取得
UpdateRubberInfo('Key ');
end;
現在、Image1上に描画されているラバーバンドの座標を取得するコードです。 ごく一般的な記述では 3-a の座標形式だと思いますが、実際の運用では解答欄の矩形座標を取得し、これを保存する際、印刷やスキャン時のズレの問題を解消するため、画像上の特徴点からの距離で座標を記録するようにしていますので、3-b はその例となっています。
AI と会話しない日がなくなって久しいです。彼(彼女?)は時々間違えることもあるけれど、その間違いを見抜く力さえあれば、Google 先生とあわせて活用することで、調べものにかかる時間と手間を大いに軽減できて、すーぱー Goooooooooooooooooooooood!!← アボガドロ数的感情表現のつもり。
動作テストを重ねるうちに、削除対象文字としてこの TRichEdit に指定した絵文字の数が激増し、それでも(おかしいなー!)と思いつつ都度『新発見絵文字』を気持ち半分喜びながら毎日追加しておりましたが、日々増え行く絵文字列が2行目の折り返しを間近に控えた頃、ようやく『 AI が使用する絵文字の種類は限定されてるに違いない』という自身の強い思い込みが『完全な誤り』であることに気づき(かつ、TRichEdit は絵文字に完全対応ではないみたいな話を AI から聞いたこともあり)、個別にいちいち指定する方式から一括削除する方式に仕様を変更したという、微笑ましくもどこか悲しい、ごく私らしい個人的なエピソードもあります。
「マークダウン表記を平文にする」をチェックした場合は、Form のキャプション(タイトル)が『MarkdownRemover』と表示されますが、チェックを外すと Form のキャプション(タイトル)が『CharSweeper』と変化するのは、用途に応じた必要な機能の提供という部分へのこだわりをタイトル的に表現したものです。名前が変わるプログラムなんて私は見たことがありませんが・・・
AI とチャットした際、その会話内容は AI の方で勝手に保存してくれますが(ただ、過去のチャットの「特定部分」を探すのがエライ面倒なことも多々あり、やはり、自分にとって『走召!』重要な情報は別に保存しておきたいなー!みたいな気が・・・私はしますし)、会話の特定部分を資料的に印刷等して活用したい場合は、どうしてもプレーンテキストでないと困る場合が・・・自分的には・・・ほとんどですと言うか、はっきり言って全部です。
それより何より、Pandoc はライセンスが GPLv2 or later ですので、法的な問題をきちんとクリアしないと Pandoc を利用したアプリケーションはもちろん公開できません。これが最大の理由で、Pandoc の利用を今回はあきらめることにしました。(個人的にはもちろん!試用してみました。デフォルト設定のまま動かしてみたのですが、コードブロックの変換部分で、インデントの処理に独自ルールが適用されるようで、変換結果のプログラミングコードをコピペする際にちょっと困るかもと思いましたが、その他は期待通りに動作しました)
//削除対象として検索する絵文字の範囲
if not (
(code >= $1F600) and (code <= $1F64F) or // 顔文字
(code >= $1F300) and (code <= $1F5FF) or // 天気・場所・物
(code >= $1F680) and (code <= $1F6FF) or // 乗り物・地図
(code >= $2600) and (code <= $26FF) or // 記号
(code >= $2700) and (code <= $27BF) or // その他記号
(code >= $FE00) and (code <= $FE0F) or // 表示スタイル
(code >= $1F900) and (code <= $1F9FF) or // 拡張絵文字
(code >= $1FA70) and (code <= $1FAFF) // Emoji 13以降
) then
このプログラムでは、開始時に音量設定が0でなければ自動消音し、終了時に開始時の音量設定を復元しています。なぜ、そのようにしたかというと、周囲に人がいるような環境では Beep 音が鳴らない方がよいと思ったからです。「入力ミス」などがあった際にユーザーに対して注意喚起するような目的で使われるこの音ですが、一人で PC を使用していてもメッセージが表示された際などに鳴ると結構(私は)気になります。
//Ctrl+Cで選択範囲をクリップボードへ送る
if plImage1.Visible then
begin
//Ctrl + C(Shiftを含まない)のみ許可
if (Key = Ord('C')) and (ssCtrl in Shift) and not (ssShift in Shift) then
begin
//plResizeImage の「クリップボードへ送る」を実行
if Assigned(plImage1.MenuClipboardRef) then
begin
plImage1.MenuClipboardRef.Click;
end;
//ショートカットキーを他に伝播させない
Key := 0;
end;
end;
これで Ctrl + C で、ラバーバンドで囲んだ範囲を、クリップボードへ画像データとして送信できるようになりました。