ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月28日(木) 19:44

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 1 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2015年9月29日(火) 12:54 
オフライン

登録日時: 2005年7月19日(火) 07:02
記事: 183
お住まい: 宮城県
EditboxにおけるIME変換中(漢字変換中)の背景色を変更する方法。
合わせて、通常時のEditBoxの背景色変換にも対応(こっちはオマケ)。

使い方は、下記のコード冒頭のコメントを参照ください。

なお、処理の詳細はこちら↓に記載。興味あればどうぞ~。
WM_IME_COMPOSITIONを掴まえた後の具体的な処理について

コード:

/*
	[MngBackgoundColorText.sbp]
	背景色を管理するクラスの定義。

	Fontは窓に紐づくが、背景色は描画のタイミングで明示的に設定するものなので、
	必ずしも紐づける必要はない。--> このクラスで別管理する。

	※IME変換中の文節などは、下線ではなく背景色で対応。変換中の項目を青味かける。

	【使い方】
	1.以下のメソッドを用いて、背景色とフォントを設定する。
	     SetColorForTextOnExitBox( dwTextColorNew As DWord, dwTextLigthColorNew As DWord )
	     SetBackgoundColorForTextOnExitBox( dwColorTextBackgroundNew As DWord )
	     SetLogiaclFontForIME( ByRef stLogFont As LOGFONT )

	2.WM_CTLCOLOREDITメッセージを捉まえたら、以下のメソッドを呼び出して、
	  その戻り値をreturnする。
	    Function WndProcFor_WM_CTLCOLOREDIT( hDC As HDC, hEdit As HWND ) As Long

	3.下記のIME関連のメッセージを捉まえたら、
	   → WM_IME_STARTCOMPOSITION, WM_IME_COMPOSITION, WM_IME_ENDCOMPOSITION, WM_IME_NOTIFY	  
	 以下のメソッドを呼び出す。
	  Function ImmProc( hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM ) As Char

	 このメソッドが「FALSE」を返した時はデフォルト動作なので、スルーすること(デフォルト窓プロシージャへ流す)。
	'// 一方で「TRUE」を返した時は、独自処理済みなので窓プロシージャを戻り値0で抜けること。


	※IME変換中の背景色は、固定値で itsRgbColorImmBackground で持っているので、
	 必要であれば変更のこと。

	以上ー。
*/

'// 各種、必要なWinAPI32の宣言と関数定義。
'// #include  にも一部あるが、不足なので、ここで明示的に宣言する。
TypeDef HIMC = DWord
Declare Function ImmSetCompositionFont Lib "imm32" Alias "ImmSetCompositionFontA" (hIMC As HIMC, ByRef lplf As LOGFONT) As Long

Const CFS_DEFAULT =        &H0000
Const CFS_RECT =           &H0001
Const CFS_POINT =          &H0002
Const CFS_FORCE_POSITION = &H0020
Const CFS_CANDIDATEPOS =   &H0040
Const CFS_EXCLUDE =        &H0080
Type COMPOSITIONFORM
	dwStyle As Long
	ptCurrentPos As POINTAPI
	rcArea As RECT
End Type
Declare Function ImmSetCompositionWindow Lib "imm32" (hIMC As HIMC, ByRef lpCompForm As COMPOSITIONFORM) As Long

Declare Function ImmGetContext Lib "imm32" (hWnd As HWND) As Long
Declare Function ImmReleaseContext Lib "imm32" (hWnd As HWND, hIMC As HIMC) As Long

'// +++ ここから、api_imm.sbp に無い宣言を自前で追加 +++
Const GCS_RESULTSTR = 	&H0800
Const GCS_COMPSTR = 	&H0008
Const GCS_COMPATTR =    &H0010
Const GCS_DELTASTART =  &H0100
'// attribute for COMPOSITIONSTRING Structure
Const ATTR_INPUT                = &H00
Const ATTR_TARGET_CONVERTED     = &H01
Const ATTR_CONVERTED            = &H02
Const ATTR_TARGET_NOTCONVERTED  = &H03
Const ATTR_INPUT_ERROR          = &H04
Const ATTR_FIXEDCONVERTED       = &H05
Declare Function ImmGetCompositionString Lib "imm32" Alias "ImmGetCompositionStringA" (hIMC As HIMC, dwIndex As DWord, lpBuf As BytePtr, dwBufferSize As DWord ) As Long

