Thread: [GD-Windows] Asian language support (IME)
Brought to you by:
vexxed72
From: Daniel V. <vo...@ep...> - 2002-10-25 05:01:31
|
As I couldn't find much useful documentation/ examples when I was looking for a way to add Asian language support to our input code I thought I should post what works for us now so other people might have it easier than I did :) The below snippet should work fine with Japanese, Chinese and Korean Windows (even Win98) though YMMV. BTW, as a little hint - make sure you have your Korean keyboard plugged in before installing Korean Windows if you don't speak the language as otherwise you won't be able to use the IME key... had to learn that the hard way ;) Some globals. INT SupportsIME, CurrentIMESize; After creating the window. HIMC hImc = ImmGetContext( Window->hWnd ); if( !hImc ) { debugf(TEXT("Creating IME context.")); hImc = ImmCreateContext(); if( hImc ) ImmAssociateContext( Window->hWnd, hImc ); else debugf(TEXT("OS doesn't support IME.")); } else ImmReleaseContext( Window->hWnd, hImc ); SupportsIME = hImc != NULL; Once per frame (could possibly be done by handling some message but I didn't have time to look into this closer and hey, it works ;)). // IME stuff. if( SupportsIME ) { HIMC hImc = ImmGetContext( Window->hWnd ); if( !hImc ) { debugf(TEXT("Creating IME context.")); hImc = ImmCreateContext(); if( hImc ) ImmAssociateContext( Window->hWnd, hImc ); else SupportsIME = 0; CurrentIMESize = 0; } else ImmReleaseContext( Window->hWnd, hImc ); } Below is some code that handles the IME windows message. case WM_IME_COMPOSITION: { // Final composition string. if( lParam & GCS_RESULTSTR ) { HIMC hImc = ImmGetContext(Window->hWnd); if( !hImc ) appErrorf( TEXT("No IME context") ); // Get the size of the result string. INT Size = ImmGetCompositionString( hImc, GCS_RESULTSTR, NULL, 0 ); TCHAR* String = new TCHAR[Size+1]; appMemzero( String, sizeof(TCHAR) * (Size+1) ); // Get the result strings that is generated by IME. Size = ImmGetCompositionString( hImc, GCS_RESULTSTR, String, Size ); Size /= sizeof( TCHAR ); // Send backspaces. for( INT i=0; i<CurrentIMESize; i++ ) { CauseInputEvent( IK_Backspace, IST_Press ); CauseInputEvent( IK_Backspace, IST_Release ); } // Send key to input system. for( INT i=0; i<Size; i++ ) { INT Key = String[i]; if( Key ) Client->Engine->Key( this, IK_Unicode, String[i] ); } delete [] String; ImmReleaseContext(Window->hWnd, hImc); CurrentIMESize = 0; } // Composition in progress. else if( lParam & GCS_COMPSTR ) { HIMC hImc = ImmGetContext(Window->hWnd); if( !hImc ) appErrorf( TEXT("No IME context") ); // Get the size of the result string. INT Size = ImmGetCompositionString( hImc, GCS_COMPSTR, NULL, 0 ); TCHAR* String = new TCHAR[Size+1]; appMemzero( String, sizeof(TCHAR) * (Size+1) ); // Get the result strings that is generated by IME. Size = ImmGetCompositionString( hImc, GCS_COMPSTR, String, Size ); Size /= sizeof( TCHAR ); // Send backspaces. for( INT i=0; i<CurrentIMESize; i++ ) { CauseInputEvent( IK_Backspace, IST_Press ); CauseInputEvent( IK_Backspace, IST_Release ); } // Send key to input system for( INT i=0; i<Size; i++ ) { INT Key = String[i]; if( Key ) Client->Engine->Key( this, IK_Unicode, String[i] ); } delete [] String; ImmReleaseContext(Window->hWnd, hImc); CurrentIMESize = Size; } else return DefWindowProcX( Window->hWnd, iMessage, wParam, lParam ); return 0; } You only want IME stuff for chatting and not for controlling the player so here's some code that toggles it on the fly. InParamter: bool Enable if( SupportsIME ) { if( !Enable ) { ImmAssociateContext( Window->hWnd, NULL ); CurrentIMESize = 0; } else { HIMC hImc = ImmGetContext( Window->hWnd ); if( !hImc ) { debugf(TEXT("Creating IME context.")); hImc = ImmCreateContext(); if( hImc ) ImmAssociateContext( Window->hWnd, hImc ); else SupportsIME = 0; CurrentIMESize = 0; } else { ImmAssociateContext( Window->hWnd, hImc ); ImmReleaseContext( Window->hWnd, hImc ); } } } Hope this of help to someone out there :) -- Daniel, Epic Games Inc. |
From: <cas...@ya...> - 2002-10-25 07:40:23
|
Daniel Vogel wrote: > As I couldn't find much useful documentation/ examples when I was looking > for a way to add Asian language support to our input code I thought I > should > post what works for us now so other people might have it easier than I did > :) I'm actually using SDL unicode support for that. And it's supposed to work, but have never really tested. Does somebody have any experience with it? Anyway, thanks for the code snipplet! Ignacio Castaño cas...@ya... _______________________________________________________________ Yahoo! Messenger Nueva versión: Webcam, voz, y mucho más ¡Gratis! Descárgalo ya desde http://messenger.yahoo.es |
From: Daniel V. <vo...@ep...> - 2002-10-25 18:10:41
|
> I'm actually using SDL unicode support for that. And it's > supposed to work, but have never really tested. Does somebody > have any experience with it? FWIW, SDL handles Unicode though not composition. In Asian languages like Korean a keypress in composition mode could e.g. modify an already typed character or add a character and in addition to that modify a previously typed character :) -- Daniel, Epic Games Inc. |
From: <cas...@ya...> - 2002-10-25 20:22:07
|
Daniel Vogel wrote: > FWIW, SDL handles Unicode though not composition. In Asian languages like > Korean a keypress in composition mode could e.g. modify an already typed > character or add a character and in addition to that modify a previously > typed character :) hmm... I thought that it was handled like spanish accents (áéíóúü) or like the euro character that work fine under SDL. Actually I hadn't planned to support Asian languages, but I expected them to work correctly. So when you get a composition character you basically remove the previous characters and insert the new one, right? It would be nice to support this somehow under SDL... I'm pretty busy right now, but I will see what can I do. Ignacio Castaño cas...@ya... _______________________________________________________________ Yahoo! Messenger Nueva versión: Webcam, voz, y mucho más ¡Gratis! Descárgalo ya desde http://messenger.yahoo.es |
From: jason z. <dir...@21...> - 2002-10-28 08:31:06
|
SXQgc2VlbXMgeW91IGRpZG4ndCBoYW5kbGUgdGhlIElNRSBjYW5kaWRhdGUgbGlzdC4gVGhlbiB0 aGUgdXNlciBjYW5ub3Qgc2VsZWN0IG9uZQ0KZnJvbSBhIGZldyB3b3JkcyBvciBwaHJhc2VzIHdo b3NlIGNvbXBvc2l0aW9uIHN0cmluZ3MgYXJlIHRoZSBzYW1lLg0KLS0tLS0gT3JpZ2luYWwgTWVz c2FnZSAtLS0tLSANCkZyb206ICJEYW5pZWwgVm9nZWwiIDx2b2dlbEBlcGljZ2FtZXMuY29tPg0K VG86IDxnYW1lZGV2bGlzdHMtd2luZG93c0BsaXN0cy5zb3VyY2Vmb3JnZS5uZXQ+DQpTZW50OiBG cmlkYXksIE9jdG9iZXIgMjUsIDIwMDIgMTowMSBQTQ0KU3ViamVjdDogW0dELVdpbmRvd3NdIEFz aWFuIGxhbmd1YWdlIHN1cHBvcnQgKElNRSkNCg0KDQo+IEFzIEkgY291bGRuJ3QgZmluZCBtdWNo IHVzZWZ1bCBkb2N1bWVudGF0aW9uLyBleGFtcGxlcyB3aGVuIEkgd2FzIGxvb2tpbmcNCj4gZm9y IGEgd2F5IHRvIGFkZCBBc2lhbiBsYW5ndWFnZSBzdXBwb3J0IHRvIG91ciBpbnB1dCBjb2RlIEkg dGhvdWdodCBJIHNob3VsZA0KPiBwb3N0IHdoYXQgd29ya3MgZm9yIHVzIG5vdyBzbyBvdGhlciBw ZW9wbGUgbWlnaHQgaGF2ZSBpdCBlYXNpZXIgdGhhbiBJIGRpZA0KPiA6KQ0KPiANCj4gVGhlIGJl bG93IHNuaXBwZXQgc2hvdWxkIHdvcmsgZmluZSB3aXRoIEphcGFuZXNlLCBDaGluZXNlIGFuZCBL b3JlYW4gV2luZG93cw0KPiAoZXZlbiBXaW45OCkgdGhvdWdoIFlNTVYuDQo+IA0KPiBCVFcsIGFz IGEgbGl0dGxlIGhpbnQgLSBtYWtlIHN1cmUgeW91IGhhdmUgeW91ciBLb3JlYW4ga2V5Ym9hcmQg cGx1Z2dlZCBpbg0KPiBiZWZvcmUgaW5zdGFsbGluZyBLb3JlYW4gV2luZG93cyBpZiB5b3UgZG9u J3Qgc3BlYWsgdGhlIGxhbmd1YWdlIGFzDQo+IG90aGVyd2lzZSB5b3Ugd29uJ3QgYmUgYWJsZSB0 byB1c2UgdGhlIElNRSBrZXkuLi4gaGFkIHRvIGxlYXJuIHRoYXQgdGhlIGhhcmQNCj4gd2F5IDsp DQo+IA0KPiANCj4gU29tZSBnbG9iYWxzLg0KPiANCj4gSU5UIFN1cHBvcnRzSU1FLA0KPiBDdXJy ZW50SU1FU2l6ZTsNCj4gDQo+IA0KPiBBZnRlciBjcmVhdGluZyB0aGUgd2luZG93Lg0KPiANCj4g SElNQyBoSW1jID0gSW1tR2V0Q29udGV4dCggV2luZG93LT5oV25kICk7DQo+IGlmKCAhaEltYyAp DQo+IHsNCj4gZGVidWdmKFRFWFQoIkNyZWF0aW5nIElNRSBjb250ZXh0LiIpKTsNCj4gaEltYyA9 IEltbUNyZWF0ZUNvbnRleHQoKTsNCj4gaWYoIGhJbWMgKQ0KPiBJbW1Bc3NvY2lhdGVDb250ZXh0 KCBXaW5kb3ctPmhXbmQsIGhJbWMgKTsNCj4gZWxzZQ0KPiBkZWJ1Z2YoVEVYVCgiT1MgZG9lc24n dCBzdXBwb3J0IElNRS4iKSk7DQo+IH0NCj4gZWxzZQ0KPiBJbW1SZWxlYXNlQ29udGV4dCggV2lu ZG93LT5oV25kLCBoSW1jICk7DQo+IA0KPiBTdXBwb3J0c0lNRSA9IGhJbWMgIT0gTlVMTDsNCj4g DQo+IA0KPiANCj4gT25jZSBwZXIgZnJhbWUgKGNvdWxkIHBvc3NpYmx5IGJlIGRvbmUgYnkgaGFu ZGxpbmcgc29tZSBtZXNzYWdlIGJ1dCBJIGRpZG4ndA0KPiBoYXZlIHRpbWUgdG8gbG9vayBpbnRv IHRoaXMgY2xvc2VyIGFuZCBoZXksIGl0IHdvcmtzIDspKS4NCj4gDQo+IC8vIElNRSBzdHVmZi4N Cj4gaWYoIFN1cHBvcnRzSU1FICkNCj4gew0KPiBISU1DIGhJbWMgPSBJbW1HZXRDb250ZXh0KCBX aW5kb3ctPmhXbmQgKTsNCj4gaWYoICFoSW1jICkNCj4gew0KPiBkZWJ1Z2YoVEVYVCgiQ3JlYXRp bmcgSU1FIGNvbnRleHQuIikpOw0KPiBoSW1jID0gSW1tQ3JlYXRlQ29udGV4dCgpOw0KPiBpZigg aEltYyApDQo+IEltbUFzc29jaWF0ZUNvbnRleHQoIFdpbmRvdy0+aFduZCwgaEltYyApOw0KPiBl bHNlDQo+IFN1cHBvcnRzSU1FID0gMDsNCj4gDQo+IEN1cnJlbnRJTUVTaXplID0gMDsNCj4gfQ0K PiBlbHNlDQo+IEltbVJlbGVhc2VDb250ZXh0KCBXaW5kb3ctPmhXbmQsIGhJbWMgKTsNCj4gfQ0K PiANCj4gDQo+IA0KPiBCZWxvdyBpcyBzb21lIGNvZGUgdGhhdCBoYW5kbGVzIHRoZSBJTUUgd2lu ZG93cyBtZXNzYWdlLg0KPiANCj4gDQo+IGNhc2UgV01fSU1FX0NPTVBPU0lUSU9OOg0KPiB7DQo+ IC8vIEZpbmFsIGNvbXBvc2l0aW9uIHN0cmluZy4NCj4gaWYoIGxQYXJhbSAmIEdDU19SRVNVTFRT VFIgKQ0KPiB7DQo+IEhJTUMgaEltYyA9IEltbUdldENvbnRleHQoV2luZG93LT5oV25kKTsNCj4g DQo+IGlmKCAhaEltYyApDQo+IGFwcEVycm9yZiggVEVYVCgiTm8gSU1FIGNvbnRleHQiKSApOw0K PiANCj4gLy8gR2V0IHRoZSBzaXplIG9mIHRoZSByZXN1bHQgc3RyaW5nLg0KPiBJTlQgU2l6ZSA9 IEltbUdldENvbXBvc2l0aW9uU3RyaW5nKCBoSW1jLCBHQ1NfUkVTVUxUU1RSLCBOVUxMLCAwICk7 DQo+IA0KPiBUQ0hBUiogU3RyaW5nID0gbmV3IFRDSEFSW1NpemUrMV07DQo+IGFwcE1lbXplcm8o IFN0cmluZywgc2l6ZW9mKFRDSEFSKSAqIChTaXplKzEpICk7DQo+IA0KPiAvLyBHZXQgdGhlIHJl c3VsdCBzdHJpbmdzIHRoYXQgaXMgZ2VuZXJhdGVkIGJ5IElNRS4NCj4gU2l6ZSA9IEltbUdldENv bXBvc2l0aW9uU3RyaW5nKCBoSW1jLCBHQ1NfUkVTVUxUU1RSLCBTdHJpbmcsIFNpemUgKTsNCj4g U2l6ZSAvPSBzaXplb2YoIFRDSEFSICk7DQo+IA0KPiAvLyBTZW5kIGJhY2tzcGFjZXMuDQo+IGZv ciggSU5UIGk9MDsgaTxDdXJyZW50SU1FU2l6ZTsgaSsrICkNCj4gew0KPiBDYXVzZUlucHV0RXZl bnQoIElLX0JhY2tzcGFjZSwgSVNUX1ByZXNzICk7DQo+IENhdXNlSW5wdXRFdmVudCggSUtfQmFj a3NwYWNlLCBJU1RfUmVsZWFzZSApOw0KPiB9DQo+IA0KPiAvLyBTZW5kIGtleSB0byBpbnB1dCBz eXN0ZW0uDQo+IGZvciggSU5UIGk9MDsgaTxTaXplOyBpKysgKQ0KPiB7DQo+IElOVCBLZXkgPSBT dHJpbmdbaV07DQo+IGlmKCBLZXkgKQ0KPiBDbGllbnQtPkVuZ2luZS0+S2V5KCB0aGlzLCBJS19V bmljb2RlLCBTdHJpbmdbaV0gKTsNCj4gfQ0KPiANCj4gZGVsZXRlIFtdIFN0cmluZzsNCj4gDQo+ IEltbVJlbGVhc2VDb250ZXh0KFdpbmRvdy0+aFduZCwgaEltYyk7DQo+IA0KPiBDdXJyZW50SU1F U2l6ZSA9IDA7DQo+IH0NCj4gLy8gQ29tcG9zaXRpb24gaW4gcHJvZ3Jlc3MuDQo+IGVsc2UgaWYo IGxQYXJhbSAmIEdDU19DT01QU1RSICkNCj4gew0KPiBISU1DIGhJbWMgPSBJbW1HZXRDb250ZXh0 KFdpbmRvdy0+aFduZCk7DQo+IA0KPiBpZiggIWhJbWMgKQ0KPiBhcHBFcnJvcmYoIFRFWFQoIk5v IElNRSBjb250ZXh0IikgKTsNCj4gDQo+IC8vIEdldCB0aGUgc2l6ZSBvZiB0aGUgcmVzdWx0IHN0 cmluZy4NCj4gSU5UIFNpemUgPSBJbW1HZXRDb21wb3NpdGlvblN0cmluZyggaEltYywgR0NTX0NP TVBTVFIsIE5VTEwsIDAgKTsNCj4gDQo+IFRDSEFSKiBTdHJpbmcgPSBuZXcgVENIQVJbU2l6ZSsx XTsNCj4gYXBwTWVtemVybyggU3RyaW5nLCBzaXplb2YoVENIQVIpICogKFNpemUrMSkgKTsNCj4g DQo+IC8vIEdldCB0aGUgcmVzdWx0IHN0cmluZ3MgdGhhdCBpcyBnZW5lcmF0ZWQgYnkgSU1FLg0K PiBTaXplID0gSW1tR2V0Q29tcG9zaXRpb25TdHJpbmcoIGhJbWMsIEdDU19DT01QU1RSLCBTdHJp bmcsIFNpemUgKTsNCj4gU2l6ZSAvPSBzaXplb2YoIFRDSEFSICk7DQo+IA0KPiAvLyBTZW5kIGJh Y2tzcGFjZXMuDQo+IGZvciggSU5UIGk9MDsgaTxDdXJyZW50SU1FU2l6ZTsgaSsrICkNCj4gew0K PiBDYXVzZUlucHV0RXZlbnQoIElLX0JhY2tzcGFjZSwgSVNUX1ByZXNzICk7DQo+IENhdXNlSW5w dXRFdmVudCggSUtfQmFja3NwYWNlLCBJU1RfUmVsZWFzZSApOw0KPiB9DQo+IA0KPiAvLyBTZW5k IGtleSB0byBpbnB1dCBzeXN0ZW0NCj4gZm9yKCBJTlQgaT0wOyBpPFNpemU7IGkrKyApDQo+IHsN Cj4gSU5UIEtleSA9IFN0cmluZ1tpXTsNCj4gaWYoIEtleSApDQo+IENsaWVudC0+RW5naW5lLT5L ZXkoIHRoaXMsIElLX1VuaWNvZGUsIFN0cmluZ1tpXSApOw0KPiB9DQo+IA0KPiBkZWxldGUgW10g U3RyaW5nOw0KPiANCj4gSW1tUmVsZWFzZUNvbnRleHQoV2luZG93LT5oV25kLCBoSW1jKTsNCj4g DQo+IEN1cnJlbnRJTUVTaXplID0gU2l6ZTsNCj4gfQ0KPiBlbHNlDQo+IHJldHVybiBEZWZXaW5k b3dQcm9jWCggV2luZG93LT5oV25kLCBpTWVzc2FnZSwgd1BhcmFtLCBsUGFyYW0gKTsNCj4gDQo+ IHJldHVybiAwOw0KPiB9DQo+IA0KPiANCj4gWW91IG9ubHkgd2FudCBJTUUgc3R1ZmYgZm9yIGNo YXR0aW5nIGFuZCBub3QgZm9yIGNvbnRyb2xsaW5nIHRoZSBwbGF5ZXIgc28NCj4gaGVyZSdzIHNv bWUgY29kZSB0aGF0IHRvZ2dsZXMgaXQgb24gdGhlIGZseS4NCj4gDQo+IEluUGFyYW10ZXI6IGJv b2wgRW5hYmxlDQo+IA0KPiBpZiggU3VwcG9ydHNJTUUgKQ0KPiB7DQo+IGlmKCAhRW5hYmxlICkN Cj4gew0KPiBJbW1Bc3NvY2lhdGVDb250ZXh0KCBXaW5kb3ctPmhXbmQsIE5VTEwgKTsNCj4gQ3Vy cmVudElNRVNpemUgPSAwOw0KPiB9DQo+IGVsc2UNCj4gew0KPiBISU1DIGhJbWMgPSBJbW1HZXRD b250ZXh0KCBXaW5kb3ctPmhXbmQgKTsNCj4gaWYoICFoSW1jICkNCj4gew0KPiBkZWJ1Z2YoVEVY VCgiQ3JlYXRpbmcgSU1FIGNvbnRleHQuIikpOw0KPiBoSW1jID0gSW1tQ3JlYXRlQ29udGV4dCgp Ow0KPiBpZiggaEltYyApDQo+IEltbUFzc29jaWF0ZUNvbnRleHQoIFdpbmRvdy0+aFduZCwgaElt YyApOw0KPiBlbHNlDQo+IFN1cHBvcnRzSU1FID0gMDsNCj4gDQo+IEN1cnJlbnRJTUVTaXplID0g MDsNCj4gfQ0KPiBlbHNlDQo+IHsNCj4gSW1tQXNzb2NpYXRlQ29udGV4dCggV2luZG93LT5oV25k LCBoSW1jICk7DQo+IEltbVJlbGVhc2VDb250ZXh0KCBXaW5kb3ctPmhXbmQsIGhJbWMgKTsNCj4g fQ0KPiB9DQo+IH0NCj4gDQo+IA0KPiBIb3BlIHRoaXMgb2YgaGVscCB0byBzb21lb25lIG91dCB0 aGVyZSA6KQ0KPiANCj4gLS0gRGFuaWVsLCBFcGljIEdhbWVzIEluYy4NCj4gDQo+IA0KPiANCj4g LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0K PiBUaGlzIHNmLm5ldCBlbWFpbCBpcyBzcG9uc29yZWQgYnk6IEluZmx1ZW5jZSB0aGUgZnV0dXJl IA0KPiBvZiBKYXZhKFRNKSB0ZWNobm9sb2d5LiBKb2luIHRoZSBKYXZhIENvbW11bml0eSANCj4g UHJvY2VzcyhTTSkgKEpDUChTTSkpIHByb2dyYW0gbm93LiANCj4gaHR0cDovL2Fkcy5zb3VyY2Vm b3JnZS5uZXQvY2dpLWJpbi9yZWRpcmVjdC5wbD9zdW5tMDAwNGVuDQo+IF9fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQo+IEdhbWVkZXZsaXN0cy13aW5kb3dz IG1haWxpbmcgbGlzdA0KPiBHYW1lZGV2bGlzdHMtd2luZG93c0BsaXN0cy5zb3VyY2Vmb3JnZS5u ZXQNCj4gaHR0cHM6Ly9saXN0cy5zb3VyY2Vmb3JnZS5uZXQvbGlzdHMvbGlzdGluZm8vZ2FtZWRl dmxpc3RzLXdpbmRvd3MNCj4gQXJjaGl2ZXM6DQo+IGh0dHA6Ly9zb3VyY2Vmb3JnZS5uZXQvbWFp bGFyY2hpdmUvZm9ydW0ucGhwP2ZvcnVtX2lkPTU1NQ0KPiANCj4gDQo= |
From: Daniel V. <vo...@ep...> - 2002-10-28 08:48:39
|
> It seems you didn't handle the IME candidate list. Then the user > cannot select one from a few words or phrases whose composition > strings are the same. Is the candidate list a form of "automatic completion"? Can you enter every word/ phrase without using/ implementing the candidate list? -- Daniel, Epic Games Inc. |
From: jason z. <dir...@21...> - 2002-10-28 09:08:48
|
Tm9wZS4NClNvbWUgSU1FcyBkbyBhdXRvbWF0aWMgY29tcGxldGlvbiB1c2luZyBjYW5kaWRhdGUg bGlzdC4gQnV0IGl0IGlzIG5vdCBqdXN0IGNvbXBsZXRpb24sIA0Kc29tZXRpbWVzIGl0IG5lZWRz IHRoZSB1c2VyIHRvIHNlbGVjdCBmcm9tIGNhbmRpZGF0ZSBsaXN0IGJ5IHByZXNzaW5nIG51bWJl ciBrZXkuDQoNCi0tLS0tIE9yaWdpbmFsIE1lc3NhZ2UgLS0tLS0gDQpGcm9tOiAiRGFuaWVsIFZv Z2VsIiA8dm9nZWxAZXBpY2dhbWVzLmNvbT4NClRvOiAiamFzb24gemhhbmciIDxkaXJlY3Rib3hA MjFjbi5jb20+OyA8Z2FtZWRldmxpc3RzLXdpbmRvd3NAbGlzdHMuc291cmNlZm9yZ2UubmV0Pg0K U2VudDogTW9uZGF5LCBPY3RvYmVyIDI4LCAyMDAyIDQ6NDggUE0NClN1YmplY3Q6IFJFOiBbR0Qt V2luZG93c10gQXNpYW4gbGFuZ3VhZ2Ugc3VwcG9ydCAoSU1FKQ0KDQoNCj4gPiBJdCBzZWVtcyB5 b3UgZGlkbid0IGhhbmRsZSB0aGUgSU1FIGNhbmRpZGF0ZSBsaXN0LiBUaGVuIHRoZSB1c2VyDQo+ ID4gY2Fubm90IHNlbGVjdCBvbmUgZnJvbSBhIGZldyB3b3JkcyBvciBwaHJhc2VzIHdob3NlIGNv bXBvc2l0aW9uDQo+ID4gc3RyaW5ncyBhcmUgdGhlIHNhbWUuDQo+IA0KPiBJcyB0aGUgY2FuZGlk YXRlIGxpc3QgYSBmb3JtIG9mICJhdXRvbWF0aWMgY29tcGxldGlvbiI/IENhbiB5b3UgZW50ZXIg ZXZlcnkNCj4gd29yZC8gcGhyYXNlIHdpdGhvdXQgdXNpbmcvIGltcGxlbWVudGluZyB0aGUgY2Fu ZGlkYXRlIGxpc3Q/DQo+IA0KPiAtLSBEYW5pZWwsIEVwaWMgR2FtZXMgSW5jLg0KPiANCj4gDQo= |
From: Daniel V. <vo...@ep...> - 2002-10-29 01:06:18
|
I forgot a small snippet in my original email. Before destroying your window you want to do something like below: HIMC hImc = ImmGetContext( Window->hWnd ); if( hImc ) { ImmAssociateContext( Window->hWnd, NULL ); ImmDestroyContext( hImc ); } Thanks to Andy Glaister for pointing it out :) -- Daniel, Epic Games Inc. > -----Original Message----- > From: gam...@li... > [mailto:gam...@li...]On Behalf Of > Daniel Vogel > Sent: Friday, October 25, 2002 1:01 AM > To: gam...@li... > Subject: [GD-Windows] Asian language support (IME) > > > As I couldn't find much useful documentation/ examples when I was looking > for a way to add Asian language support to our input code I > thought I should > post what works for us now so other people might have it easier than I did > :) > > The below snippet should work fine with Japanese, Chinese and > Korean Windows > (even Win98) though YMMV. > > BTW, as a little hint - make sure you have your Korean keyboard plugged in > before installing Korean Windows if you don't speak the language as > otherwise you won't be able to use the IME key... had to learn > that the hard > way ;) > > > Some globals. > > INT SupportsIME, > CurrentIMESize; > > > After creating the window. > > HIMC hImc = ImmGetContext( Window->hWnd ); > if( !hImc ) > { > debugf(TEXT("Creating IME context.")); > hImc = ImmCreateContext(); > if( hImc ) > ImmAssociateContext( Window->hWnd, hImc ); > else > debugf(TEXT("OS doesn't support IME.")); > } > else > ImmReleaseContext( Window->hWnd, hImc ); > > SupportsIME = hImc != NULL; > > > > Once per frame (could possibly be done by handling some message > but I didn't > have time to look into this closer and hey, it works ;)). > > // IME stuff. > if( SupportsIME ) > { > HIMC hImc = ImmGetContext( Window->hWnd ); > if( !hImc ) > { > debugf(TEXT("Creating IME context.")); > hImc = ImmCreateContext(); > if( hImc ) > ImmAssociateContext( Window->hWnd, hImc ); > else > SupportsIME = 0; > > CurrentIMESize = 0; > } > else > ImmReleaseContext( Window->hWnd, hImc ); > } > > > > Below is some code that handles the IME windows message. > > > case WM_IME_COMPOSITION: > { > // Final composition string. > if( lParam & GCS_RESULTSTR ) > { > HIMC hImc = ImmGetContext(Window->hWnd); > > if( !hImc ) > appErrorf( TEXT("No IME context") ); > > // Get the size of the result string. > INT Size = ImmGetCompositionString( hImc, > GCS_RESULTSTR, NULL, 0 ); > > TCHAR* String = new TCHAR[Size+1]; > appMemzero( String, sizeof(TCHAR) * (Size+1) ); > > // Get the result strings that is generated by IME. > Size = ImmGetCompositionString( hImc, > GCS_RESULTSTR, String, Size ); > Size /= sizeof( TCHAR ); > > // Send backspaces. > for( INT i=0; i<CurrentIMESize; i++ ) > { > CauseInputEvent( IK_Backspace, IST_Press ); > CauseInputEvent( IK_Backspace, IST_Release ); > } > > // Send key to input system. > for( INT i=0; i<Size; i++ ) > { > INT Key = String[i]; > if( Key ) > Client->Engine->Key( this, > IK_Unicode, String[i] ); > } > > delete [] String; > > ImmReleaseContext(Window->hWnd, hImc); > > CurrentIMESize = 0; > } > // Composition in progress. > else if( lParam & GCS_COMPSTR ) > { > HIMC hImc = ImmGetContext(Window->hWnd); > > if( !hImc ) > appErrorf( TEXT("No IME context") ); > > // Get the size of the result string. > INT Size = ImmGetCompositionString( hImc, > GCS_COMPSTR, NULL, 0 ); > > TCHAR* String = new TCHAR[Size+1]; > appMemzero( String, sizeof(TCHAR) * (Size+1) ); > > // Get the result strings that is generated by IME. > Size = ImmGetCompositionString( hImc, GCS_COMPSTR, > String, Size ); > Size /= sizeof( TCHAR ); > > // Send backspaces. > for( INT i=0; i<CurrentIMESize; i++ ) > { > CauseInputEvent( IK_Backspace, IST_Press ); > CauseInputEvent( IK_Backspace, IST_Release ); > } > > // Send key to input system > for( INT i=0; i<Size; i++ ) > { > INT Key = String[i]; > if( Key ) > Client->Engine->Key( this, > IK_Unicode, String[i] ); > } > > delete [] String; > > ImmReleaseContext(Window->hWnd, hImc); > > CurrentIMESize = Size; > } > else > return DefWindowProcX( Window->hWnd, iMessage, > wParam, lParam ); > > return 0; > } > > > You only want IME stuff for chatting and not for controlling the player so > here's some code that toggles it on the fly. > > InParamter: bool Enable > > if( SupportsIME ) > { > if( !Enable ) > { > ImmAssociateContext( Window->hWnd, NULL ); > CurrentIMESize = 0; > } > else > { > HIMC hImc = ImmGetContext( Window->hWnd ); > if( !hImc ) > { > debugf(TEXT("Creating IME context.")); > hImc = ImmCreateContext(); > if( hImc ) > ImmAssociateContext( Window->hWnd, hImc ); > else > SupportsIME = 0; > > CurrentIMESize = 0; > } > else > { > ImmAssociateContext( Window->hWnd, hImc ); > ImmReleaseContext( Window->hWnd, hImc ); > } > } > } > > > Hope this of help to someone out there :) > > -- Daniel, Epic Games Inc. > > > > ------------------------------------------------------- > This sf.net email is sponsored by: Influence the future > of Java(TM) technology. Join the Java Community > Process(SM) (JCP(SM)) program now. > http://ads.sourceforge.net/cgi-bin/redirect.pl?sunm0004en > _______________________________________________ > Gamedevlists-windows mailing list > Gam...@li... > https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_id=555 > |