Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

印刷ページ設定ダイアログのフォントが巨大化してしまう #1678

Closed
suconbu opened this issue May 22, 2021 · 7 comments
Closed
Labels
🐛bug🦋 ■バグ修正(Something isn't working)

Comments

@suconbu
Copy link
Member

suconbu commented May 22, 2021

問題内容

不具合再現時のスクリーンショットです。
image

※印刷ページ設定ダイアログの配置調整作業中に偶然発見してしまいました。

再現手順

  1. メニューから「ファイル」→「印刷ページ設定」を選択
  2. 印刷ページ設定ダイアログでヘッダーかフッターの「フォント」を押下
  3. フォントダイアログでそのまま OK を押下
  4. 印刷ページ設定ダイアログを OK で一旦閉じる
  5. もう一度印刷ページ設定ダイアログを開く (★発生)

不具合発生後、「『使用』のチェックを外す」→「一旦ダイアログを閉じる」→「再度表示する」で正常に戻ります。

再現頻度

100% 起こせました。

問題のカテゴリ

  • プログラムの動作上の問題
    • Appveyor ビルド版

環境情報

  • OS バージョン
    Windows 10 Home 64bit

  • サクラエディタバージョン

サクラエディタ   v2.4.2.3764 32bit dev
(GitHash fab295eb6f01c68fdbe24fb06b9592a01cb67376)
(GitURL https://github.com/sakura-editor/sakura.git)

      Compile Info: V1916 WPR WIN601/I800/C000/N601
      Last Modified: 2021/5/16 12:07:08

※ひとまず1週ほど前のこの版で試しましたが、他の版ではまだ試せていません。

スクリーンショット

@suconbu
Copy link
Member Author

suconbu commented May 22, 2021

不具合現象からすると #1421 の変更が影響していそうな気がしていますので、後ほどその変更前の版で動作を見てみます。

@suconbu suconbu added the 🐛bug🦋 ■バグ修正(Something isn't working) label May 22, 2021
@suconbu
Copy link
Member Author

suconbu commented May 23, 2021

不具合現象からすると #1421 の変更が影響していそうな気がしていますので、後ほどその変更前の版で動作を見てみます。

😣

SHA-1 Date 再現するか 備考
fab295e 2021-05-16 する
bb83d9d 2020-10-12 する Merge pull request #1421
298ac44 2020-10-11 しない

@berryzplus
Copy link
Contributor

ダイアログの処理を検証できる機構を準備したほうがいいんですかね。。。

ダイアログクラスCDialogにはもともと、できるだけWindows APIを使用しないための機構が存在していた形跡があります。GetData()とSetDataの機構がソレなんですけど、Getでダイアログからデータメンバにデータをコピーし、Setでデータをダイアログに反映しするようになっています。おそらくMFCのDDXを参考にした機構だと思うんですが、正しく使えばデータ処理とダイアログ画面を分離することができ「処理」の検証ができるようになります。なんか、Windows APIを直呼びしたい人が多かったみたいでgdgdになっちゃってますけどね。

何をどこまでやるか?ってのは考えていかなきゃならんです。

  • 印刷ページ設定ダイアログでヘッダーかフッターの「フォント」を押下
  • フォントダイアログでそのまま OK を押下
  • 印刷ページ設定ダイアログを OK で一旦閉じる

「OKを押下」したら、画面で選択したデータを確定して反映する処理が走ります。
この手順から想像できることは、2回のOK押下のうちいずれか(または両方)で、
「確定してはいけない状態での確定」が行われたんではないかということです。

まぁ、だからといってなんで巨大化すんねん!という部分は依然として謎なわけですが 😃

@suconbu
Copy link
Member Author

suconbu commented May 23, 2021

#1421 の修正で、ダイアログボックス自体のフォントハンドルを保持する変数※の初期化タイミングが変化しています。
※ PR 反映前は CDlgPrintSetting::m_hFontDlg、PR 反映後は CDialog::m_hFontDialog (新規) が該当

#1421 反映前の初期化タイミング:

CDlgPrintSetting.cpp
 143:BOOL CDlgPrintSetting::OnInitDialog( HWND hwndDlg, WPARAM wParam, LPARAM lParam )
 144:{
...
 158:	// ダイアログのフォントの取得
 159:	m_hFontDlg = (HFONT)::SendMessage( GetHwnd(), WM_GETFONT, 0, 0 ); ★ここだったものが……
 160:	LOGFONT	lf;
 161:	::GetObject(m_hFontDlg, sizeof(LOGFONT), &lf);
 162:	m_nFontHeight = lf.lfHeight;		// フォントサイズ
 163:
 164:	/* 基底クラスメンバ */
 165:	return CDialog::OnInitDialog( GetHwnd(), wParam, lParam );

反映後の初期化タイミング:

CDialog.cpp
 176:BOOL CDialog::OnInitDialog( HWND hwndDlg, WPARAM wParam, LPARAM lParam )
 177:{
...
 182:	/* ダイアログデータの設定 */
 183:	SetData();
 184:
 185:	SetDialogPosSize();
 186:
 187:	m_hFontDialog = UpdateDialogFont( hwndDlg ); ★ここに移動 (SetData よりも後という点がポイント)
 188:
 189:	m_bInited = TRUE;
 190:	return TRUE;
 191:}

この変更が要因となって、「5. もう一度印刷ページ設定ダイアログを開く」の時に OnInitDialog -> SetData -> ... -> CDlgPrintSetting::SetFontName にてまだ初期化前の CDialog::m_hFontDialog (=NULL) を CDialog::GetDialogFont 経由で参照してしまう場合があり、その後意図しない動作になっているようです。

もう少し調査して原因・対策が分かってきましたら PR 作成します。

@suconbu
Copy link
Member Author

suconbu commented May 23, 2021

フォントサイズがおかしくなるまでの流れが分かってきました。

  1. OnInitDialog が呼ばれる。
CDialog.cpp
 176:BOOL CDialog::OnInitDialog( HWND hwndDlg, WPARAM wParam, LPARAM lParam )
...
 182:	/* ダイアログデータの設定 */
 183:	SetData();
...
 187:	m_hFontDialog = UpdateDialogFont( hwndDlg );
  1. SetData の先で呼ばれる SetFontName にて、ダイアログボックスのフォントが意図せず破棄される。
CDlgPrintSetting.cpp
 896:void CDlgPrintSetting::SetFontName( int idTxt, int idUse, LOGFONT& lf, int nPointSize )
...
		★ダイアログボックスのフォントが取れる(この時点では「MS Pゴシック」)
 908:		HFONT	hFontOld = (HFONT)::SendMessage(GetItemHwnd( idTxt ), WM_GETFONT, 0, 0 );
 909:
 910:		// 論理フォントを作成
 911:		HFONT	hFont = ::CreateFontIndirect( &lft );
 912:		if (hFont) {
 913:			// フォントの設定
 914:			::SendMessage( GetItemHwnd( idTxt ), WM_SETFONT, (WPARAM)hFont, MAKELPARAM(FALSE, 0) );
 915:		}
 916:		if (GetDialogFont() != hFontOld) { ★この時点ではGetDialogFontはNULLを返却→「真」
 917:			// 古いフォントの破棄
 918:			::DeleteObject( hFontOld ); ★ダイアログボックスのフォントなのに誤って破棄
 919:		}
 920:
  1. OnInitDialog から呼ばれる UpdateDialogFont にて、ダイアログボックスのフォントをシステムフォント相当 (≒Yu Gothic UI) に差し替える際、異常な高さ指定をしてしまう。
window.cpp
 388:HFONT UpdateDialogFont( HWND hwnd )

	★先ほど破棄したフォントハンドルが取れる
 390:	HFONT hFontDialog = (HFONT)::SendMessageAny( hwnd, WM_GETFONT, 0, (LPARAM)NULL );
...
 396:	// 現在設定済みフォントと同じ高さのシステムフォント風フォントを得て再設定
 397:	LOGFONT lfDialog = {};

	★フォントハンドル破棄済みのため情報取得に失敗。lfDialogの全メンバは初期値の 0 のまま。
 398:	GetObject( hFontDialog, sizeof( lfDialog ), &lfDialog );

	★高さ0指定でシステムフォント相当のフォントを作成しようとする。
 399:	HFONT hFontSystemBased = GetSystemBasedFont( lfDialog.lfHeight );

まだフォントが「大きく」なってしまう理由がはっきりしていないのですが、LOGFONT 構造体の説明によると lfHeight = 0 の場合には「デフォルト」のフォントサイズが使われるとされていて、これが不具合発生時に見えているフォントの大きさなのかもしれません。
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfonta

@berryzplus
Copy link
Contributor

フォントサイズがおかしくなるまでの流れが分かってきました。

  1. OnInitDialog が呼ばれる。

見てみましたが呼出し順がおかしいですね。

BOOL CDialog::OnInitDialog( HWND hwndDlg, WPARAM wParam, LPARAM lParam )
{
m_hWnd = hwndDlg;
// Modified by KEITA for WIN64 2003.9.6
::SetWindowLongPtr( m_hWnd, DWLP_USER, lParam );
/* ダイアログデータの設定 */
SetData();
SetDialogPosSize();
m_hFontDialog = UpdateDialogFont( hwndDlg );
m_bInited = TRUE;
return TRUE;
}

189行目のSetData()がダイアログ項目へのデータセット(≒描画)を行うので、
フォント設定はSetData()の前までに済ませる必要があると思います。
 👇
そうしないと、フォント変更時に再描画する羽目になります。
 👇
画面が「ちらつく」の原因となるのでイクナイです。

@suconbu
Copy link
Member Author

suconbu commented May 25, 2021

#1682 がマージされましたのでクローズします。

@suconbu suconbu closed this as completed May 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛bug🦋 ■バグ修正(Something isn't working)
Projects
None yet
Development

No branches or pull requests

2 participants