Const IMM_ERROR_NODATA = -1
Const IMN_OPENCANDIDATE = &H0005
Type CANDIDATEFORM
    dwIndex As DWord
    dwStyle As DWord
    ptCurrentPos As POINTAPI
    rcArea As RECT
End Type
Declare Function ImmSetCandidateWindow Lib "imm32" (hIMC As HIMC, ByRef lpCandidateFoem As CANDIDATEFORM) As Char
'// --- ここまで(imm.hを参照して定義 [C:\borland\bcc55\Include\imm.h] ) ---
'// ※Web上で参照するなら http://katahiromz.web.fc2.com/mathai/immdev.h 辺り。


'// +++ 以下も追加 +++
Declare Function ExtTextOut Lib "Gdi32" Alias "ExtTextOutA" ( hDC As HDC, nXStart As Long, nYStart As Long, dwOptions As DWord, ByRef lpRect As RECT, lpString As BytePtr, cbString As Long, lpDx As *Long)
Const ETO_CLIPPED = &H0004
'// --- ここまで ---


#include 
'// WsColorVector クラスを利用のため。→外部に公開時はソコを削除しようか。




Class ManagementAndDrowTextBackGroundColor
	itsBrushTextBackground As HBRUSH
	itsRgbColorTextBackground As DWord
	itsRgbColorText As Dword
	itsRgbColorTextAtNotFocused As Dword

	itsImmLastLength As DWord
	itsImmLastLengthMax As DWord
	itsLogFontIME AS LOGFONT
	itsLogFontIME_IsEnable As Char
	itsRgbColorImmBackground As DWord '暫定処置(変換時の属性処理が不完全)

	'// ※将来に、calloc() を Heep~に置き換える考慮でここにまとめておく。
	Function _HeapWorikngArea( dwSize As DWord ) As VoidPtr
		_HeapWorikngArea = calloc( dwSize )
	End Function
	Sub _FreeWorkingArea( pMark As VoidPtr )
		free( pMark )
	End Sub

Public
	Sub ManagementAndDrowTextBackGroundColor()
		'テキストの色と背景色(任意に変えることを考慮して追加)
		itsBrushTextBackground = NULL '処理の共通化のために、NULLで初期化
		This.SetColorForTextOnExitBox( RGB( &h00,&h00,&h00 ), DISABLED_RGB )
		This.SetBackgoundColorForTextOnExitBox( RGB( &hFF,&hFF,&hFF ) )

		'IMMの変換領域の初期値
		itsImmLastLength = 0
		itsRgbColorImmBackground = RGB( &H44, &H44, &H44 ) '// 変換中の背景色【暫定固定値】
		itsLogFontIME_IsEnable = FALSE
	End Sub
	Sub ~ManagementAndDrowTextBackGroundColor()
		If itsBrushTextBackground <> NULL Then
			DeleteObject( itsBrushTextBackground )
		End If
	End Sub



	'文字色を設定(エディット窓の文字色+非フォーカス時の淡色)。
	Sub SetColorForTextOnExitBox( dwTextColorNew As DWord, dwTextLigthColorNew As DWord )
		itsRgbColorText = dwTextColorNew
		itsRgbColorTextAtNotFocused = dwTextLigthColorNew
	End Sub
	'文字の背景色を設定(エディット窓の背景色)
	Sub SetBackgoundColorForTextOnExitBox( dwColorTextBackgroundNew As DWord )
		itsRgbColorTextBackground = dwColorTextBackgroundNew
		If itsBrushTextBackground <> NULL Then
			DeleteObject( itsBrushTextBackground )
		End If
		itsBrushTextBackground = CreateSolidBrush( itsRgbColorTextBackground )
	End Sub

	'文字色の取得
	Function GetColorForTextOnExitBox() As DWord
		GetColorForTextOnExitBox = itsRgbColorText
	End Function
	'文字の背景色の取得
	Function GetBackgoundColorForTextOnExitBox() As DWord
		GetBackgoundColorForTextOnExitBox = itsRgbColorTextBackground
	End Function
	'非フォーカス時の淡色化の有無を取得
	Function IsTextColorUseLight()
		IsTextColorUseLight = (DISABLED_RGB <> itsRgbColorTextAtNotFocused)
	End Function

	'IME変換中に利用するフォントの「論理フォント構造体」を設定する。→内部でコピーして保持する。
	Sub SetLogiaclFontForIME( ByRef stLogFont As LOGFONT )
		memcpy( VarPtr(itsLogFontIME), VarPtr(stLogFont), sizeOf(LOGFONT) )
		itsLogFontIME_IsEnable = TRUE
	End Sub


	'// 親窓に WM_CTLCOLOREDIT が通知された時の動作。
	'// ※lParam As HWND, wParam As HDC で対象が渡されてくるので、
	'//   適切に文字色と背景色を設定して返すと、その色でテキストを描画してくれる。
	'// ref.[コントロールの背景色/フォント変更] - http://www50.tok2.com/home2/StillGreen/ ... kcolor.htm
	Function WndProcFor_WM_CTLCOLOREDIT( hDC As HDC, hEdit As HWND ) As Long
		'テキストの文字色
		SetBkMode( hDC, OPAQUE ) '背景を塗りつぶしモードに設定
		If itsRgbColorTextAtNotFocused = DISABLED_RGB Then '非フォーカス時の扱いで分岐
			SetTextColor( hDC, itsRgbColorText )
		Else
			If GetFocus() = hEdit Then
				SetTextColor( hDC, itsRgbColorText )
			Else
				SetTextColor( hDC, itsRgbColorTextAtNotFocused )
			End If
		End If

		'テキストの背景色
		SetBkColor( hDC, itsRgbColorTextBackground ) 'for テキストが書かれている部分
		WndProcFor_WM_CTLCOLOREDIT = itsBrushTextBackground As Long 'for テキストが書かれていない部分
	End Function

