2010-07-20 11 views
7

Tôi đã tạo điều khiển hộp văn bản một dòng của riêng mình trong C# .net 3.5Đưa IME vào hộp văn bản tùy chỉnh, bắt nguồn từ Điều khiển

Tôi đã viết hoàn toàn từ đầu, bao gồm mã lựa chọn của riêng tôi, cuộn, sao chép/dán vv Nó thậm chí có thể chọn văn bản từ trái sang phải, không phải là tôi từng sử dụng ...

Sự cố tôi gặp phải là với IME (trình soạn thảo phương thức nhập). IME hoạt động ở mức độ nào đó, nhưng tôi có một vài vấn đề. Tôi sẽ liệt kê một trong số họ ở đây.

Thông thường, sử dụng Hộp văn bản, xây dựng IME được hiển thị bên trong Hộp văn bản. Tuy nhiên, trong Control của tôi, IME được hiển thị ở góc dưới cùng bên phải của màn hình. Tôi đã thử xem xét các điều khiển tùy chỉnh khác, bao gồm các điều khiển được sử dụng trong SharpDevelop. Tuy nhiên, điều này có cùng một vấn đề. Nhập bằng tiếng Trung, tiếng Nhật hoặc tiếng Hàn khiến các nội dung IME được thực hiện ở góc dưới cùng bên phải của màn hình.

Tôi cần một số gợi ý về cách thực hiện việc này trong hộp văn bản của riêng mình và tôi đã xem API Windows cho IME, nhưng có quá nhiều chức năng và tôi không biết bắt đầu từ đâu.

Vì vậy, có ý tưởng nào không?

Sẽ tốt nếu có bất kỳ mẫu mã nào trong C++ (được quản lý/không được quản lý) hoặc VB.net. Tôi có thể di chuyển nó qua một cách dễ dàng đủ.

Trả lời

10

OK, có vẻ như không có nhiều chuyên gia IME trên StackOverflow ... hoặc không ai quan tâm.

Dù sao, tôi đã tìm ra.

Về cơ bản, tôi phải bẫy các thông điệp sau Windows:

WM_INPUTLANGCHANGE = 0x51 
WM_KEYUP = 0x101 
WM_CHAR = 0x102 
WM_CONVERTREQUESTEX = 0x108 
WM_IME_STARTCOMPOSITION = 0x10D 
WM_IME_ENDCOMPOSITION = 0x10E 
WM_IME_COMPOSITION = 0x10F 
WM_IME_SETCONTEXT = 0x281 
WM_IME_NOTIFY = 0x282 
WM_IME_CONTROL = 0x283 
WM_IME_COMPOSITIONFULL = 0x284 
WM_IME_SELECT = 0x285 
WM_IME_CHAR = 0x286 
WM_IME_REQUEST = 0x0288 
WM_IME_KEYDOWN = 0x290 
WM_IME_KEYUP = 0x291 

Tôi bẫy WM_KEYUPWM_CHAR, bởi vì nếu tôi bấm ở đâu đó ở giữa hợp lại một nhân vật Hàn Quốc, tôi không nhận được một phần nhưng tôi cần phải thêm ký tự đó vào hộp văn bản của tôi. Đây là một hành vi kỳ lạ, tôi tự hỏi nếu đó là một lỗi.

Khi điều đó xảy ra, có các hành vi khác nhau giữa tiếng Hàn, tiếng Trung và tiếng Nhật.

Hàn Quốc thực sự dễ dàng (tôi không chắc chắn về chuyển đổi Hanja mặc dù, bởi vì tôi không biết cách sử dụng nó anyway).

Về cơ bản, đối với tất cả ngôn ngữ, bất cứ khi nào tôi nhận được WM_IME_COMPOSITION, tôi phải gọi ImmGetCompositionString trong Imm32.dll như tôi đã mô tả trong câu trả lời cho this question. Sau đó tôi hiển thị điều này dưới dạng bố cục đang diễn ra, nhưng không thêm nó vào văn bản đã lưu trữ của tôi.

Khi chuỗi đã được tổng hợp thư từ Windows thì khác nhau đối với mỗi IME. Mỗi lần, tôi có thể lấy nó từ thông báo WM_IME_COMPOSITION.

Trong tiếng Hàn, LParam chỉ đơn giản là sẽ GCS_RESULTSTR, và WParam sẽ là nhân vật bước vào, mà tôi chỉ có thể cast để char

Trong tiếng Nhật 'lParam' sẽ GCS_RESULTREADSTR | GCS_RESULTREADCLAUSE | GCS_RESULTSTR0 | GCS_RESULTCLAUSE. Tôi phải sử dụng kết quả của ImmGetCompositionString mà tôi đã lưu trữ từ tin nhắn WM_IME_COMPOSITION trước đó, bởi vì tại thời điểm này, nó sẽ là một chuỗi rỗng.

Ở Trung Quốc, LParam sẽ là GCS_RESULTREADCLAUSE | GCS_RESULTSTR0 | GCS_RESULTCLAUSE. Nó giống với tiếng Nhật, ngoại trừ khi ImmGetCompositionString được lưu trữ trước đó trống, trong trường hợp này tôi cần phải đúc WParam cho một thẻ.

Trong cả ba trường hợp, tôi phải đảm bảo rằng quá trình hiển thị của mình đang được tiến hành sẽ bị xóa.

Nếu tôi nhận WM_IME_STARTCOMPOSITION, tôi đặt một lá cờ sắp xếp bố cục (và hiển thị chuỗi compositing cơ bản dở dang)

Nếu tôi nhận WM_IME_ENDCOMPOSITION tôi xóa cờ đó (và xóa chuỗi compositing cơ bản dở dang).

Đôi khi tôi không nhận được WM_IME_ENDCOMPOSITION, vì vậy, tôi xóa cờ của mình khi nhận được WM_CHAR.


Tất cả trong tất cả, đó là một trải nghiệm học tập rất thú vị và vẫn đang trong quá trình thực hiện - nhưng bây giờ IME có thể sử dụng được! Tôi ở lại làm việc đến 1 giờ sáng để hoàn thành công việc.

+1

Chỉ cần tìm thấy http://stackoverflow.com/questions/434048/how-do-you-use-ime, sẽ rất tuyệt khi được xem trước đó! –