반응형

Dictionary를 Xelement로 변환 한 후 , XML파일로 저장한다.

저장한 파일을 읽어서 Dictionary로 변환.

 

#소스코드

//Dictionary to Element:
Dictionary<string, string> dict = new Dictionary<string,string>();
XElement el = new XElement("root",dict.Select(kv => new XElement(kv.Key, kv.Value)));
el.Save("파일경로") 
     
//Element to Dictionary:
 
XElement rootElement = XElement.Load("파일 경로");
Dictionary<string, string> dict = new Dictionary<string, string>();
foreach(var el in rootElement.Elements())
{
   dict.Add(el.Name.LocalName, el.Value);
}
 
반응형

C#에 DataGrid를 다루다 보면 cell BeginEdit(셀 에디트를 위해)를 호출 하게 되는데 , 이때 영어 같은 경우는 합성 문자가 아니기 때문에 상관이 없지만, 한글 같은 경우는 합성 문자이기때문에 첫번째 타이핑을 할때 IME_Composition 인 상태의 커서를 만들어야 한글 입력이 제대로 된다.

하지만 DataGrid(WPF)의 경우에는 딱히 지원이 없어 보인다. 또 나같은 경우는 한글키 입력 일경우에는  KEY_DOWN 메세지 자체를 프로그램에서 캐치 하지 못했다. 해서 전역 후킹을 통해서 이문제를 해결했다.  

 

@소스코드

 