Private
	Function IsDarkColorBackgroundForIME()
		Dim colorCls As WsColorVector( itsRgbColorTextBackground )
		Dim xBrightness As Single

		xBrightness = colorCls.GetBrightness() '0.0~1.0で規格化された〝輝度"
		If xBrightness < 0.4 Then
			'充分にブラックに近い場合は(輝度が低い)Yesとする。
			IsDarkColorBackgroundForIME = TRUE

			'変換中背景色は固定的に下記を用いる。
			itsRgbColorImmBackground = RGB( &H44, &H44, &H44 )
		Else
			IsDarkColorBackgroundForIME = FALSE
		End If
	End Function
Public
	'// エディットボックスをサブクラス化して、IME関連の下記のメッセージを捉まえたときの動作。
	'//   --> WM_IME_STARTCOMPOSITION, WM_IME_COMPOSITION, WM_IME_ENDCOMPOSITION, WM_IME_NOTIFY
	'//  (※通知先は、親窓かもしれない?その場合はサブクラス化不要)
	'// 
	'// この関数が「FALSE」を返した時はデフォルト動作なのでスルーすること。
	'// 一方で「TRUE」を返した時は、独自処理済みなので窓プロシージャを戻り値0で抜けること。
	Function ImmProc( hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM ) As Char
		Dim hImc As HIMC

		ImmProc = FALSE

		'Win Vistaより前では、IMM関連の挙動が異なるので弾く。
		If OS_Vista > GetOsType() Then
			Exit Function
		End If

		'【TODO】変換中属性の処理が不完全なので、一定値以下の黒背景でのみ、本関数を有効にする。
		'※ここを抜けた時点で、itsRgbColorImmBackground は設定済み。
		If FALSE = IsDarkColorBackgroundForIME() Then
			Exit Function
		End If

		'// IMMコンテキストを取得
		hImc = ImmGetContext( hWnd )
		If hImc = NULL Then
			Exit Function
		End If

		Select Case dwMsg
			'// 文字変換開始
			Case WM_IME_STARTCOMPOSITION
				ImmProc = ImeStartComposition( hWnd, hImc, wParam, lParam )
		
			'// 文字変換処理中
			Case WM_IME_COMPOSITION
				If lParam = 0 Then
					'// 変化はあったがlParam=0(変化の内容が未定義)は、
					'// 「1byteのみ入力で、やっぱキャンセル」された状態の様子(仕様見つからず。実機確認)。
					'// 一旦「WM_IME_ENDCOMPOSITION」扱いする。
					'// …で、本来は「ImeEndComposition()」を呼びたいのだが、再描画範囲(itsImmLastLengthMax)が
					'// ただしく機能していないようなので、、、無理やりだが「全体再描画」で対応。
					'// 【ToDo】もう少しスマートな再描画をしたい。at 2015.09.02
					InvalidateRgn( hWnd, NULL, TRUE )
				Else
					ImmProc = ImeComposition( hWnd, hImc, wParam, lParam )
				End If
		
			'// 文字変換終了
			Case WM_IME_ENDCOMPOSITION
				ImmProc = ImeEndComposition( hWnd, hImc, wParam, lParam )
	
			'// その他のIME関連の通知
			Case WM_IME_NOTIFY
				Select Case wParam
					'// 変換候補リストが表示されようとしている
					Case IMN_OPENCANDIDATE
						ImmProc = ImmSetCandidateWindowPos( hWnd, hImc )

					Case Else
						ImmProc = FALSE

				End Select
			Case Else
				ImmProc = FALSE

		End Select

		'// IMMコンテキストを解放
		ImmReleaseContext( hWnd, hImc )
	End Function

