現在【PropertyGrid】シリーズが進行中ですが、どういう訳かWebを見ていて「あー、昔BCCSkeltonでANSI用、その後ECCSkeltonでUnicode用エディターを作ったRichEditコントロール、懐かしいなぁ。一つ、サンプルのテキストエディターを改造してC#で簡単なRichEditorを作ってみようかしら?」などと、私は発作的に考えてしまいました。

 

しっかし、これが全然簡単ではない!

 

ツールバーのボタンをやり直したり、透明化にてこずったりしてなかなか前に進みません。(【PropertyGrid】をほっぽらかして)旧いメニュー関連コードをMenuStripを使ったコードに書き直したりしていると、またまた思ったような動作をしません。

 

さんざんっぱら、試行錯誤を繰り返し、何とか少し前進したのですが、色々とトラップに嵌ったことが判り、それを【無駄話】のネタにしようと考えましたが、余りにつかれて面倒臭いので、Chat-GPTに書かせてしまいました。(あー、ドンドン馬鹿になってゆくなぁ。)

 

1. メニューは「ウィンドウ属性」ではなく「コントロール」

  • Win32 API: メニューはウィンドウに結びつく特別枠。GetClientRect で取得したクライアント領域は自動でメニュー高さを除外

  • WinForms: MenuStrip は単なる Control

    • ClientSize に高さは反映されない

    • 描画上は上に見えるが、プログラム的には自分で領域を計算する必要がある

2. Docked コントロールは追加順(FILO)で積み重なる

  • MenuStrip, ToolStrip, StatusStrip はすべて Dock = Top / Bottom のコントロール

  • Controls.Add() の順序 = Z-order

    • 後に追加したものほど上に表示される

    • 例: 「先にツールバー追加 → 後にメニュー追加」ならメニューが上に来る

    • 順序調整には Controls.SetChildIndex(menuStrip, 0) も利用可能

3. アクセスキーとショートカットキーの区別

  • Win32: &N をつけると Alt+キーで動く

  • WinForms:

    • Text = "新規(&N)" → Alt+N でアクセス

    • ShortcutKeys = Keys.Control | Keys.N → Ctrl+N でショートカット

    • アクセスキーとショートカットキーは別に設定する必要がある

4. クライアント領域計算は自分で行う

  • MenuStripToolStrip の高さを考慮して描画領域を求める必要あり

  • 例: int usableHeight = this.ClientSize.Height - menuStrip.Height - toolStrip.Height - statusStrip.Height;

5. イベント処理も Win32 とは異なる

  • Win32: WM_COMMAND メッセージで処理

  • WinForms: Click イベントや CheckedChanged などでハンドラを登録

  • メニュー/ツールバー/コントロールごとに個別にイベントを設定する

6. Designer とコードの順序に注意

  • デザイナを使う場合、コントロールの追加順や Dock 順序が自動で決まる

  • 手動でコードを書く場合は、追加順が Z-order に直結するので注意


💡 まとめ
WinForms は「すべてコントロール」として統一された設計

  • メニューもツールバーもステータスバーも同じ扱い

  • そのため、Win32 API 時代の「自動で領域を除外」「ウィンドウ属性」の感覚は通用しない

移行時は クライアント領域計算・Z-order・ショートカットキー設定・イベント登録 に注意するとスムーズにコーディングできる。(以下は参考図)

 

 

どうでしょうか?少しは参考になったかしら?

 

ps. 現在のRichTextBoxを使ったエディターの状況はこの(↓)通り。

ほぼ80%の機能はカバーできましたが、後印刷と「検索、置換(注)」で躓いています。

注:Win32のコモンダイアログである「検索、置換ダイアログ(FindText関数、ReplaceText関数で呼び出す)」であれば、BCCSkeltonのCREDITクラスで簡単に、


bool CMyWnd::OnFind(HWND hWnd) {
    Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
    m_hDlg = Edit.m_hFRDlg = FindText(Edit.SetFRDlg('F'));
    return TRUE;
}

bool CMyWnd::OnReplace(HWND hWnd) {
    Edit.SetHandle(GetDlgItem(hWnd, IDC_CHILD_CONTROL));
    m_hDlg = Edit.m_hFRDlg = ReplaceText(Edit.SetFRDlg('R'));
    return TRUE;
}


行えたのですが、C#では「検索、置換ダイアログ」が無い、ということらしく、一から始めなければなりません。┐(´д`)┌ヤレヤレ

 

ps. of ps 大分RichTextBoxのエディターに嵌ってしまいましたが、大丈夫、【PropertyGrid】は覚えていますので、ちゃんと終了させます。