#region 전역 후킹


        const int VK_PROCESSKEY = 0xE5;
        const int WM_IME_COMPOSITION = 0x10F;
        const int WM_IME_ENDCOMPOSITION = 0x10E;
        const int KEYEVENTF_EXTENDEDKEY = 0x1;
        const int KEYEVENTF_KEYUP = 0x2;
        [DllImport("user32.dll")]
        static extern bool keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);

        [DllImport("user32.dll")]
        static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc callback, IntPtr hInstance, uint threadId);

        [DllImport("user32.dll")]
        static extern bool UnhookWindowsHookEx(IntPtr hInstance);

        [DllImport("user32.dll")]
        static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode, int wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);

        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

        const int WH_KEYBOARD_LL = 13; // Номер глобального LowLevel-хука на клавиатуру
        const int WM_KEYDOWN = 0x100; // Сообщения нажатия клавиши
        
        const int WM_IME_STARTCOMPOSITION = 0x010D;

        #region VirtualKey
        public enum VKeys : int
        {
            VK_LBUTTON = 0x01,  //Left mouse button
            VK_RBUTTON = 0x02,  //Right mouse button
            VK_CANCEL = 0x03,  //Control-break processing
            VK_MBUTTON = 0x04,  //Middle mouse button (three-button mouse)
            VK_BACK = 0x08,  //BACKSPACE key
            VK_TAB = 0x09,  //TAB key
            VK_CLEAR = 0x0C,  //CLEAR key
            VK_RETURN = 0x0D,  //ENTER key
            VK_SHIFT = 0x10,  //SHIFT key
            VK_CONTROL = 0x11,  //CTRL key
            VK_MENU = 0x12,  //ALT key
            VK_PAUSE = 0x13,  //PAUSE key
            VK_CAPITAL = 0x14,  //CAPS LOCK key
            VK_HANGUL = 0x15,
            VK_ESCAPE = 0x1B,  //ESC key
            VK_SPACE = 0x20,  //SPACEBAR
            VK_PRIOR = 0x21,  //PAGE UP key
            VK_NEXT = 0x22,  //PAGE DOWN key
            VK_END = 0x23,  //END key
            VK_HOME = 0x24,  //HOME key
            VK_LEFT = 0x25,  //LEFT ARROW key
            VK_UP = 0x26,  //UP ARROW key
            VK_RIGHT = 0x27,  //RIGHT ARROW key
            VK_DOWN = 0x28,  //DOWN ARROW key
            VK_SELECT = 0x29,  //SELECT key
            VK_PRINT = 0x2A,  //PRINT key
            VK_EXECUTE = 0x2B,  //EXECUTE key
            VK_SNAPSHOT = 0x2C,  //PRINT SCREEN key
            VK_INSERT = 0x2D,  //INS key
            VK_DELETE = 0x2E,  //DEL key
            VK_HELP = 0x2F,  //HELP key
            VK_0 = 0x30,  //0 key
            VK_1 = 0x31,  //1 key
            VK_2 = 0x32,  //2 key
            VK_3 = 0x33,  //3 key
            VK_4 = 0x34,  //4 key
            VK_5 = 0x35,  //5 key
            VK_6 = 0x36,  //6 key
            VK_7 = 0x37,  //7 key
            VK_8 = 0x38,  //8 key
            VK_9 = 0x39,  //9 key
            VK_A = 0x41,  //A key
            VK_B = 0x42,  //B key
            VK_C = 0x43,  //C key
            VK_D = 0x44,  //D key
            VK_E = 0x45,  //E key
            VK_F = 0x46,  //F key
            VK_G = 0x47,  //G key
            VK_H = 0x48,  //H key
            VK_I = 0x49,  //I key
            VK_J = 0x4A,  //J key
            VK_K = 0x4B,  //K key
            VK_L = 0x4C,  //L key
            VK_M = 0x4D,  //M key
            VK_N = 0x4E,  //N key
            VK_O = 0x4F,  //O key
            VK_P = 0x50,  //P key
            VK_Q = 0x51,  //Q key
            VK_R = 0x52,  //R key
            VK_S = 0x53,  //S key
            VK_T = 0x54,  //T key
            VK_U = 0x55,  //U key
            VK_V = 0x56,  //V key
            VK_W = 0x57,  //W key
            VK_X = 0x58,  //X key
            VK_Y = 0x59,  //Y key
            VK_Z = 0x5A,  //Z key
            VK_NUMPAD0 = 0x60,  //Numeric keypad 0 key
            VK_NUMPAD1 = 0x61,  //Numeric keypad 1 key
            VK_NUMPAD2 = 0x62,  //Numeric keypad 2 key
            VK_NUMPAD3 = 0x63,  //Numeric keypad 3 key
            VK_NUMPAD4 = 0x64,  //Numeric keypad 4 key
            VK_NUMPAD5 = 0x65,  //Numeric keypad 5 key
            VK_NUMPAD6 = 0x66,  //Numeric keypad 6 key
            VK_NUMPAD7 = 0x67,  //Numeric keypad 7 key
            VK_NUMPAD8 = 0x68,  //Numeric keypad 8 key
            VK_NUMPAD9 = 0x69,  //Numeric keypad 9 key
            VK_SEPARATOR = 0x6C,  //Separator key
            VK_SUBTRACT = 0x6D,  //Subtract key
            VK_DECIMAL = 0x6E,  //Decimal key
            VK_DIVIDE = 0x6F,  //Divide key
            VK_F1 = 0x70,  //F1 key
            VK_F2 = 0x71,  //F2 key
            VK_F3 = 0x72,  //F3 key
            VK_F4 = 0x73,  //F4 key
            VK_F5 = 0x74,  //F5 key
            VK_F6 = 0x75,  //F6 key
            VK_F7 = 0x76,  //F7 key
            VK_F8 = 0x77,  //F8 key
            VK_F9 = 0x78,  //F9 key
            VK_F10 = 0x79,  //F10 key
            VK_F11 = 0x7A,  //F11 key
            VK_F12 = 0x7B,  //F12 key
            VK_SCROLL = 0x91,  //SCROLL LOCK key
            VK_LSHIFT = 0xA0,  //Left SHIFT key
            VK_RSHIFT = 0xA1,  //Right SHIFT key
            VK_LCONTROL = 0xA2,  //Left CONTROL key
            VK_RCONTROL = 0xA3,  //Right CONTROL key
            VK_LMENU = 0xA4,   //Left MENU key
            VK_RMENU = 0xA5,  //Right MENU key
            VK_PLAY = 0xFA,  //Play key
            VK_ZOOM = 0xFB, //Zoom key
        } 
        #endregion

        private LowLevelKeyboardProc _proc = hookProc;

        private static IntPtr hhook = IntPtr.Zero;

        public void SetHook()
        {

            IntPtr hInstance = LoadLibrary("User32");
            hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, hInstance, 0);
        }

        public static void UnHook()
        {
            UnhookWindowsHookEx(hhook);
        }

        public static IntPtr hookProc(int code, IntPtr wParam, IntPtr lParam)
        {

            if (code >= 0 && wParam == (IntPtr)WM_KEYDOWN && CommonObj._keyCount <= 0)
            {
                int vkCode = Marshal.ReadInt32(lParam);

                //방향키나 엔터키 텝키 일경우에는 후킹 하지 않는다
              VKeys vk_value = (VKeys)vkCode;
                switch (vk_value)
                {
                    case VKeys.VK_RETURN:
                    case VKeys.VK_TAB:
                    case VKeys.VK_UP:
                    case VKeys.VK_DOWN:
                    case VKeys.VK_LEFT:
                    case VKeys.VK_RIGHT:
                    case VKeys.VK_LCONTROL:
                    case VKeys.VK_RCONTROL:
                    case VKeys.VK_DELETE: 
                    case VKeys.VK_HANGUL:
                    case VKeys.VK_LSHIFT:
                    case VKeys.VK_RSHIFT:
                        
                    return CallNextHookEx(hhook, code, (int)wParam, lParam);
                        

                }
                //사용자의 DataGrid를 EditMode로 전환 한다.
                _dataGrid.BeginEdit();     
                    
                //후킹한 키보드를 강제로 입력 한다.                 
                keybd_event((byte)Marshal.ReadByte(lParam), 0, KEYEVENTF_EXTENDEDKEY, 0); 

                return (IntPtr)1;
            }
            else
                return CallNextHookEx(hhook, code, (int)wParam, lParam);
        }

        #endregion

 

 

 

SetHook() 을 호출하면 키보드 후킹이 시작되고, UnHook()를 호출하면 후킹이 종료 된다.

C#프로그램을 하다가 막히면 결국 WinApi를 사용해서 해결해야 하니, 아무래도 윈도우 Application 개발자는 C++(WinApi)을 기본적으로 알면 많은 도움이 될것 같다.

반응형

http://cmdream.tistory.com/213

반응형

 

 

다국어 처리를 하면서 Settings 에 내가 생성한 Language란 값이 도대체 어디에 저장이 되는지 궁금했다.

찾아본 결과 C# 코드에서 경로를 가져오는 방법을 알아냈다.

해당 파일로 가보면 Language란 값이 셋팅이 되어 있는것을 확인해 볼 수 있다.

결과 값을 확인해 보면 왜저런 경로에 있을까 라는 생각이 든다.

 


//User.Config 파일의 경로를 가져오는 코드
string userConfigPath = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoaming);

 


 

+ Recent posts