Private
	Function ImeStartComposition( hWnd As HWND, hImc As HIMC, wParam As WPARAM, lParam As LPARAM ) As Char
		itsImmLastLength = 0    '// 内部変数を初期化
		itsImmLastLengthMax = 0 '// 内部変数を初期化

		ImeStartComposition = FALSE '// IMEに対しては何もしない(デフォルト動作)。
	End Function

	Function ImeEndComposition( hWnd As HWND, hImc As HIMC, wParam As WPARAM, lParam As LPARAM ) As Char
		Dim hDC As HDC
		Dim stPoint As POINTAPI
		Dim stRect As RECT
		Dim fontExtentPoint As SIZE
		Dim data As Word
	
		'// 変換窓で描画した範囲を「再描画」して後始末する。
		hDC = GetDC( hWnd )
			data = &HA4A4 '// 全角の「い」に相当。
			GetTextExtentPoint32( hDC, VarPtr(data), sizeOf(Word), fontExtentPoint )
	
			GetCaretPos( stPoint )
			stRect.right  = stPoint.x
			stRect.top    = stPoint.y
			stRect.left   = stPoint.x + itsImmLastLengthMax
			stRect.bottom = stPoint.y + fontExtentPoint.cy
			InvalidateRect( hWnd, stRect, TRUE )
		ReleaseDC( hWnd, hDC )

		ImeEndComposition = FALSE '// IMEに対しては何もしない(デフォルト動作)。
	End Function
	
	Function ImeComposition( hWnd As HWND, hImc As HIMC, wParam As WPARAM, lParam As LPARAM )
		Dim pszImmString As BytePtr
		Dim pAttrArray As *Char
	

		ImeComposition = FALSE
		pszImmString = NULL
		If (lParam and GCS_RESULTSTR) <> 0 Then
			'// 文字列の変換状態が全て確定した場合に GCS_RESULTSTRフラグがONになる
			'// →確定した文字列を取得する。
			pszImmString = GetCompositionString( hImc, GCS_RESULTSTR )
			If pszImmString <> NULL Then
				'// 呼び出し元のエディット窓に対して、確定文字列を挿入する。
				SendMessage( hWnd, EM_REPLACESEL, TRUE, pszImmString )

				'// 利用した領域を解放
				_FreeWorkingArea( pszImmString )

				'// IMEに対して独自処理をしたとして、デフォルト動作をSkipするよう設定。
				ImeComposition = TRUE
			End If
		End If 
		'// ※「確定」状態で且つ、次の「未確定(=変換状態に変化)がある」状態もあるので留意。
		'//   ↑↓なので★続けて★処理する。
		If (lParam and GCS_COMPSTR) <> 0 Then 
			'// 変換状態に何か変化があった場合に GCS_COMPSTRフラグがONになる
			'// →変換中(IME途中)の文字列を取得する。
			pszImmString = GetCompositionString( hImc, GCS_COMPSTR )

			If pszImmString <> NULL Then
				'// 文字列が取れたなら、その属性(下記の5種類)を取得する(1文字当たり8bitの定数)。
				'//   ・選択されていなく、変換されていない文字。:ATTR_INPUT
				'//   ・選択されていて、変換されている文字。
				'//   ・選択されていなく、変換されている文字。
				'//   ・選択されていて、変換されていない文字。
				'//   ・無効な文字
				pAttrArray = GetCompositionString( hImc, GCS_COMPATTR ) As *Char

				'// 変換中の文字列を、IME窓へ明示的に表示(IME窓=Composition窓)
				'// →背景色などを任意にできる♪
				DisplayCompositionString( hWnd, pszImmString, pAttrArray )

				'// 利用した領域を解放
				_FreeWorkingArea( pszImmString )
				If pAttrArray <> NULL Then
					_FreeWorkingArea( pAttrArray )
				End If

				'// IMEに対して独自処理をしたとして、デフォルト動作をSkipするよう設定。
				ImeComposition = TRUE
			End If
		End If
	End Function 

	'// ImmGetCompositionStringA()に対するラッパー関数。【Unicodeは未考慮】
	Function GetCompositionString( hImc As HIMC, dwType As DWord ) As BytePtr
		Dim nSize As Long
		Dim pszImmString As BytePtr
	
		nSize = ImmGetCompositionString( hImc, dwType, NULL, 0 )
		if nSize > 0 Then
			pszImmString = _HeapWorikngArea( nSize +1 )
			ImmGetCompositionString( hImc, dwType, pszImmString, nSize )
			pszImmString[ nSize ] = NULL
			'// この文字列( or 属性配列)がNULL文字で終わるとは限らない。
			'// 従って、bufに返された文字列の長さを戻り値によって判定しなければならない。
			'// http://nienie.com/~masapico/api_ImmGetC ... tring.html
			'// →文字列と仮定して、NULLを終端に追加することで、返却先に終端を伝えるようにしようか。
			'//  ただし、属性配列はATTR_INPUT=0x00なので、終端の区別が出来ない。利用時は注意。
		End If
		GetCompositionString = pszImmString
	End Function

	'// IME変換中文字列を自前で描画する。
	'// ⇒これにより、背景色の設定などが可能になる。
	Sub DisplayCompositionString( hWnd As HWND, pszImmString As BytePtr, pAttrArray As *Char )
		Dim hDC As HDC
		Dim stPoint As POINTAPI
		Dim stClientRect As RECT
		Dim stImeRect As RECT
	
		Dim hBrush As HBRUSH
		Dim hPen As HPEN
		Dim hFont As HFONT
	
		Dim fontExtentPoint As SIZE
		Dim data As Word
	

		hDC = GetDC( hWnd )

		'【TODO】変換中の文字列である旨をユーザーへ伝える方法として、背景色を変更。
		' 通常のIMEだと下線とかフォント側の変更でやってるね。
		' 背景色の方が楽なので、暫定でこの方法。
		hBrush = SelectObject( hDC, CreateSolidBrush( itsRgbColorImmBackground ) )
		hPen = SelectObject( hDC, CreatePen( PS_SOLID, 1, itsRgbColorImmBackground ) )
		If TRUE = itsLogFontIME_IsEnable Then
			'【TODO】本来は、属性に応じて一文字ごとに下線の有り無し等設定すべきだが、一括設定で暫定。
			hFont = SelectObject( hDC, CreateFontIndirect( itsLogFontIME ) ) 
		End If

		data = &HA4A4 '// 全角の「い」に相当。
		GetTextExtentPoint32( hDC, VarPtr(data), sizeOf(Word), fontExtentPoint )

		GetCaretPos( stPoint )
		GetClientRect( hWnd, stClientRect )
		If itsImmLastLength > 0 Then
			'// 背景を塗りつぶす(だいぶ無理やり…)
			stImeRect.left   = stPoint.x
			stImeRect.top    = stPoint.y
			stImeRect.bottom = stPoint.y + fontExtentPoint.cy
			stImeRect.right  = stPoint.x + itsImmLastLength
			If stImeRect.right > stClientRect.right Then
				stImeRect.right = stClientRect.right -1
			End If

			Rectangle( hDC, 
				stImeRect.left,  stImeRect.top, 
				stImeRect.right, stImeRect.bottom  )
			If itsImmLastLength > itsImmLastLengthMax Then
				itsImmLastLengthMax = itsImmLastLength
			End If
		End If
		itsImmLastLength = ( lstrlen( pszImmString ) +1 ) * (fontExtentPoint.cx / 2) '// 横幅を更新
		_TextOutWithAttr( hDC, 
			VarPtr(stPoint), 
			VarPtr(fontExtentPoint),
			stClientRect.right,
			pszImmString,
			pAttrArray )

		DeleteObject( SelectObject( hDC, hBrush ) ) '// HDCから解放したBRUSHは、本関数内で作成したものなので破棄する。
		DeleteObject( SelectObject( hDC, hPen )   ) '// HDCから解放したPENは、本関数内で作成したものなので破棄する。
		If TRUE = itsLogFontIME_IsEnable Then
			DeleteObject( SelectObject( hDC, hFont )  ) '// HDCから解放したFONTは、本関数内で作成したものなので破棄する。
		End If

		ReleaseDC( hWnd, hDC )
	End Sub
	'// IME属性(選択中、変換中etc)に応じて異なる背景色で表示
	Sub _TextOutWithAttr( hDC As HDC, pstPoint As *POINTAPI, pFontExtentPoint As *SIZE, nMaxClientRightPos As Long, pszImmString As BytePtr, pAttrArray As *Char )
		Dim textLength As DWord
		Dim stImeRectParts As RECT
		Dim nX As Long
		Dim nY As Long
		Dim rgbList[ 6 ] As DWord
		Dim sameAttrLength As DWord
		Dim pMarkStart As BytePtr
		Dim nDX As DWord
		Dim i As DWord

		'// 【暫定】IME変換中の背景色を元に、変換対象や選択状態の背景色を生成。
		rgbList[ ATTR_INPUT ] = itsRgbColorImmBackground '// RGB( &H44, &H44, &H44 ) '// 入力直後
		rgbList[ ATTR_TARGET_CONVERTED ]    = itsRgbColorImmBackground + RGB( &H33, &H33, &H77 ) '// 変換中!→青味かける。
		rgbList[ ATTR_CONVERTED ]           = itsRgbColorImmBackground '// 変換中だけど未選択。→「入力直後」と同じ色にする。
		rgbList[ ATTR_TARGET_NOTCONVERTED ] = itsRgbColorImmBackground '// 無い?→「入力直後」と同じ色にする。
		rgbList[ ATTR_INPUT_ERROR ]         = itsRgbColorImmBackground '// 無い?→「入力直後」と同じ色にする。
		'// 参考サイトhttp://nienie.com/~masapico/api_ImmGetCompositionString.html


		SetTextColor( hDC, itsRgbColorText )
		textLength = lstrlen( pszImmString )

		'// pAttrArrayにしたがって、『属性の切り替わる単位で』背景書を変換して書こうか。
		'// http://nienie.com/~masapico/api_ImmGetC ... tring.html
		'// 
		nDX = pFontExtentPoint->cx / 2
		nX = pstPoint->x
		nY = pstPoint->y
		i = 0
		pMarkStart = pszImmString
		While( i < textLength )
			'// 属性の変わる直前までをピックアップ
			sameAttrLength = 1
			While( (pAttrArray[ i ] = pAttrArray[ i+1 ]) and (i < textLength) ) '// 終端にNULLが入る仕様を利用(オーバーフローしない)
				sameAttrLength++
				i++
			Wend

			'// 属性単位で文字列を描画
			SetBkColor( hDC, rgbList[ pAttrArray[ i ] ] )
			stImeRectParts.left = nX
			stImeRectParts.top  = nY
			stImeRectParts.right   = nX + sameAttrLength * nDX
			stImeRectParts.bottom  = nY + pFontExtentPoint->cy
			If stImeRectParts.right > nMaxClientRightPos Then
				stImeRectParts.right = nMaxClientRightPos -1
				i = textLength '// ループを抜けるフラグとして設定。
			End If
			ExtTextOut( hDC, 
				nX, nY, 
				ETO_CLIPPED, 
				stImeRectParts,
				pMarkStart, sameAttrLength,
				NULL )
			nX = stImeRectParts.right
			pMarkStart += sameAttrLength
			i++
		Wend
	End Sub

	'// IME変換リストの表示位置を設定する。
	Function ImmSetCandidateWindowPos( hWnd As HWND, hImc As HIMC ) As Char
		Dim stPoint As POINTAPI
		Dim stImmCandidateForm As CANDIDATEFORM
	
		GetCaretPos( stPoint )
		ZeroMemory( VarPtr(stImmCandidateForm), Len(stImmCandidateForm) )
		stImmCandidateForm.ptCurrentPos.x = stPoint.x
		stImmCandidateForm.ptCurrentPos.y = stPoint.y
		stImmCandidateForm.dwStyle = CFS_CANDIDATEPOS
	
		ImmSetCandidateWindow( hImc, stImmCandidateForm )


		'// その後のIME動作はデフォルトの流れに任せる。
		ImmSetCandidateWindowPos = FALSE
	End Function

End Class



通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 1 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[8人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean