Concurrent Clean + 日本語 : フォント選択ダイアログ

フォント選択ダイアログのフォント名に日本語が表示されないという問題があります。これを解決しましょう。

      • -

これも、WindowsAPIのControlの一つ、COMBOBOXを使っているところのようなのですが、ここのフォントが変更できていないのです。ボタンやエディットのフォントは変更できているのに。
下のところが、COMBOBOXを生成しているところと思われるのですが、ここで、フォント変更のメッセージを送っているはずなのですよね。気づいたところは、ここだけ、CreateWindowExを使っているのですが、何か関係あるのでしょうか?

< cCrossCallWindows_121.c >
void EvalCcRqCREATEPOPUP (CrossCallInfo *pcci)	/* hwnd, x,y,w,h,isEditable;  HWND hwndPopUp,hwndEdit (if isEditable). */
{
	HWND parent, hwndPopUp, hwndEdit;
	int x, y, w, h;
	int style;
	BOOL isEditable;

	parent     = (HWND) pcci->p1;
	x          = pcci->p2;
	y          = pcci->p3;
	w          = pcci->p4;
	h          = pcci->p5;
	isEditable = (BOOL) pcci->p6;

	style	= WS_CHILD
			| WS_GROUP
			| WS_TABSTOP
			| WS_VSCROLL
			| CBS_AUTOHSCROLL
		//	| CBS_OWNERDRAWFIXED	// PA: removed, otherwise garbage strings appear for empty popups.
			| CBS_HASSTRINGS
			| WS_CLIPSIBLINGS;
	if (isEditable)
		style |= CBS_DROPDOWN;
	else
		style |= CBS_DROPDOWNLIST;

	hwndPopUp = CreateWindowEx (0,
							 "COMBOBOX",
							 "",
							 style,
							 x, y, w, h,
							 parent,
							 (HMENU) 0,
							 ghInst,
							 0);
	SendMessage  (hwndPopUp, CB_SETEXTENDEDUI, (WPARAM) TRUE, 0);
	SendMessage  (hwndPopUp, WM_SETFONT, (WPARAM)gControlFont, MAKELPARAM (TRUE,0));
	SetWindowPos (hwndPopUp, HWND_BOTTOM, 0,0,0,0, SWP_NOMOVE+SWP_NOSIZE);	// This should implement control stack

	/*	Store the standard Windows callback routine adress in stdPopUpCallback
		and subclass the combobox's edit control with PopUpControlProcedure.
	*/
	if (isEditable)
	{
		hwndEdit = GetWindow (hwndPopUp,GW_CHILD);
		stdPopUpCallback = SetWindowLong (hwndEdit, GWL_WNDPROC, (LONG) PopUpControlProcedure);
	}
	else
	{
		hwndEdit = 0;
	}
	MakeReturn2Cci (pcci, (int) hwndPopUp, (int) hwndEdit);
}
      • -

結局、いろいろ試行錯誤した結果、ダイアログに対してだけ、初期化時にフォントを設定するコマンドが発行されていたことが分かりました。しかも、通常のコントロールのフォントとは別のフォントで。
ということで、cCrossCallWindows_121.cより、

static BOOL CALLBACK DialogProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
...
		case WM_INITDIALOG:
			{
...
				//EnumChildWindows (hwnd, SetControlFontProc, (LPARAM) gDlogFont);
				EnumChildWindows (hwnd, SetControlFontProc, (LPARAM) gControlFont);
...
			}
			break;

てな感じで、gControlFontを使用するように変更して、ついでに、ダイアログのコントロールの幅の計算を正しく行えるように、osfont.iclより

osDefaultfont :: !*OSToolbox -> (!Font,!*OSToolbox)
osDefaultfont tb
	= ({fontdef=def,fontimp=imp},tb)
where
	def		= (name,styles,size)
	imp		= {osfontname=name,osfontstyles=sStyle2IStyle styles,osfontsize=size}
	name	= "MS ゴシック"
	styles	= []
	size	= 10
/*
	name	= "Times New Roman"
	styles	= []
	size	= 10
*/

osDialogfont :: !*OSToolbox -> (!Font,!*OSToolbox)
osDialogfont tb
	= ({fontdef=def,fontimp=imp},tb)
where
	def		= (name,styles,size)
	imp		= {osfontname=name,osfontstyles=sStyle2IStyle styles,osfontsize=size}
	name	= "MS ゴシック"
	styles	= []
	size	= 10
/*
	name	= "MS Sans Serif"
	styles	= []
	size	= 8
*/

という形で、デフォルトフォントを変更してみました。ただし、このsizeなんですが、本当の本当に使っているフォントとはサイズが違います。少し小さめにしないと、なぜか、コントロールが大きく描かれすぎてしまったからなんですが、それがなぜかは追究していません。
ということで、大体、日本語関連のところは調整が終わった感じですので、IDEコンパイルして、動作状況を確認してみようと思います。
そういえば、SJISのダメ文字(2バイト目に"\"が出現する文字。"ソ"など)が、コンパイラでバグを起こすということだったので、それも直さないとな・・・。