Code Coverage Statistics for Source File

c:\Tools\SD3\src\Libraries\ICSharpCode.TextEditor\Project\Src\Gui\Ime.cs

Sequence Point Coverage
N/A
0 of 0
Branch Coverage
N/A
0 of 0
Lines
175
Highlight: Uncovered Code Covered Code
L V Source
1
// <file>
2
//     <copyright see="prj:///doc/copyright.txt"/>
3
//     <license see="prj:///doc/license.txt"/>
4
//     <owner name="Shinsaku Nakagawa" email="shinsaku@users.sourceforge.jp"/>
5
//     <version>$Revision: 2561 $</version>
6
// </file>
7
8
using System;
9
using System.Drawing;
10
using System.Runtime.InteropServices;
11
using System.Windows.Forms;
12
13
namespace ICSharpCode.TextEditor
14
{
15
	/// <summary>
16
	/// Used internally, not for own use.
17
	/// </summary>
18
	internal class Ime
19
	{
20
		public Ime(IntPtr hWnd, Font font)
21
		{
22
			string PROCESSOR_ARCHITEW6432 = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432");
23
			if (PROCESSOR_ARCHITEW6432 == "IA64" || PROCESSOR_ARCHITEW6432 == "AMD64") {
24
				disableIME = true;
25
			}
26
			this.hWnd = hWnd;
27
			this.hIMEWnd = ImmGetDefaultIMEWnd(hWnd);
28
			this.font = font;
29
			SetIMEWindowFont(font);
30
		}
31
32
		private Font font = null;
33
		public Font Font
34
		{
35
			get {
36
				return font;
37
			}
38
			set {
39
				if (!value.Equals(font)) {
40
					font = value;
41
					lf = null;
42
					SetIMEWindowFont(value);
43
				}
44
			}
45
		}
46
47
		public IntPtr HWnd
48
		{
49
			set {
50
				if (this.hWnd != value) {
51
					this.hWnd = value;
52
					this.hIMEWnd = ImmGetDefaultIMEWnd(value);
53
					SetIMEWindowFont(font);
54
				}
55
			}
56
		}
57
58
		[ DllImport("imm32.dll") ]
59
		private static extern IntPtr ImmGetDefaultIMEWnd(IntPtr hWnd);
60
61
		[ DllImport("user32.dll") ]
62
		private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, COMPOSITIONFORM lParam);
63
		[ DllImport("user32.dll") ]
64
		private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, [In, MarshalAs(UnmanagedType.LPStruct)] LOGFONT lParam);
65
66
		[ StructLayout(LayoutKind.Sequential) ]
67
		private class COMPOSITIONFORM
68
		{
69
			public int dwStyle = 0;
70
			public POINT ptCurrentPos = null;
71
			public RECT rcArea = null;
72
		}
73
74
		[ StructLayout(LayoutKind.Sequential) ]
75
		private class POINT
76
		{
77
			public int x = 0;
78
			public int y = 0;
79
		}
80
81
		[ StructLayout(LayoutKind.Sequential) ]
82
		private class RECT
83
		{
84
			public int left = 0;
85
			public int top = 0;
86
			public int right = 0;
87
			public int bottom = 0;
88
		}
89
90
		private const int WM_IME_CONTROL = 0x0283;
91
92
		private const int IMC_SETCOMPOSITIONWINDOW = 0x000c;
93
		private IntPtr hIMEWnd;
94
		private IntPtr hWnd;
95
		private const int CFS_POINT = 0x0002;
96
97
		[ StructLayout(LayoutKind.Sequential) ]
98
		private class LOGFONT
99
		{
100
			public int lfHeight = 0;
101
			public int lfWidth = 0;
102
			public int lfEscapement = 0;
103
			public int lfOrientation = 0;
104
			public int lfWeight = 0;
105
			public byte lfItalic = 0;
106
			public byte lfUnderline = 0;
107
			public byte lfStrikeOut = 0;
108
			public byte lfCharSet = 0;
109
			public byte lfOutPrecision = 0;
110
			public byte lfClipPrecision = 0;
111
			public byte lfQuality = 0;
112
			public byte lfPitchAndFamily = 0;
113
			[ MarshalAs(UnmanagedType.ByValTStr, SizeConst=32) ] public string lfFaceName = null;
114
		}
115
		private const int IMC_SETCOMPOSITIONFONT = 0x000a;
116
		LOGFONT lf = null;
117
		static bool disableIME;
118
		
119
		private void SetIMEWindowFont(Font f)
120
		{
121
			if (disableIME || hIMEWnd == IntPtr.Zero) return;
122
			
123
			if (lf == null) {
124
				lf = new LOGFONT();
125
				f.ToLogFont(lf);
126
				lf.lfFaceName = f.Name;  // This is very important! "Font.ToLogFont" Method sets invalid value to LOGFONT.lfFaceName
127
			}
128
129
			try {
130
				SendMessage(
131
					hIMEWnd,
132
					WM_IME_CONTROL,
133
					new IntPtr(IMC_SETCOMPOSITIONFONT),
134
					lf
135
				);
136
			} catch (AccessViolationException ex) {
137
				Handle(ex);
138
			}
139
		}
140
141
		public void SetIMEWindowLocation(int x, int y)
142
		{
143
			if (disableIME || hIMEWnd == IntPtr.Zero) return;
144
145
			POINT p = new POINT();
146
			p.x = x;
147
			p.y = y;
148
149
			COMPOSITIONFORM lParam = new COMPOSITIONFORM();
150
			lParam.dwStyle = CFS_POINT;
151
			lParam.ptCurrentPos = p;
152
			lParam.rcArea = new RECT();
153
154
			try {
155
				SendMessage(
156
					hIMEWnd,
157
					WM_IME_CONTROL,
158
					new IntPtr(IMC_SETCOMPOSITIONWINDOW),
159
					lParam
160
				);
161
			} catch (AccessViolationException ex) {
162
				Handle(ex);
163
			}
164
		}
165
		
166
		void Handle(Exception ex)
167
		{
168
			Console.WriteLine(ex);
169
			if (!disableIME) {
170
				disableIME = true;
171
				MessageBox.Show("Error calling IME: " + ex.Message + "\nIME is disabled.", "IME error");
172
			}
173
		}
174
	}
175
}