첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
다운로드

▶ MainForm.cs

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Enumeration
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region IMM 컨텍스트 연결 확장 플래그 - ImmAssociateContextExFlag

        /// <summary>
        /// IMM 컨텍스트 연결 확장 플래그
        /// </summary>
        [Flags]
        private enum ImmAssociateContextExFlag : uint
        {
            /// <summary>
            /// IACE_CHILDREN
            /// </summary>
            IACE_CHILDREN = 0x0001,

            /// <summary>
            /// IACE_DEFAULT
            /// </summary>
            IACE_DEFAULT = 0x0010,

            /// <summary>
            /// IACE_IGNORENOCONTEXT
            /// </summary>
            IACE_IGNORENOCONTEXT = 0x0020
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Import
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region IMM 컨텍스트 확장 연결하기 - ImmAssociateContextEx(windowHandle, imcHandle, flag)

        /// <summary>
        /// IMM 컨텍스트 확장 연결하기
        /// </summary>
        /// <param name="windowHandle">윈도우 핸들</param>
        /// <param name="imcHandle">IMC 핸들</param>
        /// <param name="flag">플래그</param>
        /// <returns>처리 결과</returns>
        [DllImport("Imm32.dll")]
        private static extern bool ImmAssociateContextEx(IntPtr windowHandle, IntPtr imcHandle, ImmAssociateContextExFlag flag);

        #endregion
        #region IMM 컨텍스트 구하기 - ImmGetContext(windowHandle)

        /// <summary>
        /// IMM 컨텍스트 구하기
        /// </summary>
        /// <param name="windowHandle">윈도우 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("Imm32.dll")]
        private static extern int ImmGetContext(IntPtr windowHandle);

        #endregion
        #region IMM 작성 문자열 구하기 - ImmGetCompositionString(imcHandle, index, stringBuilder, bufferLength)

        /// <summary>
        /// IMM 작성 문자열 구하기
        /// </summary>
        /// <param name="imcHandle">IMC 핸들</param>
        /// <param name="index">인덱스</param>
        /// <param name="stringBuilder">문자열 빌더</param>
        /// <param name="bufferLength">버퍼 길이</param>
        /// <returns>처리 결과</returns>
        [DllImport("Imm32.dll")]
        private static extern int ImmGetCompositionString(int imcHandle, int index, StringBuilder stringBuilder, int bufferLength);

        #endregion
        #region IMM 컨텍스트 해제하기 - ImmReleaseContext(windowHandle, imcHandle)

        /// <summary>
        /// IMM 컨텍스트 해제하기
        /// </summary>
        /// <param name="windowHandle">윈도우 핸들</param>
        /// <param name="imcHandle">IMC 핸들</param>
        /// <returns>처리 결과</returns>
        [DllImport("Imm32.dll")]
        private static extern bool ImmReleaseContext(IntPtr windowHandle, int imcHandle);

        #endregion

        #region DBCS 리드 바이트 여부 구하기 - IsDBCSLeadByte(testCharacter)

        /// <summary>
        /// DBCS 리드 바이트 여부 구하기
        /// </summary>
        /// <param name="testCharacter">테스트 문자</param>
        /// <returns>DBCS 리드 바이트 여부</returns>
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern int IsDBCSLeadByte(byte testCharacter); 

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// WM_IME_SETCONTEXT
        /// </summary>
        private const int WM_IME_SETCONTEXT = 0x0281;

        /// <summary>
        /// WM_IME_CHAR
        /// </summary>
        private const int WM_IME_CHAR = 0x0286;

        /// <summary>
        /// WM_IME_STARTCOMPOSITION
        /// </summary>
        private const int WM_IME_STARTCOMPOSITION = 0x10D;

        /// <summary>
        /// WM_IME_COMPOSITION
        /// </summary>
        private const int WM_IME_COMPOSITION = 0x10F;

        /// <summary>
        /// WM_IME_ENDCOMPOSITION
        /// </summary>
        private const int WM_IME_ENDCOMPOSITION = 0x10E;

        /// <summary>
        /// GCS_RESULTREADSTR
        /// </summary>
        private const int GCS_RESULTREADSTR = 0x0200;

        /// <summary>
        /// GCS_COMPSTR
        /// </summary>
        private const int GCS_COMPSTR = 0x0008;

        /// <summary>
        /// 문자열 빌더
        /// </summary>
        private StringBuilder stringBuilder = new StringBuilder();

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 윈도우 프로시저 처리하기 - WndProc(message)

        /// <summary>
        /// 윈도우 프로시저 처리하기
        /// </summary>
        /// <param name="message">메시지</param>
        protected override void WndProc(ref Message message)
        {
            switch(message.Msg)
            {
                case WM_IME_SETCONTEXT :

                    if(message.WParam.ToInt32() != 0)
                    {
                        bool rc = ImmAssociateContextEx(Handle, IntPtr.Zero, ImmAssociateContextExFlag.IACE_DEFAULT);

                        if(rc)
                        {
                            DefWndProc(ref message);
                        }
                        else
                        {
                            base.WndProc(ref message);
                        }
                    }
                    else
                    {
                        base.WndProc(ref message);
                    }

                    break;

                case WM_IME_STARTCOMPOSITION : // 한글 조립 시작시

                    break;

                case WM_IME_ENDCOMPOSITION : // 한글 조립 종료시

                    break;

                case WM_IME_CHAR : // 완성 문자 표시

                    AppendCharacter(Handle, message.WParam.ToInt32(), message.LParam.ToInt32());

                    break;

                default :

                    base.WndProc(ref message);

                    break;
            }
        }

        #endregion
        #region 페인트시 처리하기 - OnPaint(e)

        /// <summary>
        /// 페인트시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.DrawString(this.stringBuilder.ToString(), Font, Brushes.Blue, ClientRectangle);

            base.OnPaint(e);
        }

        #endregion
        #region 키 PRESS 처리하기 - OnKeyPress(e)

        /// <summary>
        /// 키 PRESS 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            string text = Convert.ToString(e.KeyChar);

            this.stringBuilder.Append(text);

            Refresh();

            base.OnKeyPress(e);
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 문자 추가하기 - AppendCharacter(windowHandle, wordParameter, longParameter)

        /// <summary>
        /// 문자 추가하기
        /// </summary>
        /// <param name="windowHandle">윈도우 핸들</param>
        /// <param name="wordParameter">WORD 매개 변수</param>
        /// <param name="longParameter">LONG 매개 변수</param>
        private void AppendCharacter(IntPtr windowHandle, int wordParameter, int longParameter)
        {
            char character = (char)(wordParameter);

            string text = Convert.ToString(character);

            this.stringBuilder.Append(text);

            Refresh();
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요