Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
PR の目的
「ファイルを開く」および「名前を付けて保存」ダイアログにて、「最近のファイル」・「最近のフォルダ」コンボボックスにフォーカスがある状態で Ctrl+Backspace を押すとクラッシュします。
#1470 の機能追加による劣化バグで、本PRはその修正が目的です。
カテゴリ
PR の背景
問題の原因ですが、コンボボックスをサブクラス化する処理が CBS_DROPDOWNLIST (編集できないコンボボックス)を考慮していなかったことです。
SetComboBoxDeleter 関連のコードは、API関数 GetComboBoxInfo を通じて コンボボックス内部の Edit のハンドルを入手できることを前提としています。編集可能なコンボボックスでは期待通りにEditを取得できますが、CBS_DROPDOWNLIST スタイルのコンボボックスに対して同じことをすると結果は ComboBox のハンドルになってしまいます。このケースを考慮できていませんでした。
sakura/sakura_core/dlg/CDialog.cpp
Lines 813 to 816 in 526f512
hwndCtl が CBS_DROPDOWNLIST スタイルのコンボボックスだった場合、info.hwndItem に ComboBox が入った状態で返ってくるため、Edit をサブクラス化するつもりで ComboBox をサブクラス化することになります。
sakura/sakura_core/dlg/CDialog.cpp
Lines 767 to 770 in 526f512
ここで Edit の親(=ComboBox)を取得しようとして ComboBox の親(=ダイアログ)を取得してます。
sakura/sakura_core/dlg/CDialog.cpp
Lines 781 to 785 in 526f512
hwndCombo はダイアログです。CB_GETEDITSELには反応してくれません。
selStart
とselEnd
は未初期化のままです。sakura/sakura_core/dlg/CDialog.cpp
Lines 793 to 798 in 526f512
length
は 0、text
はL'\0'
が入った長さ1の配列となります。selStart
が偶然0になっていなければDeletePreviousWord
の中で Access Violation が発生します😢仕様・動作説明
問題に対する対処として、CBS_DROPDOWNLIST スタイルのコンボボックスに SetComboBoxDeleter を適用しないことにします。該当するのは「ファイルを開く」および「名前を付けて保存」ダイアログ下部のそれです。
副作用として履歴削除が機能しなくなる…と思いきや、実は別バグ(後述)により CBS_DROPDOWNLIST スタイルのコンボボックスでは元から機能していなかったため、機能面では退行しないものと思われます。
PR の影響範囲
以下のダイアログに存在したクラッシュバグを修正します。
以下の画面に存在するコンボボックスに関係するコードを変更します。
テスト内容
「共通設定」→「編集」→「Vistaスタイルのファイルダイアログ」にチェックが入っていない状態で、開く・保存ダイアログに対して以下のテストが必要です
他の画面の該当コンボボックス(上記)に対して、履歴削除・単語削除がそれぞれ引き続き機能することの確認が必要です。
関連 issue, PR
#1463, #1470
参考資料
履歴削除の別バグ
sakura/sakura_core/dlg/CDialog.cpp
Lines 725 to 738 in 526f512
CBS_DROPDOWNLIST スタイルのコンボボックスは CB_GETEDITSEL が送られてきても何もしないようで、
dwSelStart
とdwSelEnd
は常に0のまま変わりません。cEditText
は最短でも長さ1(null文字の分)であるため、dwSelEnd < (DWORD)cEditText.GetStringLength()
の条件式により、履歴削除が実行されることはありません。本 PR では元から動いていなかったことを理由として機能を削除しますが、対処方針として適切かどうかというと微妙だと思っています。後から追加PRとして修正することも考えていますので、問題があればご指摘ください。