View Issue Details

IDProjectCategoryView StatusLast Update
0013140LazarusIDEpublic2018-05-12 20:00
ReporterSaeka-jpAssigned ToMartin Friebe 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version0.9.26Product Build 
Target Version1.0.0Fixed in Version0.9.31 (SVN) 
Summary0013140: Cannot input Japanese character correctly in IDE( SynEdit )
DescriptionWe use IME(Input Method Editor) when input Japanese character.
And we cannot input on Lazarus IDE correctry, for now.

( What about IME? http://en.wikipedia.org/wiki/Input_method )

This is not only issue for Japanese character, but also Chinese, Korean, etc..( almost Far East Asia Language )

TagsNo tags attached.
Fixed in Revision
LazTarget1.0
WidgetsetWin32/Win64
Attached Files
  • imm.pp (29,961 bytes)
    {
        This file is part of the Free Pascal run time library.
        Copyright (c) 2005 by the Free Pascal development team
        Header translation by Alexey Barkovoy for Free Pascal Platform
    
        Input Method Manager definitions
    
        See the file COPYING.FPC, included in this distribution,
        for details about the copyright.
    
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
     **********************************************************************}
    
    
    (**********************************************************************)
    (*      imm.h - Input Method Manager definitions                      *)
    (*                                                                    *)
    (*      Copyright (c) Microsoft Corporation. All rights reserved.     *)
    (**********************************************************************)
    
    {$mode objfpc}
    
    unit Imm;
    
    interface
    
    uses
      Windows;
    
    type
      HIMC  = THandle;
      HIMCC = THandle;
    
      LPHKL  = ^HKL;
      LPUINT = ^LongWord;
    
      tagCOMPOSITIONFORM = record
        dwStyle: DWORD;
        ptCurrentPos: TPoint;
        rcArea:  TRect;
      end;
      COMPOSITIONFORM = tagCOMPOSITIONFORM;
      TCompositionForm = tagCOMPOSITIONFORM;
      PCompositionForm = ^TCompositionForm;
    
      tagCANDIDATEFORM = record
        dwIndex: DWORD;
        dwStyle: DWORD;
        ptCurrentPos: TPoint;
        rcArea: TRect;
      end;
      CANDIDATEFORM = tagCANDIDATEFORM;
      TCandidateForm = tagCANDIDATEFORM;
      PCandidateForm = ^TCandidateForm;
    
      tagCANDIDATELIST = record
        dwSize: DWORD;
        dwStyle: DWORD;
        dwCount: DWORD;
        dwSelection: DWORD;
        dwPageStart: DWORD;
        dwPageSize: DWORD;
        dwOffset: array[0..0] of DWORD;
      end;
      CANDIDATELIST = tagCANDIDATELIST;
      TCandidateList = tagCANDIDATELIST;
      PCandidateList = ^TCandidateList;
    
      tagREGISTERWORDA = record
        lpReading: PAnsiChar;
        lpWord: PAnsiChar;
      end;
      REGISTERWORDA = tagREGISTERWORDA;
      TRegisterWordA = tagREGISTERWORDA;
      PRegisterWordA = ^TRegisterWordA;
    
      tagREGISTERWORDW = record
        lpReading: PWideChar;
        lpWord: PWideChar;
      end;
      REGISTERWORDW = tagREGISTERWORDW;
      TRegisterWordW = tagREGISTERWORDW;
      PRegisterWordW = ^TRegisterWordW;
    
      {$IFDEF UNICODE}
      REGISTERWORD = REGISTERWORDW;
      TRegisterWord = TRegisterWordW;
      PRegisterWord = PRegisterWordW;
      {$ELSE}
      REGISTERWORD = REGISTERWORDA;
      TRegisterWord = TRegisterWordA;
      PRegisterWord = PRegisterWordA;
      {$ENDIF}
    
      tagRECONVERTSTRING = record
        dwSize: DWORD;
        dwVersion: DWORD;
        dwStrLen: DWORD;
        dwStrOffset: DWORD;
        dwCompStrLen: DWORD;
        dwCompStrOffset: DWORD;
        dwTargetStrLen: DWORD;
        dwTargetStrOffset: DWORD;
      end;
      RECONVERTSTRING = tagRECONVERTSTRING;
      TReconvertString = tagRECONVERTSTRING;
      PReconvertString = ^TReconvertString;
    
    const
      STYLE_DESCRIPTION_SIZE = 32;
    
    type
      tagSTYLEBUFA = record
        dwStyle: DWORD;
        szDescription: array [0..STYLE_DESCRIPTION_SIZE-1] of AnsiChar;
      end;
      STYLEBUFA = tagSTYLEBUFA;
      TStyleBufA = tagSTYLEBUFA;
      PStyleBufA = ^TStyleBufA;
    
      tagSTYLEBUFW = record
        dwStyle: DWORD;
        szDescription: array [0..STYLE_DESCRIPTION_SIZE-1] of WideChar;
      end;
      STYLEBUFW = tagSTYLEBUFW;
      TStyleBufW = tagSTYLEBUFW;
      PStyleBufW = ^TStyleBufW;
    
      {$IFDEF UNICODE}
      STYLEBUF = STYLEBUFW;
      TStyleBuf = TStyleBufW;
      PStyleBuf = PStyleBufW;
      {$ELSE}
      STYLEBUF = STYLEBUFA;
      TStyleBuf = TStyleBufA;
      PStyleBuf = PStyleBufA;
      {$ENDIF}
    
    const
      IMEMENUITEM_STRING_SIZE = 80;
    
    type
      tagIMEMENUITEMINFOA = record
        cbSize: LongWord;
        fType: LongWord;
        fState: LongWord;
        wID: LongWord;
        hbmpChecked: HBITMAP;
        hbmpUnchecked: HBITMAP;
        dwItemData: DWORD;
        szString: array[0..IMEMENUITEM_STRING_SIZE-1] of AnsiChar;
        hbmpItem: HBITMAP;
      end;
      IMEMENUITEMINFOA = tagIMEMENUITEMINFOA;
      TIMEMenuItemInfoA = tagIMEMENUITEMINFOA;
      PIMEMenuItemInfoA = ^TIMEMenuItemInfoA;
    
      tagIMEMENUITEMINFOW = record
        cbSize: LongWord;
        fType: LongWord;
        fState: LongWord;
        wID: LongWord;
        hbmpChecked: HBITMAP;
        hbmpUnchecked: HBITMAP;
        dwItemData: DWORD;
        szString: array[0..IMEMENUITEM_STRING_SIZE-1] of WideChar;
        hbmpItem: HBITMAP;
      end;
      IMEMENUITEMINFOW = tagIMEMENUITEMINFOW;
      TIMEMenuItemInfoW = tagIMEMENUITEMINFOW;
      PIMEMenuItemInfoW = ^TIMEMenuItemInfoW;
    
      {$IFDEF UNICODE}
      IMEMENUITEMINFO = IMEMENUITEMINFOW;
      TIMEMenuItemInfo = TIMEMenuItemInfoW;
      PIMEMenuItemInfo = PIMEMenuItemInfoW;
      {$ELSE}
      IMEMENUITEMINFO = IMEMENUITEMINFOA;
      TIMEMenuItemInfo = TIMEMenuItemInfoA;
      PIMEMenuItemInfo = PIMEMenuItemInfoA;
      {$ENDIF}
    
    
      tagIMECHARPOSITION = record
        dwSize: DWORD;
        dwCharPos: DWORD;
        pt: TPoint;
        cLineHeight: LongWord;
        rcDocument: TRect;
      end;
      IMECHARPOSITION = tagIMECHARPOSITION;
      TIMECharPosition = tagIMECHARPOSITION;
      PIMECharPosition = ^TIMECharPosition;
    
    
      IMCEnumProc = function (h: HIMC; l: LPARAM): BOOL; stdcall;
    
    
    {$IFDEF FPC}
    type
      PLOGFONTA = PLOGFONT;
      PLOGFONTW = ^TLOGFONTW;
    
      tagLOGFONTW = packed record
        lfHeight: Longint;
        lfWidth: Longint;
        lfEscapement: Longint;
        lfOrientation: Longint;
        lfWeight: Longint;
        lfItalic: Byte;
        lfUnderline: Byte;
        lfStrikeOut: Byte;
        lfCharSet: Byte;
        lfOutPrecision: Byte;
        lfClipPrecision: Byte;
        lfQuality: Byte;
        lfPitchAndFamily: Byte;
        lfFaceName: array[0..LF_FACESIZE - 1] of WideChar;
      end;
      TLOGFONTW = tagLOGFONTW;
    
    {$ENDIF}
    
    
    // prototype of IMM API
    
    const
      imm32 = 'imm32.dll';
      
    function ImmInstallIMEA(lpszIMEFileName, lpszLayoutText: PAnsiChar): HKL; stdcall; external imm32;
    function ImmInstallIMEW(lpszIMEFileName, lpszLayoutText: PWideChar): HKL; stdcall; external imm32;
    function ImmInstallIME(lpszIMEFileName, lpszLayoutText: PChar): HKL; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmInstallIMEW'{$ELSE}'ImmInstallIMEA'{$ENDIF};
    
    function ImmGetDefaultIMEWnd(hWnd: HWND): HWND; stdcall; external imm32;
    
    function ImmGetDescriptionA(hKl: HKL; PAnsiChar: PAnsiChar; uBufLen: UINT): UINT; stdcall; external imm32;
    function ImmGetDescriptionW(hKl: HKL; PWideChar: PWideChar; uBufLen: UINT): UINT; stdcall; external imm32;
    function ImmGetDescription(hKl: HKL; PChar: PChar; uBufLen: UINT): UINT; stdcall; external imm32 name {$IFDEF UNICODE}'ImmGetDescriptionW'{$ELSE}'ImmGetDescriptionA'{$ENDIF};
    
    function ImmGetIMEFileNameA(hKl: HKL; PAnsiChar: PAnsiChar; uBufLen: UINT): UINT; stdcall; external imm32;
    function ImmGetIMEFileNameW(hKl: HKL; PWideChar: PWideChar; uBufLen: UINT): UINT; stdcall; external imm32;
    function ImmGetIMEFileName(hKl: HKL; PChar: PChar; uBufLen: UINT): UINT; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmGetIMEFileNameW'{$ELSE}'ImmGetIMEFileNameA'{$ENDIF};
    
    function ImmGetProperty(hKl: HKL; dWord: DWORD): DWORD; stdcall; external imm32;
    
    function ImmIsIME(hKl: HKL): Boolean; stdcall; external imm32;
    
    function ImmSimulateHotKey(hWnd: HWND; dWord: DWORD): Boolean; stdcall; external imm32;
    
    function ImmCreateContext: HIMC; stdcall; external imm32;
    function ImmDestroyContext(hImc: HIMC): Boolean; stdcall; external imm32;
    function ImmGetContext(hWnd: HWND): HIMC; stdcall; external imm32;
    function ImmReleaseContext(hWnd: HWND; hImc: HIMC): Boolean; stdcall; external imm32;
    function ImmAssociateContext(hWnd: HWND; hImc: HIMC): HIMC; stdcall; external imm32;
    
    function ImmAssociateContextEx(hWnd: HWND; hImc: HIMC; dw: DWORD): HIMC; stdcall; external imm32;
    
    function ImmGetCompositionStringA(hImc: HIMC; dWord1: DWORD; lpBuf: pointer; dwBufLen: DWORD): Longint; stdcall; external imm32;
    function ImmGetCompositionStringW(hImc: HIMC; dWord1: DWORD; lpBuf: pointer; dwBufLen: DWORD): Longint; stdcall; external imm32;
    function ImmGetCompositionString(hImc: HIMC; dWord1: DWORD; lpBuf: pointer; dwBufLen: DWORD): Longint; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmGetCompositionStringW'{$ELSE}'ImmGetCompositionStringA'{$ENDIF};
    
    function ImmSetCompositionStringA(hImc: HIMC; dwIndex: DWORD; lpComp: Pointer;
      dwCompLen: DWORD; lpRead: Pointer; dwReadLen: DWORD): Boolean; stdcall; external imm32;
    function ImmSetCompositionStringW(hImc: HIMC; dwIndex: DWORD; lpComp: Pointer;
      dwCompLen: DWORD; lpRead: Pointer; dwReadLen: DWORD): Boolean; stdcall; external imm32;
    function ImmSetCompositionString(hImc: HIMC; dwIndex: DWORD; lpComp: Pointer;
      dwCompLen: DWORD; lpRead: Pointer; dwReadLen: DWORD): Boolean; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmSetCompositionStringW'{$ELSE}'ImmSetCompositionStringA'{$ENDIF};
    
    function ImmGetCandidateListCountA(hImc: HIMC; var ListCount: DWORD): DWORD; stdcall; external imm32;
    function ImmGetCandidateListCountW(hImc: HIMC; var ListCount: DWORD): DWORD; stdcall; external imm32;
    function ImmGetCandidateListCount(hImc: HIMC; var ListCount: DWORD): DWORD; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmGetCandidateListCountW'{$ELSE}'ImmGetCandidateListCountA'{$ENDIF};
    
    function ImmGetCandidateListA(hImc: HIMC; deIndex: DWORD; lpCandidateList: PCandidateList; dwBufLen: DWORD): DWORD; stdcall; external imm32;
    function ImmGetCandidateListW(hImc: HIMC; deIndex: DWORD; lpCandidateList: PCandidateList; dwBufLen: DWORD): DWORD; stdcall; external imm32;
    function ImmGetCandidateList(hImc: HIMC; deIndex: DWORD; lpCandidateList: PCandidateList; dwBufLen: DWORD): DWORD; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmGetCandidateListW'{$ELSE}'ImmGetCandidateListA'{$ENDIF};
    
    function ImmGetGuideLineA(hImc: HIMC; dwIndex: DWORD; lpBuf: PAnsiChar; dwBufLen: DWORD): DWORD; stdcall; external imm32;
    function ImmGetGuideLineW(hImc: HIMC; dwIndex: DWORD; lpBuf: PWideChar; dwBufLen: DWORD): DWORD; stdcall; external imm32;
    function ImmGetGuideLine(hImc: HIMC; dwIndex: DWORD; lpBuf: PChar; dwBufLen: DWORD): DWORD; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmGetGuideLineW'{$ELSE}'ImmGetGuideLineA'{$ENDIF};
    
    function ImmGetConversionStatus(hImc: HIMC; var Conversion, Sentence: DWORD): Boolean; stdcall; external imm32;
    function ImmSetConversionStatus(hImc: HIMC; Conversion, Sentence: DWORD): Boolean; stdcall; external imm32;
    function ImmGetOpenStatus(hImc: HIMC): Boolean; stdcall; external imm32;
    function ImmSetOpenStatus(hImc: HIMC; fOpen: Boolean): Boolean; stdcall; external imm32;
    
    function ImmGetCompositionFontA(hImc: HIMC; lpLogfont: PLogFontA): Boolean; stdcall; external imm32;
    function ImmGetCompositionFontW(hImc: HIMC; lpLogfont: PLogFontW): Boolean; stdcall; external imm32;
    function ImmGetCompositionFont(hImc: HIMC; lpLogfont: PLogFont): Boolean; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmGetCompositionFontW'{$ELSE}'ImmGetCompositionFontA'{$ENDIF};
    
    function ImmSetCompositionFontA(hImc: HIMC; lpLogfont: PLogFontA): Boolean; stdcall; external imm32;
    function ImmSetCompositionFontW(hImc: HIMC; lpLogfont: PLogFontW): Boolean; stdcall; external imm32;
    function ImmSetCompositionFont(hImc: HIMC; lpLogfont: PLogFont): Boolean; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmSetCompositionFontW'{$ELSE}'ImmSetCompositionFontA'{$ENDIF};
    
    function ImmConfigureIMEA(hKl: HKL; hWnd: HWND; dwMode: DWORD; lpData: Pointer): Boolean; stdcall; external imm32;
    function ImmConfigureIMEW(hKl: HKL; hWnd: HWND; dwMode: DWORD; lpData: Pointer): Boolean; stdcall; external imm32;
    function ImmConfigureIME(hKl: HKL; hWnd: HWND; dwMode: DWORD; lpData: Pointer): Boolean; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmConfigureIMEW'{$ELSE}'ImmConfigureIMEA'{$ENDIF};
    
    function ImmEscapeA(hKl: HKL; hImc: HIMC; uEscape: UINT; lpData: Pointer): LRESULT; stdcall; external imm32;
    function ImmEscapeW(hKl: HKL; hImc: HIMC; uEscape: UINT; lpData: Pointer): LRESULT; stdcall; external imm32;
    function ImmEscape(hKl: HKL; hImc: HIMC; uEscape: UINT; lpData: Pointer): LRESULT; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmEscapeW'{$ELSE}'ImmEscapeA'{$ENDIF};
    
    function ImmGetConversionListA(hKl: HKL; hImc: HIMC; lpSrc: PAnsiChar; lpDst: PCandidateList;
      dwBufLen: DWORD; uFlag: UINT): DWORD; stdcall; external imm32;
    function ImmGetConversionListW(hKl: HKL; hImc: HIMC; lpSrc: PWideChar; lpDst: PCandidateList;
      dwBufLen: DWORD; uFlag: UINT): DWORD; stdcall; external imm32;
    function ImmGetConversionList(hKl: HKL; hImc: HIMC; lpSrc: PChar; lpDst: PCandidateList;
      dwBufLen: DWORD; uFlag: UINT): DWORD; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmGetConversionListW'{$ELSE}'ImmGetConversionListA'{$ENDIF};
    
    function ImmNotifyIME(hImc: HIMC; dwAction, dwIndex, dwValue: DWORD): Boolean; stdcall; external imm32;
    
    function ImmGetStatusWindowPos(hImc: HIMC; var lpPoint: TPoint): Boolean; stdcall; external imm32;
    function ImmSetStatusWindowPos(hImc: HIMC; lpPoint: PPoint): Boolean; stdcall; external imm32;
    function ImmGetCompositionWindow(hImc: HIMC; lpCompForm: PCompositionForm): Boolean; stdcall; external imm32;
    function ImmSetCompositionWindow(hImc: HIMC; lpCompForm: PCompositionForm): Boolean; stdcall; external imm32;
    function ImmGetCandidateWindow(hImc: HIMC; dwBufLen: DWORD; lpCandidate: PCandidateForm): Boolean; stdcall; external imm32;
    function ImmSetCandidateWindow(hImc: HIMC; lpCandidate: PCandidateForm): Boolean; stdcall; external imm32;
    
    function ImmIsUIMessageA(hWnd: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM): Boolean; stdcall; external imm32;
    function ImmIsUIMessageW(hWnd: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM): Boolean; stdcall; external imm32;
    function ImmIsUIMessage(hWnd: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM): Boolean; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmIsUIMessageW'{$ELSE}'ImmIsUIMessageA'{$ENDIF};
    
    function ImmGetVirtualKey(hWnd: HWND): UINT; stdcall; external imm32;
    
    type
      RegisterWordEnumProcA = function(lpReading: PAnsiChar; dwStyle: DWORD; lpszString: PAnsiChar; lpData: Pointer): Integer;
      RegisterWordEnumProcW = function(lpReading: PWideChar; dwStyle: DWORD; lpszString: PWideChar; lpData: Pointer): Integer;
      {$IFDEF UNICODE}
      RegisterWordEnumProc = RegisterWordEnumProcW;
      {$ELSE}
      RegisterWordEnumProc = RegisterWordEnumProcA;
      {$ENDIF}
    
    function ImmRegisterWordA(hKl: HKL; lpszReading: PAnsiChar; dwStyle: DWORD; lpszRegister: PAnsiChar): Boolean; stdcall; external imm32;
    function ImmRegisterWordW(hKl: HKL; lpszReading: PWideChar; dwStyle: DWORD; lpszRegister: PWideChar): Boolean; stdcall; external imm32;
    function ImmRegisterWord(hKl: HKL; lpszReading: PChar; dwStyle: DWORD; lpszRegister: PChar): Boolean; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmRegisterWordW'{$ELSE}'ImmRegisterWordA'{$ENDIF};
    
    function ImmUnregisterWordA(hKl: HKL; lpszReading: PAnsiChar; dwStyle: DWORD; lpszUnregister: PAnsiChar): Boolean; stdcall; external imm32;
    function ImmUnregisterWordW(hKl: HKL; lpszReading: PWideChar; dwStyle: DWORD; lpszUnregister: PWideChar): Boolean; stdcall; external imm32;
    function ImmUnregisterWord(hKl: HKL; lpszReading: PChar; dwStyle: DWORD; lpszUnregister: PChar): Boolean; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmUnregisterWordW'{$ELSE}'ImmUnregisterWordA'{$ENDIF};
    
    function ImmGetRegisterWordStyleA(hKl: HKL; nItem: UINT; lpStyleBuf: PStyleBufA): UINT; stdcall; external imm32;
    function ImmGetRegisterWordStyleW(hKl: HKL; nItem: UINT; lpStyleBuf: PStyleBufW): UINT; stdcall; external imm32;
    function ImmGetRegisterWordStyle(hKl: HKL; nItem: UINT; lpStyleBuf: PStyleBuf): UINT; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmGetRegisterWordStyleW'{$ELSE}'ImmGetRegisterWordStyleA'{$ENDIF};
    
    function ImmEnumRegisterWordA(hKl: HKL; lpfnEnumProc: RegisterWordEnumProcA;
      lpszReading: PAnsiChar; dwStyle: DWORD; lpszRegister: PAnsiChar; lpData: Pointer): UINT; stdcall; external imm32;
    function ImmEnumRegisterWordW(hKl: HKL; lpfnEnumProc: RegisterWordEnumProcW;
     lpszReading: PWideChar; dwStyle: DWORD; lpszRegister: PWideChar; lpData: Pointer): UINT; stdcall; external imm32;
    function ImmEnumRegisterWord(hKl: HKL; lpfnEnumProc: RegisterWordEnumProc;
      lpszReading: PChar; dwStyle: DWORD; lpszRegister: PChar; lpData: Pointer): UINT; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmEnumRegisterWordW'{$ELSE}'ImmEnumRegisterWordA'{$ENDIF};
    
    function ImmDisableIME(dw: DWORD): BOOL; stdcall; external imm32;
    function ImmEnumInputContext(idThread: DWORD; lpfn: IMCEnumProc; lParam: LPARAM): BOOL; stdcall; external imm32;
    
    function ImmGetImeMenuItemsA(hImc: HIMC; dwFlags: DWORD; dwType: DWORD; out lpImeParentMenu: TIMEMenuItemInfoA;
      out lpImeMenu: TIMEMenuItemInfoA; dwSize: DWORD): BOOL; stdcall; external imm32;
    function ImmGetImeMenuItemsW(hImc: HIMC; dwFlags: DWORD; dwType: DWORD; out lpImeParentMenu: TIMEMenuItemInfoW;
      out lpImeMenu: TIMEMenuItemInfoW; dwSize: DWORD): BOOL; stdcall; external imm32;
    function ImmGetImeMenuItems(hImc: HIMC; dwFlags: DWORD; dwType: DWORD; out lpImeParentMenu: TIMEMenuItemInfo;
      out lpImeMenu: TIMEMenuItemInfo; dwSize: DWORD): BOOL; stdcall; external imm32
      name {$IFDEF UNICODE}'ImmGetImeMenuItemsW'{$ELSE}'ImmGetImeMenuItemsA'{$ENDIF};
    
    
    const          
      // wParam for WM_IME_CONTROL
      IMC_GETCANDIDATEPOS             = $0007;
      IMC_SETCANDIDATEPOS             = $0008;
      IMC_GETCOMPOSITIONFONT          = $0009;
      IMC_SETCOMPOSITIONFONT          = $000A;
      IMC_GETCOMPOSITIONWINDOW        = $000B;
      IMC_SETCOMPOSITIONWINDOW        = $000C;
      IMC_GETSTATUSWINDOWPOS          = $000F;
      IMC_SETSTATUSWINDOWPOS          = $0010;
      IMC_CLOSESTATUSWINDOW           = $0021;
      IMC_OPENSTATUSWINDOW            = $0022;
    
    
      // dwAction for ImmNotifyIME
      NI_OPENCANDIDATE                = $0010;
      NI_CLOSECANDIDATE               = $0011;
      NI_SELECTCANDIDATESTR           = $0012;
      NI_CHANGECANDIDATELIST          = $0013;
      NI_FINALIZECONVERSIONRESULT     = $0014;
      NI_COMPOSITIONSTR               = $0015;
      NI_SETCANDIDATE_PAGESTART       = $0016;
      NI_SETCANDIDATE_PAGESIZE        = $0017;
      NI_IMEMENUSELECTED              = $0018;
    
      // lParam for WM_IME_SETCONTEXT
      ISC_SHOWUICANDIDATEWINDOW       = $00000001;
      ISC_SHOWUICOMPOSITIONWINDOW     = $80000000;
      ISC_SHOWUIGUIDELINE             = $40000000;
      ISC_SHOWUIALLCANDIDATEWINDOW    = $0000000F;
      ISC_SHOWUIALL                   = $C000000F;
    
    
      // dwIndex for ImmNotifyIME/NI_COMPOSITIONSTR
      CPS_COMPLETE                    = $0001;
      CPS_CONVERT                     = $0002;
      CPS_REVERT                      = $0003;
      CPS_CANCEL                      = $0004;
    
      // the modifiers of hot key
      MOD_ALT                         = $0001;
      MOD_CONTROL                     = $0002;
      MOD_SHIFT                       = $0004;
    
      MOD_LEFT                        = $8000;
      MOD_RIGHT                       = $4000;
    
      MOD_ON_KEYUP                    = $0800;
      MOD_IGNORE_ALL_MODIFIER         = $0400;
    
      // Windows for Simplified Chinese Edition hot key ID from 0x10 - 0x2F
      IME_CHOTKEY_IME_NONIME_TOGGLE           = $10;
      IME_CHOTKEY_SHAPE_TOGGLE                = $11;
      IME_CHOTKEY_SYMBOL_TOGGLE               = $12;
    
      // Windows for Japanese Edition hot key ID from 0x30 - 0x4F
      IME_JHOTKEY_CLOSE_OPEN                  = $30;
    
      // Windows for Korean Edition hot key ID from 0x50 - 0x6F
      IME_KHOTKEY_SHAPE_TOGGLE                = $50;
      IME_KHOTKEY_HANJACONVERT                = $51;
      IME_KHOTKEY_ENGLISH                     = $52;
    
      // Windows for Traditional Chinese Edition hot key ID from 0x70 - 0x8F
      IME_THOTKEY_IME_NONIME_TOGGLE           = $70;
      IME_THOTKEY_SHAPE_TOGGLE                = $71;
      IME_THOTKEY_SYMBOL_TOGGLE               = $72;
    
      // direct switch hot key ID from 0x100 - 0x11F
      IME_HOTKEY_DSWITCH_FIRST                = $100;
      IME_HOTKEY_DSWITCH_LAST                 = $11F;
    
      // IME private hot key from 0x200 - 0x21F
      IME_HOTKEY_PRIVATE_FIRST                = $200;
      IME_ITHOTKEY_RESEND_RESULTSTR           = $200;
      IME_ITHOTKEY_PREVIOUS_COMPOSITION       = $201;
      IME_ITHOTKEY_UISTYLE_TOGGLE             = $202;
      IME_ITHOTKEY_RECONVERTSTRING            = $203;
      IME_HOTKEY_PRIVATE_LAST                 = $21F;
    
    
      // parameter of ImmGetCompositionString
      GCS_COMPREADSTR                 = $0001;
      GCS_COMPREADATTR                = $0002;
      GCS_COMPREADCLAUSE              = $0004;
      GCS_COMPSTR                     = $0008;
      GCS_COMPATTR                    = $0010;
      GCS_COMPCLAUSE                  = $0020;
      GCS_CURSORPOS                   = $0080;
      GCS_DELTASTART                  = $0100;
      GCS_RESULTREADSTR               = $0200;
      GCS_RESULTREADCLAUSE            = $0400;
      GCS_RESULTSTR                   = $0800;
      GCS_RESULTCLAUSE                = $1000;
    
      // style bit flags for WM_IME_COMPOSITION
      CS_INSERTCHAR                   = $2000;
      CS_NOMOVECARET                  = $4000;
    
      // IME version constants
      IMEVER_0310                     = $0003000A;
      IMEVER_0400                     = $00040000;
    
    
      // IME property bits
      IME_PROP_AT_CARET               = $00010000;
      IME_PROP_SPECIAL_UI             = $00020000;
      IME_PROP_CANDLIST_START_FROM_1  = $00040000;
      IME_PROP_UNICODE                = $00080000;
      IME_PROP_COMPLETE_ON_UNSELECT   = $00100000;
    
    
      // IME UICapability bits
      UI_CAP_2700                     = $00000001;
      UI_CAP_ROT90                    = $00000002;
      UI_CAP_ROTANY                   = $00000004;
    
      // ImmSetCompositionString Capability bits
      SCS_CAP_COMPSTR                 = $00000001;
      SCS_CAP_MAKEREAD                = $00000002;
      SCS_CAP_SETRECONVERTSTRING      = $00000004;
    
    
      // IME WM_IME_SELECT inheritance Capability bits
      SELECT_CAP_CONVERSION           = $00000001;
      SELECT_CAP_SENTENCE             = $00000002;
    
    
      // ID for deIndex of ImmGetGuideLine
      GGL_LEVEL                       = $00000001;
      GGL_INDEX                       = $00000002;
      GGL_STRING                      = $00000003;
      GGL_PRIVATE                     = $00000004;
    
    
      // ID for dwLevel of GUIDELINE Structure
      GL_LEVEL_NOGUIDELINE            = $00000000;
      GL_LEVEL_FATAL                  = $00000001;
      GL_LEVEL_ERROR                  = $00000002;
      GL_LEVEL_WARNING                = $00000003;
      GL_LEVEL_INFORMATION            = $00000004;
    
    
      // ID for dwIndex of GUIDELINE Structure
      GL_ID_UNKNOWN                   = $00000000;
      GL_ID_NOMODULE                  = $00000001;
      GL_ID_NODICTIONARY              = $00000010;
      GL_ID_CANNOTSAVE                = $00000011;
      GL_ID_NOCONVERT                 = $00000020;
      GL_ID_TYPINGERROR               = $00000021;
      GL_ID_TOOMANYSTROKE             = $00000022;
      GL_ID_READINGCONFLICT           = $00000023;
      GL_ID_INPUTREADING              = $00000024;
      GL_ID_INPUTRADICAL              = $00000025;
      GL_ID_INPUTCODE                 = $00000026;
      GL_ID_INPUTSYMBOL               = $00000027;
      GL_ID_CHOOSECANDIDATE           = $00000028;
      GL_ID_REVERSECONVERSION         = $00000029;
      GL_ID_PRIVATE_FIRST             = $00008000;
      GL_ID_PRIVATE_LAST              = $0000FFFF;
    
    
      // ID for dwIndex of ImmGetProperty
      IGP_GETIMEVERSION               = DWORD(-4);
      IGP_PROPERTY                    = $00000004;
      IGP_CONVERSION                  = $00000008;
      IGP_SENTENCE                    = $0000000c;
      IGP_UI                          = $00000010;
      IGP_SETCOMPSTR                  = $00000014;
      IGP_SELECT                      = $00000018;
    
      // dwIndex for ImmSetCompositionString API
      SCS_SETSTR                      = (GCS_COMPREADSTR or GCS_COMPSTR);
      SCS_CHANGEATTR                  = (GCS_COMPREADATTR or GCS_COMPATTR);
      SCS_CHANGECLAUSE                = (GCS_COMPREADCLAUSE or GCS_COMPCLAUSE);
      SCS_SETRECONVERTSTRING          = $00010000;
      SCS_QUERYRECONVERTSTRING        = $00020000;
    
      // attribute for COMPOSITIONSTRING Structure
      ATTR_INPUT                      = $00;
      ATTR_TARGET_CONVERTED           = $01;
      ATTR_CONVERTED                  = $02;
      ATTR_TARGET_NOTCONVERTED        = $03;
      ATTR_INPUT_ERROR                = $04;
      ATTR_FIXEDCONVERTED             = $05;
    
      // bit field for IMC_SETCOMPOSITIONWINDOW, IMC_SETCANDIDATEWINDOW
      CFS_DEFAULT                     = $0000;
      CFS_RECT                        = $0001;
      CFS_POINT                       = $0002;
      CFS_FORCE_POSITION              = $0020;
      CFS_CANDIDATEPOS                = $0040;
      CFS_EXCLUDE                     = $0080;
    
      // conversion direction for ImmGetConversionList
      GCL_CONVERSION                  = $0001;
      GCL_REVERSECONVERSION           = $0002;
      GCL_REVERSE_LENGTH              = $0003;
    
      // bit field for conversion mode
      IME_CMODE_ALPHANUMERIC          = $0000;
      IME_CMODE_NATIVE                = $0001;
      IME_CMODE_CHINESE               = IME_CMODE_NATIVE;
      // IME_CMODE_HANGEUL is old name of IME_CMODE_HANGUL. It will be gone eventually.
      IME_CMODE_HANGEUL               = IME_CMODE_NATIVE;
      IME_CMODE_HANGUL                = IME_CMODE_NATIVE;
      IME_CMODE_JAPANESE              = IME_CMODE_NATIVE;
      IME_CMODE_KATAKANA              = $0002;  // only effect under IME_CMODE_NATIVE
      IME_CMODE_LANGUAGE              = $0003;
      IME_CMODE_FULLSHAPE             = $0008;
      IME_CMODE_ROMAN                 = $0010;
      IME_CMODE_CHARCODE              = $0020;
      IME_CMODE_HANJACONVERT          = $0040;
      IME_CMODE_SOFTKBD               = $0080;
      IME_CMODE_NOCONVERSION          = $0100;
      IME_CMODE_EUDC                  = $0200;
      IME_CMODE_SYMBOL                = $0400;
      IME_CMODE_FIXED                 = $0800;
    
      // bit field for sentence mode
      IME_SMODE_NONE                  = $0000;
      IME_SMODE_PLAURALCLAUSE         = $0001;
      IME_SMODE_SINGLECONVERT         = $0002;
      IME_SMODE_AUTOMATIC             = $0004;
      IME_SMODE_PHRASEPREDICT         = $0008;
      IME_SMODE_CONVERSATION          = $0010;
    
      // style of candidate
      IME_CAND_UNKNOWN                = $0000;
      IME_CAND_READ                   = $0001;
      IME_CAND_CODE                   = $0002;
      IME_CAND_MEANING                = $0003;
      IME_CAND_RADICAL                = $0004;
      IME_CAND_STROKE                 = $0005;
    
      // wParam of report message WM_IME_NOTIFY
      IMN_CLOSESTATUSWINDOW           = $0001;
      IMN_OPENSTATUSWINDOW            = $0002;
      IMN_CHANGECANDIDATE             = $0003;
      IMN_CLOSECANDIDATE              = $0004;
      IMN_OPENCANDIDATE               = $0005;
      IMN_SETCONVERSIONMODE           = $0006;
      IMN_SETSENTENCEMODE             = $0007;
      IMN_SETOPENSTATUS               = $0008;
      IMN_SETCANDIDATEPOS             = $0009;
      IMN_SETCOMPOSITIONFONT          = $000A;
      IMN_SETCOMPOSITIONWINDOW        = $000B;
      IMN_SETSTATUSWINDOWPOS          = $000C;
      IMN_GUIDELINE                   = $000D;
      IMN_PRIVATE                     = $000E;
    
      // wParam of report message WM_IME_REQUEST
      IMR_COMPOSITIONWINDOW           = $0001;
      IMR_CANDIDATEWINDOW             = $0002;
      IMR_COMPOSITIONFONT             = $0003;
      IMR_RECONVERTSTRING             = $0004;
      IMR_CONFIRMRECONVERTSTRING      = $0005;
      IMR_QUERYCHARPOSITION           = $0006;
      IMR_DOCUMENTFEED                = $0007;
    
      // error code of ImmGetCompositionString
      IMM_ERROR_NODATA                = (-1);
      IMM_ERROR_GENERAL               = (-2);
    
    
      // dialog mode of ImmConfigureIME
      IME_CONFIG_GENERAL              = 1;
      IME_CONFIG_REGISTERWORD         = 2;
      IME_CONFIG_SELECTDICTIONARY     = 3;
    
    
      // flags for ImmEscape
      IME_ESC_QUERY_SUPPORT           = $0003;
      IME_ESC_RESERVED_FIRST          = $0004;
      IME_ESC_RESERVED_LAST           = $07FF;
      IME_ESC_PRIVATE_FIRST           = $0800;
      IME_ESC_PRIVATE_LAST            = $0FFF;
    
      IME_ESC_SEQUENCE_TO_INTERNAL    = $1001;
      IME_ESC_GET_EUDC_DICTIONARY     = $1003;
      IME_ESC_SET_EUDC_DICTIONARY     = $1004;
      IME_ESC_MAX_KEY                 = $1005;
      IME_ESC_IME_NAME                = $1006;
      IME_ESC_SYNC_HOTKEY             = $1007;
      IME_ESC_HANJA_MODE              = $1008;
      IME_ESC_AUTOMATA                = $1009;
      IME_ESC_PRIVATE_HOTKEY          = $100a;
      IME_ESC_GETHELPFILENAME         = $100b;
      // style of word registration
      IME_REGWORD_STYLE_EUDC          = $00000001;
      IME_REGWORD_STYLE_USER_FIRST    = $80000000;
      IME_REGWORD_STYLE_USER_LAST     = $FFFFFFFF;
    
    
      // dwFlags for ImmAssociateContextEx
      IACE_CHILDREN                   = $0001;
      IACE_DEFAULT                    = $0010;
      IACE_IGNORENOCONTEXT            = $0020;
    
      // dwFlags for ImmGetImeMenuItems
      IGIMIF_RIGHTMENU                = $0001;
    
      // dwType for ImmGetImeMenuItems
      IGIMII_CMODE                    = $0001;
      IGIMII_SMODE                    = $0002;
      IGIMII_CONFIGURE                = $0004;
      IGIMII_TOOLS                    = $0008;
      IGIMII_HELP                     = $0010;
      IGIMII_OTHER                    = $0020;
      IGIMII_INPUTTOOLS               = $0040;
    
      // fType of IMEMENUITEMINFO structure
      IMFT_RADIOCHECK = $00001;
      IMFT_SEPARATOR  = $00002;
      IMFT_SUBMENU    = $00004;
    
      // fState of IMEMENUITEMINFO structure
      IMFS_GRAYED          = MFS_GRAYED;
      IMFS_DISABLED        = MFS_DISABLED;
      IMFS_CHECKED         = MFS_CHECKED;
      IMFS_HILITE          = MFS_HILITE;
      IMFS_ENABLED         = MFS_ENABLED;
      IMFS_UNCHECKED       = MFS_UNCHECKED;
      IMFS_UNHILITE        = MFS_UNHILITE;
      IMFS_DEFAULT         = MFS_DEFAULT;
    
      // type of soft keyboard
      // for Windows Tranditional Chinese Edition
      SOFTKEYBOARD_TYPE_T1            = $0001;
      // for Windows Simplified Chinese Edition
      SOFTKEYBOARD_TYPE_C1            = $0002;
    
    implementation
    
    end.
    
    imm.pp (29,961 bytes)
  • synedit_pp_18762.patch (2,044 bytes)
    Index: synedit.pp
    ===================================================================
    --- synedit.pp	(revision 18763)
    +++ synedit.pp	(working copy)
    @@ -65,6 +65,10 @@
       {$IFDEF USE_UTF8BIDI_LCL}
       FreeBIDI, utf8bidi,
       {$ENDIF}
    +{ #FIX-JP ADD >>}
    +  Imm,
    +{ << FIX-JP }
    +
       Types, FPCAdds, LCLIntf, LCLType, LMessages, LCLProc,
     {$ELSE}
       Windows,
    @@ -296,10 +300,15 @@
         procedure WMEraseBkgnd(var Msg: TMessage); message WM_ERASEBKGND;
         procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message WM_GETDLGCODE;
         procedure WMHScroll(var Msg: {$IFDEF SYN_LAZARUS}TLMScroll{$ELSE}TWMScroll{$ENDIF}); message WM_HSCROLL;
    -{$IFDEF SYN_MBCSSUPPORT}
    +
    +{ #FIX-JP ADD >>}
    +    fImeCount: Integer;
    +{ << FIX-JP }
    +
    +//{$IFDEF SYN_MBCSSUPPORT}
         procedure WMImeComposition(var Msg: TMessage); message WM_IME_COMPOSITION;
         procedure WMImeNotify(var Msg: TMessage); message WM_IME_NOTIFY;
    -{$ENDIF}
    +//{$ENDIF}
         procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
         {$IFDEF SYN_LAZARUS}
         procedure WMExit(var Message: TLMExit); message LM_EXIT;
    @@ -1894,7 +1903,7 @@
       end;
     end;
     
    -{$IFDEF SYN_MBCSSUPPORT}
    +//{$IFDEF SYN_MBCSSUPPORT}
     procedure TCustomSynEdit.WMImeComposition(var Msg: TMessage);
     var
       imc: HIMC;
    @@ -1940,8 +1949,9 @@
       end;
       inherited;
     end;
    -{$ENDIF}
    +//{$ENDIF}
     
    +
     procedure TCustomSynEdit.IncPaintLock;
     begin
       inc(fPaintLock);
    @@ -3851,9 +3861,9 @@
     procedure TCustomSynEdit.UpdateCaret;
     var
       CX, CY: Integer;
    -{$IFDEF SYN_MBCSSUPPORT}
    +//{$IFDEF SYN_MBCSSUPPORT}
       cf: TCompositionForm;
    -{$ENDIF}
    +//{$ENDIF}
     begin
       if (PaintLock <> 0)
       {$IFDEF SYN_LAZARUS}
    @@ -3884,13 +3894,13 @@
           HideCaret;
           SetCaretPosEx(Handle ,CX + FCaretOffset.X, CY + FCaretOffset.Y);
         end;
    -{$IFDEF SYN_MBCSSUPPORT}
    +//{$IFDEF SYN_MBCSSUPPORT}
         if HandleAllocated then begin
           cf.dwStyle := CFS_POINT;
           cf.ptCurrentPos := Point(CX, CY);
           ImmSetCompositionWindow(ImmGetContext(Handle), @cf);
         end;
    -{$ENDIF}
    +//{$ENDIF}
       end;
     end;
     
    
    synedit_pp_18762.patch (2,044 bytes)

Relationships

related to 0011819 closedMartin Friebe SynEdit overlaps double width characters 
related to 0021450 closedMartin Friebe WM_IME_* (e.g WM_IME_NOTIFY) are not delivered to components 

Activities

Dmitry Boyarintsev

2009-02-09 14:53

developer   ~0025225

Saeka, what does actually happen?
Are there any rubbish-chars appearing at the SynEdit?

do have any information on Eastern languages support for other OSes, like Linux or Mac OS X.

Saeka-jp

2009-02-09 15:16

reporter   ~0025226

Thanks, Could you see snapshot fixjp.pdf 0011819 FixJp09261.zip?

Under Windows, input character is correct, but IME input editor show at incorrect position and incorrect font size.

About other OS(Linux,BSD) information.
http://en.wikipedia.org/wiki/Immodule
http://www.scim-im.org/projects

It seems to be happen in Mac OS X too, but I don't have any information for now.

2009-02-11 10:17

 

imm.pp (29,961 bytes)
{
    This file is part of the Free Pascal run time library.
    Copyright (c) 2005 by the Free Pascal development team
    Header translation by Alexey Barkovoy for Free Pascal Platform

    Input Method Manager definitions

    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 **********************************************************************}


(**********************************************************************)
(*      imm.h - Input Method Manager definitions                      *)
(*                                                                    *)
(*      Copyright (c) Microsoft Corporation. All rights reserved.     *)
(**********************************************************************)

{$mode objfpc}

unit Imm;

interface

uses
  Windows;

type
  HIMC  = THandle;
  HIMCC = THandle;

  LPHKL  = ^HKL;
  LPUINT = ^LongWord;

  tagCOMPOSITIONFORM = record
    dwStyle: DWORD;
    ptCurrentPos: TPoint;
    rcArea:  TRect;
  end;
  COMPOSITIONFORM = tagCOMPOSITIONFORM;
  TCompositionForm = tagCOMPOSITIONFORM;
  PCompositionForm = ^TCompositionForm;

  tagCANDIDATEFORM = record
    dwIndex: DWORD;
    dwStyle: DWORD;
    ptCurrentPos: TPoint;
    rcArea: TRect;
  end;
  CANDIDATEFORM = tagCANDIDATEFORM;
  TCandidateForm = tagCANDIDATEFORM;
  PCandidateForm = ^TCandidateForm;

  tagCANDIDATELIST = record
    dwSize: DWORD;
    dwStyle: DWORD;
    dwCount: DWORD;
    dwSelection: DWORD;
    dwPageStart: DWORD;
    dwPageSize: DWORD;
    dwOffset: array[0..0] of DWORD;
  end;
  CANDIDATELIST = tagCANDIDATELIST;
  TCandidateList = tagCANDIDATELIST;
  PCandidateList = ^TCandidateList;

  tagREGISTERWORDA = record
    lpReading: PAnsiChar;
    lpWord: PAnsiChar;
  end;
  REGISTERWORDA = tagREGISTERWORDA;
  TRegisterWordA = tagREGISTERWORDA;
  PRegisterWordA = ^TRegisterWordA;

  tagREGISTERWORDW = record
    lpReading: PWideChar;
    lpWord: PWideChar;
  end;
  REGISTERWORDW = tagREGISTERWORDW;
  TRegisterWordW = tagREGISTERWORDW;
  PRegisterWordW = ^TRegisterWordW;

  {$IFDEF UNICODE}
  REGISTERWORD = REGISTERWORDW;
  TRegisterWord = TRegisterWordW;
  PRegisterWord = PRegisterWordW;
  {$ELSE}
  REGISTERWORD = REGISTERWORDA;
  TRegisterWord = TRegisterWordA;
  PRegisterWord = PRegisterWordA;
  {$ENDIF}

  tagRECONVERTSTRING = record
    dwSize: DWORD;
    dwVersion: DWORD;
    dwStrLen: DWORD;
    dwStrOffset: DWORD;
    dwCompStrLen: DWORD;
    dwCompStrOffset: DWORD;
    dwTargetStrLen: DWORD;
    dwTargetStrOffset: DWORD;
  end;
  RECONVERTSTRING = tagRECONVERTSTRING;
  TReconvertString = tagRECONVERTSTRING;
  PReconvertString = ^TReconvertString;

const
  STYLE_DESCRIPTION_SIZE = 32;

type
  tagSTYLEBUFA = record
    dwStyle: DWORD;
    szDescription: array [0..STYLE_DESCRIPTION_SIZE-1] of AnsiChar;
  end;
  STYLEBUFA = tagSTYLEBUFA;
  TStyleBufA = tagSTYLEBUFA;
  PStyleBufA = ^TStyleBufA;

  tagSTYLEBUFW = record
    dwStyle: DWORD;
    szDescription: array [0..STYLE_DESCRIPTION_SIZE-1] of WideChar;
  end;
  STYLEBUFW = tagSTYLEBUFW;
  TStyleBufW = tagSTYLEBUFW;
  PStyleBufW = ^TStyleBufW;

  {$IFDEF UNICODE}
  STYLEBUF = STYLEBUFW;
  TStyleBuf = TStyleBufW;
  PStyleBuf = PStyleBufW;
  {$ELSE}
  STYLEBUF = STYLEBUFA;
  TStyleBuf = TStyleBufA;
  PStyleBuf = PStyleBufA;
  {$ENDIF}

const
  IMEMENUITEM_STRING_SIZE = 80;

type
  tagIMEMENUITEMINFOA = record
    cbSize: LongWord;
    fType: LongWord;
    fState: LongWord;
    wID: LongWord;
    hbmpChecked: HBITMAP;
    hbmpUnchecked: HBITMAP;
    dwItemData: DWORD;
    szString: array[0..IMEMENUITEM_STRING_SIZE-1] of AnsiChar;
    hbmpItem: HBITMAP;
  end;
  IMEMENUITEMINFOA = tagIMEMENUITEMINFOA;
  TIMEMenuItemInfoA = tagIMEMENUITEMINFOA;
  PIMEMenuItemInfoA = ^TIMEMenuItemInfoA;

  tagIMEMENUITEMINFOW = record
    cbSize: LongWord;
    fType: LongWord;
    fState: LongWord;
    wID: LongWord;
    hbmpChecked: HBITMAP;
    hbmpUnchecked: HBITMAP;
    dwItemData: DWORD;
    szString: array[0..IMEMENUITEM_STRING_SIZE-1] of WideChar;
    hbmpItem: HBITMAP;
  end;
  IMEMENUITEMINFOW = tagIMEMENUITEMINFOW;
  TIMEMenuItemInfoW = tagIMEMENUITEMINFOW;
  PIMEMenuItemInfoW = ^TIMEMenuItemInfoW;

  {$IFDEF UNICODE}
  IMEMENUITEMINFO = IMEMENUITEMINFOW;
  TIMEMenuItemInfo = TIMEMenuItemInfoW;
  PIMEMenuItemInfo = PIMEMenuItemInfoW;
  {$ELSE}
  IMEMENUITEMINFO = IMEMENUITEMINFOA;
  TIMEMenuItemInfo = TIMEMenuItemInfoA;
  PIMEMenuItemInfo = PIMEMenuItemInfoA;
  {$ENDIF}


  tagIMECHARPOSITION = record
    dwSize: DWORD;
    dwCharPos: DWORD;
    pt: TPoint;
    cLineHeight: LongWord;
    rcDocument: TRect;
  end;
  IMECHARPOSITION = tagIMECHARPOSITION;
  TIMECharPosition = tagIMECHARPOSITION;
  PIMECharPosition = ^TIMECharPosition;


  IMCEnumProc = function (h: HIMC; l: LPARAM): BOOL; stdcall;


{$IFDEF FPC}
type
  PLOGFONTA = PLOGFONT;
  PLOGFONTW = ^TLOGFONTW;

  tagLOGFONTW = packed record
    lfHeight: Longint;
    lfWidth: Longint;
    lfEscapement: Longint;
    lfOrientation: Longint;
    lfWeight: Longint;
    lfItalic: Byte;
    lfUnderline: Byte;
    lfStrikeOut: Byte;
    lfCharSet: Byte;
    lfOutPrecision: Byte;
    lfClipPrecision: Byte;
    lfQuality: Byte;
    lfPitchAndFamily: Byte;
    lfFaceName: array[0..LF_FACESIZE - 1] of WideChar;
  end;
  TLOGFONTW = tagLOGFONTW;

{$ENDIF}


// prototype of IMM API

const
  imm32 = 'imm32.dll';
  
function ImmInstallIMEA(lpszIMEFileName, lpszLayoutText: PAnsiChar): HKL; stdcall; external imm32;
function ImmInstallIMEW(lpszIMEFileName, lpszLayoutText: PWideChar): HKL; stdcall; external imm32;
function ImmInstallIME(lpszIMEFileName, lpszLayoutText: PChar): HKL; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmInstallIMEW'{$ELSE}'ImmInstallIMEA'{$ENDIF};

function ImmGetDefaultIMEWnd(hWnd: HWND): HWND; stdcall; external imm32;

function ImmGetDescriptionA(hKl: HKL; PAnsiChar: PAnsiChar; uBufLen: UINT): UINT; stdcall; external imm32;
function ImmGetDescriptionW(hKl: HKL; PWideChar: PWideChar; uBufLen: UINT): UINT; stdcall; external imm32;
function ImmGetDescription(hKl: HKL; PChar: PChar; uBufLen: UINT): UINT; stdcall; external imm32 name {$IFDEF UNICODE}'ImmGetDescriptionW'{$ELSE}'ImmGetDescriptionA'{$ENDIF};

function ImmGetIMEFileNameA(hKl: HKL; PAnsiChar: PAnsiChar; uBufLen: UINT): UINT; stdcall; external imm32;
function ImmGetIMEFileNameW(hKl: HKL; PWideChar: PWideChar; uBufLen: UINT): UINT; stdcall; external imm32;
function ImmGetIMEFileName(hKl: HKL; PChar: PChar; uBufLen: UINT): UINT; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmGetIMEFileNameW'{$ELSE}'ImmGetIMEFileNameA'{$ENDIF};

function ImmGetProperty(hKl: HKL; dWord: DWORD): DWORD; stdcall; external imm32;

function ImmIsIME(hKl: HKL): Boolean; stdcall; external imm32;

function ImmSimulateHotKey(hWnd: HWND; dWord: DWORD): Boolean; stdcall; external imm32;

function ImmCreateContext: HIMC; stdcall; external imm32;
function ImmDestroyContext(hImc: HIMC): Boolean; stdcall; external imm32;
function ImmGetContext(hWnd: HWND): HIMC; stdcall; external imm32;
function ImmReleaseContext(hWnd: HWND; hImc: HIMC): Boolean; stdcall; external imm32;
function ImmAssociateContext(hWnd: HWND; hImc: HIMC): HIMC; stdcall; external imm32;

function ImmAssociateContextEx(hWnd: HWND; hImc: HIMC; dw: DWORD): HIMC; stdcall; external imm32;

function ImmGetCompositionStringA(hImc: HIMC; dWord1: DWORD; lpBuf: pointer; dwBufLen: DWORD): Longint; stdcall; external imm32;
function ImmGetCompositionStringW(hImc: HIMC; dWord1: DWORD; lpBuf: pointer; dwBufLen: DWORD): Longint; stdcall; external imm32;
function ImmGetCompositionString(hImc: HIMC; dWord1: DWORD; lpBuf: pointer; dwBufLen: DWORD): Longint; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmGetCompositionStringW'{$ELSE}'ImmGetCompositionStringA'{$ENDIF};

function ImmSetCompositionStringA(hImc: HIMC; dwIndex: DWORD; lpComp: Pointer;
  dwCompLen: DWORD; lpRead: Pointer; dwReadLen: DWORD): Boolean; stdcall; external imm32;
function ImmSetCompositionStringW(hImc: HIMC; dwIndex: DWORD; lpComp: Pointer;
  dwCompLen: DWORD; lpRead: Pointer; dwReadLen: DWORD): Boolean; stdcall; external imm32;
function ImmSetCompositionString(hImc: HIMC; dwIndex: DWORD; lpComp: Pointer;
  dwCompLen: DWORD; lpRead: Pointer; dwReadLen: DWORD): Boolean; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmSetCompositionStringW'{$ELSE}'ImmSetCompositionStringA'{$ENDIF};

function ImmGetCandidateListCountA(hImc: HIMC; var ListCount: DWORD): DWORD; stdcall; external imm32;
function ImmGetCandidateListCountW(hImc: HIMC; var ListCount: DWORD): DWORD; stdcall; external imm32;
function ImmGetCandidateListCount(hImc: HIMC; var ListCount: DWORD): DWORD; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmGetCandidateListCountW'{$ELSE}'ImmGetCandidateListCountA'{$ENDIF};

function ImmGetCandidateListA(hImc: HIMC; deIndex: DWORD; lpCandidateList: PCandidateList; dwBufLen: DWORD): DWORD; stdcall; external imm32;
function ImmGetCandidateListW(hImc: HIMC; deIndex: DWORD; lpCandidateList: PCandidateList; dwBufLen: DWORD): DWORD; stdcall; external imm32;
function ImmGetCandidateList(hImc: HIMC; deIndex: DWORD; lpCandidateList: PCandidateList; dwBufLen: DWORD): DWORD; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmGetCandidateListW'{$ELSE}'ImmGetCandidateListA'{$ENDIF};

function ImmGetGuideLineA(hImc: HIMC; dwIndex: DWORD; lpBuf: PAnsiChar; dwBufLen: DWORD): DWORD; stdcall; external imm32;
function ImmGetGuideLineW(hImc: HIMC; dwIndex: DWORD; lpBuf: PWideChar; dwBufLen: DWORD): DWORD; stdcall; external imm32;
function ImmGetGuideLine(hImc: HIMC; dwIndex: DWORD; lpBuf: PChar; dwBufLen: DWORD): DWORD; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmGetGuideLineW'{$ELSE}'ImmGetGuideLineA'{$ENDIF};

function ImmGetConversionStatus(hImc: HIMC; var Conversion, Sentence: DWORD): Boolean; stdcall; external imm32;
function ImmSetConversionStatus(hImc: HIMC; Conversion, Sentence: DWORD): Boolean; stdcall; external imm32;
function ImmGetOpenStatus(hImc: HIMC): Boolean; stdcall; external imm32;
function ImmSetOpenStatus(hImc: HIMC; fOpen: Boolean): Boolean; stdcall; external imm32;

function ImmGetCompositionFontA(hImc: HIMC; lpLogfont: PLogFontA): Boolean; stdcall; external imm32;
function ImmGetCompositionFontW(hImc: HIMC; lpLogfont: PLogFontW): Boolean; stdcall; external imm32;
function ImmGetCompositionFont(hImc: HIMC; lpLogfont: PLogFont): Boolean; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmGetCompositionFontW'{$ELSE}'ImmGetCompositionFontA'{$ENDIF};

function ImmSetCompositionFontA(hImc: HIMC; lpLogfont: PLogFontA): Boolean; stdcall; external imm32;
function ImmSetCompositionFontW(hImc: HIMC; lpLogfont: PLogFontW): Boolean; stdcall; external imm32;
function ImmSetCompositionFont(hImc: HIMC; lpLogfont: PLogFont): Boolean; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmSetCompositionFontW'{$ELSE}'ImmSetCompositionFontA'{$ENDIF};

function ImmConfigureIMEA(hKl: HKL; hWnd: HWND; dwMode: DWORD; lpData: Pointer): Boolean; stdcall; external imm32;
function ImmConfigureIMEW(hKl: HKL; hWnd: HWND; dwMode: DWORD; lpData: Pointer): Boolean; stdcall; external imm32;
function ImmConfigureIME(hKl: HKL; hWnd: HWND; dwMode: DWORD; lpData: Pointer): Boolean; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmConfigureIMEW'{$ELSE}'ImmConfigureIMEA'{$ENDIF};

function ImmEscapeA(hKl: HKL; hImc: HIMC; uEscape: UINT; lpData: Pointer): LRESULT; stdcall; external imm32;
function ImmEscapeW(hKl: HKL; hImc: HIMC; uEscape: UINT; lpData: Pointer): LRESULT; stdcall; external imm32;
function ImmEscape(hKl: HKL; hImc: HIMC; uEscape: UINT; lpData: Pointer): LRESULT; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmEscapeW'{$ELSE}'ImmEscapeA'{$ENDIF};

function ImmGetConversionListA(hKl: HKL; hImc: HIMC; lpSrc: PAnsiChar; lpDst: PCandidateList;
  dwBufLen: DWORD; uFlag: UINT): DWORD; stdcall; external imm32;
function ImmGetConversionListW(hKl: HKL; hImc: HIMC; lpSrc: PWideChar; lpDst: PCandidateList;
  dwBufLen: DWORD; uFlag: UINT): DWORD; stdcall; external imm32;
function ImmGetConversionList(hKl: HKL; hImc: HIMC; lpSrc: PChar; lpDst: PCandidateList;
  dwBufLen: DWORD; uFlag: UINT): DWORD; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmGetConversionListW'{$ELSE}'ImmGetConversionListA'{$ENDIF};

function ImmNotifyIME(hImc: HIMC; dwAction, dwIndex, dwValue: DWORD): Boolean; stdcall; external imm32;

function ImmGetStatusWindowPos(hImc: HIMC; var lpPoint: TPoint): Boolean; stdcall; external imm32;
function ImmSetStatusWindowPos(hImc: HIMC; lpPoint: PPoint): Boolean; stdcall; external imm32;
function ImmGetCompositionWindow(hImc: HIMC; lpCompForm: PCompositionForm): Boolean; stdcall; external imm32;
function ImmSetCompositionWindow(hImc: HIMC; lpCompForm: PCompositionForm): Boolean; stdcall; external imm32;
function ImmGetCandidateWindow(hImc: HIMC; dwBufLen: DWORD; lpCandidate: PCandidateForm): Boolean; stdcall; external imm32;
function ImmSetCandidateWindow(hImc: HIMC; lpCandidate: PCandidateForm): Boolean; stdcall; external imm32;

function ImmIsUIMessageA(hWnd: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM): Boolean; stdcall; external imm32;
function ImmIsUIMessageW(hWnd: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM): Boolean; stdcall; external imm32;
function ImmIsUIMessage(hWnd: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM): Boolean; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmIsUIMessageW'{$ELSE}'ImmIsUIMessageA'{$ENDIF};

function ImmGetVirtualKey(hWnd: HWND): UINT; stdcall; external imm32;

type
  RegisterWordEnumProcA = function(lpReading: PAnsiChar; dwStyle: DWORD; lpszString: PAnsiChar; lpData: Pointer): Integer;
  RegisterWordEnumProcW = function(lpReading: PWideChar; dwStyle: DWORD; lpszString: PWideChar; lpData: Pointer): Integer;
  {$IFDEF UNICODE}
  RegisterWordEnumProc = RegisterWordEnumProcW;
  {$ELSE}
  RegisterWordEnumProc = RegisterWordEnumProcA;
  {$ENDIF}

function ImmRegisterWordA(hKl: HKL; lpszReading: PAnsiChar; dwStyle: DWORD; lpszRegister: PAnsiChar): Boolean; stdcall; external imm32;
function ImmRegisterWordW(hKl: HKL; lpszReading: PWideChar; dwStyle: DWORD; lpszRegister: PWideChar): Boolean; stdcall; external imm32;
function ImmRegisterWord(hKl: HKL; lpszReading: PChar; dwStyle: DWORD; lpszRegister: PChar): Boolean; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmRegisterWordW'{$ELSE}'ImmRegisterWordA'{$ENDIF};

function ImmUnregisterWordA(hKl: HKL; lpszReading: PAnsiChar; dwStyle: DWORD; lpszUnregister: PAnsiChar): Boolean; stdcall; external imm32;
function ImmUnregisterWordW(hKl: HKL; lpszReading: PWideChar; dwStyle: DWORD; lpszUnregister: PWideChar): Boolean; stdcall; external imm32;
function ImmUnregisterWord(hKl: HKL; lpszReading: PChar; dwStyle: DWORD; lpszUnregister: PChar): Boolean; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmUnregisterWordW'{$ELSE}'ImmUnregisterWordA'{$ENDIF};

function ImmGetRegisterWordStyleA(hKl: HKL; nItem: UINT; lpStyleBuf: PStyleBufA): UINT; stdcall; external imm32;
function ImmGetRegisterWordStyleW(hKl: HKL; nItem: UINT; lpStyleBuf: PStyleBufW): UINT; stdcall; external imm32;
function ImmGetRegisterWordStyle(hKl: HKL; nItem: UINT; lpStyleBuf: PStyleBuf): UINT; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmGetRegisterWordStyleW'{$ELSE}'ImmGetRegisterWordStyleA'{$ENDIF};

function ImmEnumRegisterWordA(hKl: HKL; lpfnEnumProc: RegisterWordEnumProcA;
  lpszReading: PAnsiChar; dwStyle: DWORD; lpszRegister: PAnsiChar; lpData: Pointer): UINT; stdcall; external imm32;
function ImmEnumRegisterWordW(hKl: HKL; lpfnEnumProc: RegisterWordEnumProcW;
 lpszReading: PWideChar; dwStyle: DWORD; lpszRegister: PWideChar; lpData: Pointer): UINT; stdcall; external imm32;
function ImmEnumRegisterWord(hKl: HKL; lpfnEnumProc: RegisterWordEnumProc;
  lpszReading: PChar; dwStyle: DWORD; lpszRegister: PChar; lpData: Pointer): UINT; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmEnumRegisterWordW'{$ELSE}'ImmEnumRegisterWordA'{$ENDIF};

function ImmDisableIME(dw: DWORD): BOOL; stdcall; external imm32;
function ImmEnumInputContext(idThread: DWORD; lpfn: IMCEnumProc; lParam: LPARAM): BOOL; stdcall; external imm32;

function ImmGetImeMenuItemsA(hImc: HIMC; dwFlags: DWORD; dwType: DWORD; out lpImeParentMenu: TIMEMenuItemInfoA;
  out lpImeMenu: TIMEMenuItemInfoA; dwSize: DWORD): BOOL; stdcall; external imm32;
function ImmGetImeMenuItemsW(hImc: HIMC; dwFlags: DWORD; dwType: DWORD; out lpImeParentMenu: TIMEMenuItemInfoW;
  out lpImeMenu: TIMEMenuItemInfoW; dwSize: DWORD): BOOL; stdcall; external imm32;
function ImmGetImeMenuItems(hImc: HIMC; dwFlags: DWORD; dwType: DWORD; out lpImeParentMenu: TIMEMenuItemInfo;
  out lpImeMenu: TIMEMenuItemInfo; dwSize: DWORD): BOOL; stdcall; external imm32
  name {$IFDEF UNICODE}'ImmGetImeMenuItemsW'{$ELSE}'ImmGetImeMenuItemsA'{$ENDIF};


const          
  // wParam for WM_IME_CONTROL
  IMC_GETCANDIDATEPOS             = $0007;
  IMC_SETCANDIDATEPOS             = $0008;
  IMC_GETCOMPOSITIONFONT          = $0009;
  IMC_SETCOMPOSITIONFONT          = $000A;
  IMC_GETCOMPOSITIONWINDOW        = $000B;
  IMC_SETCOMPOSITIONWINDOW        = $000C;
  IMC_GETSTATUSWINDOWPOS          = $000F;
  IMC_SETSTATUSWINDOWPOS          = $0010;
  IMC_CLOSESTATUSWINDOW           = $0021;
  IMC_OPENSTATUSWINDOW            = $0022;


  // dwAction for ImmNotifyIME
  NI_OPENCANDIDATE                = $0010;
  NI_CLOSECANDIDATE               = $0011;
  NI_SELECTCANDIDATESTR           = $0012;
  NI_CHANGECANDIDATELIST          = $0013;
  NI_FINALIZECONVERSIONRESULT     = $0014;
  NI_COMPOSITIONSTR               = $0015;
  NI_SETCANDIDATE_PAGESTART       = $0016;
  NI_SETCANDIDATE_PAGESIZE        = $0017;
  NI_IMEMENUSELECTED              = $0018;

  // lParam for WM_IME_SETCONTEXT
  ISC_SHOWUICANDIDATEWINDOW       = $00000001;
  ISC_SHOWUICOMPOSITIONWINDOW     = $80000000;
  ISC_SHOWUIGUIDELINE             = $40000000;
  ISC_SHOWUIALLCANDIDATEWINDOW    = $0000000F;
  ISC_SHOWUIALL                   = $C000000F;


  // dwIndex for ImmNotifyIME/NI_COMPOSITIONSTR
  CPS_COMPLETE                    = $0001;
  CPS_CONVERT                     = $0002;
  CPS_REVERT                      = $0003;
  CPS_CANCEL                      = $0004;

  // the modifiers of hot key
  MOD_ALT                         = $0001;
  MOD_CONTROL                     = $0002;
  MOD_SHIFT                       = $0004;

  MOD_LEFT                        = $8000;
  MOD_RIGHT                       = $4000;

  MOD_ON_KEYUP                    = $0800;
  MOD_IGNORE_ALL_MODIFIER         = $0400;

  // Windows for Simplified Chinese Edition hot key ID from 0x10 - 0x2F
  IME_CHOTKEY_IME_NONIME_TOGGLE           = $10;
  IME_CHOTKEY_SHAPE_TOGGLE                = $11;
  IME_CHOTKEY_SYMBOL_TOGGLE               = $12;

  // Windows for Japanese Edition hot key ID from 0x30 - 0x4F
  IME_JHOTKEY_CLOSE_OPEN                  = $30;

  // Windows for Korean Edition hot key ID from 0x50 - 0x6F
  IME_KHOTKEY_SHAPE_TOGGLE                = $50;
  IME_KHOTKEY_HANJACONVERT                = $51;
  IME_KHOTKEY_ENGLISH                     = $52;

  // Windows for Traditional Chinese Edition hot key ID from 0x70 - 0x8F
  IME_THOTKEY_IME_NONIME_TOGGLE           = $70;
  IME_THOTKEY_SHAPE_TOGGLE                = $71;
  IME_THOTKEY_SYMBOL_TOGGLE               = $72;

  // direct switch hot key ID from 0x100 - 0x11F
  IME_HOTKEY_DSWITCH_FIRST                = $100;
  IME_HOTKEY_DSWITCH_LAST                 = $11F;

  // IME private hot key from 0x200 - 0x21F
  IME_HOTKEY_PRIVATE_FIRST                = $200;
  IME_ITHOTKEY_RESEND_RESULTSTR           = $200;
  IME_ITHOTKEY_PREVIOUS_COMPOSITION       = $201;
  IME_ITHOTKEY_UISTYLE_TOGGLE             = $202;
  IME_ITHOTKEY_RECONVERTSTRING            = $203;
  IME_HOTKEY_PRIVATE_LAST                 = $21F;


  // parameter of ImmGetCompositionString
  GCS_COMPREADSTR                 = $0001;
  GCS_COMPREADATTR                = $0002;
  GCS_COMPREADCLAUSE              = $0004;
  GCS_COMPSTR                     = $0008;
  GCS_COMPATTR                    = $0010;
  GCS_COMPCLAUSE                  = $0020;
  GCS_CURSORPOS                   = $0080;
  GCS_DELTASTART                  = $0100;
  GCS_RESULTREADSTR               = $0200;
  GCS_RESULTREADCLAUSE            = $0400;
  GCS_RESULTSTR                   = $0800;
  GCS_RESULTCLAUSE                = $1000;

  // style bit flags for WM_IME_COMPOSITION
  CS_INSERTCHAR                   = $2000;
  CS_NOMOVECARET                  = $4000;

  // IME version constants
  IMEVER_0310                     = $0003000A;
  IMEVER_0400                     = $00040000;


  // IME property bits
  IME_PROP_AT_CARET               = $00010000;
  IME_PROP_SPECIAL_UI             = $00020000;
  IME_PROP_CANDLIST_START_FROM_1  = $00040000;
  IME_PROP_UNICODE                = $00080000;
  IME_PROP_COMPLETE_ON_UNSELECT   = $00100000;


  // IME UICapability bits
  UI_CAP_2700                     = $00000001;
  UI_CAP_ROT90                    = $00000002;
  UI_CAP_ROTANY                   = $00000004;

  // ImmSetCompositionString Capability bits
  SCS_CAP_COMPSTR                 = $00000001;
  SCS_CAP_MAKEREAD                = $00000002;
  SCS_CAP_SETRECONVERTSTRING      = $00000004;


  // IME WM_IME_SELECT inheritance Capability bits
  SELECT_CAP_CONVERSION           = $00000001;
  SELECT_CAP_SENTENCE             = $00000002;


  // ID for deIndex of ImmGetGuideLine
  GGL_LEVEL                       = $00000001;
  GGL_INDEX                       = $00000002;
  GGL_STRING                      = $00000003;
  GGL_PRIVATE                     = $00000004;


  // ID for dwLevel of GUIDELINE Structure
  GL_LEVEL_NOGUIDELINE            = $00000000;
  GL_LEVEL_FATAL                  = $00000001;
  GL_LEVEL_ERROR                  = $00000002;
  GL_LEVEL_WARNING                = $00000003;
  GL_LEVEL_INFORMATION            = $00000004;


  // ID for dwIndex of GUIDELINE Structure
  GL_ID_UNKNOWN                   = $00000000;
  GL_ID_NOMODULE                  = $00000001;
  GL_ID_NODICTIONARY              = $00000010;
  GL_ID_CANNOTSAVE                = $00000011;
  GL_ID_NOCONVERT                 = $00000020;
  GL_ID_TYPINGERROR               = $00000021;
  GL_ID_TOOMANYSTROKE             = $00000022;
  GL_ID_READINGCONFLICT           = $00000023;
  GL_ID_INPUTREADING              = $00000024;
  GL_ID_INPUTRADICAL              = $00000025;
  GL_ID_INPUTCODE                 = $00000026;
  GL_ID_INPUTSYMBOL               = $00000027;
  GL_ID_CHOOSECANDIDATE           = $00000028;
  GL_ID_REVERSECONVERSION         = $00000029;
  GL_ID_PRIVATE_FIRST             = $00008000;
  GL_ID_PRIVATE_LAST              = $0000FFFF;


  // ID for dwIndex of ImmGetProperty
  IGP_GETIMEVERSION               = DWORD(-4);
  IGP_PROPERTY                    = $00000004;
  IGP_CONVERSION                  = $00000008;
  IGP_SENTENCE                    = $0000000c;
  IGP_UI                          = $00000010;
  IGP_SETCOMPSTR                  = $00000014;
  IGP_SELECT                      = $00000018;

  // dwIndex for ImmSetCompositionString API
  SCS_SETSTR                      = (GCS_COMPREADSTR or GCS_COMPSTR);
  SCS_CHANGEATTR                  = (GCS_COMPREADATTR or GCS_COMPATTR);
  SCS_CHANGECLAUSE                = (GCS_COMPREADCLAUSE or GCS_COMPCLAUSE);
  SCS_SETRECONVERTSTRING          = $00010000;
  SCS_QUERYRECONVERTSTRING        = $00020000;

  // attribute for COMPOSITIONSTRING Structure
  ATTR_INPUT                      = $00;
  ATTR_TARGET_CONVERTED           = $01;
  ATTR_CONVERTED                  = $02;
  ATTR_TARGET_NOTCONVERTED        = $03;
  ATTR_INPUT_ERROR                = $04;
  ATTR_FIXEDCONVERTED             = $05;

  // bit field for IMC_SETCOMPOSITIONWINDOW, IMC_SETCANDIDATEWINDOW
  CFS_DEFAULT                     = $0000;
  CFS_RECT                        = $0001;
  CFS_POINT                       = $0002;
  CFS_FORCE_POSITION              = $0020;
  CFS_CANDIDATEPOS                = $0040;
  CFS_EXCLUDE                     = $0080;

  // conversion direction for ImmGetConversionList
  GCL_CONVERSION                  = $0001;
  GCL_REVERSECONVERSION           = $0002;
  GCL_REVERSE_LENGTH              = $0003;

  // bit field for conversion mode
  IME_CMODE_ALPHANUMERIC          = $0000;
  IME_CMODE_NATIVE                = $0001;
  IME_CMODE_CHINESE               = IME_CMODE_NATIVE;
  // IME_CMODE_HANGEUL is old name of IME_CMODE_HANGUL. It will be gone eventually.
  IME_CMODE_HANGEUL               = IME_CMODE_NATIVE;
  IME_CMODE_HANGUL                = IME_CMODE_NATIVE;
  IME_CMODE_JAPANESE              = IME_CMODE_NATIVE;
  IME_CMODE_KATAKANA              = $0002;  // only effect under IME_CMODE_NATIVE
  IME_CMODE_LANGUAGE              = $0003;
  IME_CMODE_FULLSHAPE             = $0008;
  IME_CMODE_ROMAN                 = $0010;
  IME_CMODE_CHARCODE              = $0020;
  IME_CMODE_HANJACONVERT          = $0040;
  IME_CMODE_SOFTKBD               = $0080;
  IME_CMODE_NOCONVERSION          = $0100;
  IME_CMODE_EUDC                  = $0200;
  IME_CMODE_SYMBOL                = $0400;
  IME_CMODE_FIXED                 = $0800;

  // bit field for sentence mode
  IME_SMODE_NONE                  = $0000;
  IME_SMODE_PLAURALCLAUSE         = $0001;
  IME_SMODE_SINGLECONVERT         = $0002;
  IME_SMODE_AUTOMATIC             = $0004;
  IME_SMODE_PHRASEPREDICT         = $0008;
  IME_SMODE_CONVERSATION          = $0010;

  // style of candidate
  IME_CAND_UNKNOWN                = $0000;
  IME_CAND_READ                   = $0001;
  IME_CAND_CODE                   = $0002;
  IME_CAND_MEANING                = $0003;
  IME_CAND_RADICAL                = $0004;
  IME_CAND_STROKE                 = $0005;

  // wParam of report message WM_IME_NOTIFY
  IMN_CLOSESTATUSWINDOW           = $0001;
  IMN_OPENSTATUSWINDOW            = $0002;
  IMN_CHANGECANDIDATE             = $0003;
  IMN_CLOSECANDIDATE              = $0004;
  IMN_OPENCANDIDATE               = $0005;
  IMN_SETCONVERSIONMODE           = $0006;
  IMN_SETSENTENCEMODE             = $0007;
  IMN_SETOPENSTATUS               = $0008;
  IMN_SETCANDIDATEPOS             = $0009;
  IMN_SETCOMPOSITIONFONT          = $000A;
  IMN_SETCOMPOSITIONWINDOW        = $000B;
  IMN_SETSTATUSWINDOWPOS          = $000C;
  IMN_GUIDELINE                   = $000D;
  IMN_PRIVATE                     = $000E;

  // wParam of report message WM_IME_REQUEST
  IMR_COMPOSITIONWINDOW           = $0001;
  IMR_CANDIDATEWINDOW             = $0002;
  IMR_COMPOSITIONFONT             = $0003;
  IMR_RECONVERTSTRING             = $0004;
  IMR_CONFIRMRECONVERTSTRING      = $0005;
  IMR_QUERYCHARPOSITION           = $0006;
  IMR_DOCUMENTFEED                = $0007;

  // error code of ImmGetCompositionString
  IMM_ERROR_NODATA                = (-1);
  IMM_ERROR_GENERAL               = (-2);


  // dialog mode of ImmConfigureIME
  IME_CONFIG_GENERAL              = 1;
  IME_CONFIG_REGISTERWORD         = 2;
  IME_CONFIG_SELECTDICTIONARY     = 3;


  // flags for ImmEscape
  IME_ESC_QUERY_SUPPORT           = $0003;
  IME_ESC_RESERVED_FIRST          = $0004;
  IME_ESC_RESERVED_LAST           = $07FF;
  IME_ESC_PRIVATE_FIRST           = $0800;
  IME_ESC_PRIVATE_LAST            = $0FFF;

  IME_ESC_SEQUENCE_TO_INTERNAL    = $1001;
  IME_ESC_GET_EUDC_DICTIONARY     = $1003;
  IME_ESC_SET_EUDC_DICTIONARY     = $1004;
  IME_ESC_MAX_KEY                 = $1005;
  IME_ESC_IME_NAME                = $1006;
  IME_ESC_SYNC_HOTKEY             = $1007;
  IME_ESC_HANJA_MODE              = $1008;
  IME_ESC_AUTOMATA                = $1009;
  IME_ESC_PRIVATE_HOTKEY          = $100a;
  IME_ESC_GETHELPFILENAME         = $100b;
  // style of word registration
  IME_REGWORD_STYLE_EUDC          = $00000001;
  IME_REGWORD_STYLE_USER_FIRST    = $80000000;
  IME_REGWORD_STYLE_USER_LAST     = $FFFFFFFF;


  // dwFlags for ImmAssociateContextEx
  IACE_CHILDREN                   = $0001;
  IACE_DEFAULT                    = $0010;
  IACE_IGNORENOCONTEXT            = $0020;

  // dwFlags for ImmGetImeMenuItems
  IGIMIF_RIGHTMENU                = $0001;

  // dwType for ImmGetImeMenuItems
  IGIMII_CMODE                    = $0001;
  IGIMII_SMODE                    = $0002;
  IGIMII_CONFIGURE                = $0004;
  IGIMII_TOOLS                    = $0008;
  IGIMII_HELP                     = $0010;
  IGIMII_OTHER                    = $0020;
  IGIMII_INPUTTOOLS               = $0040;

  // fType of IMEMENUITEMINFO structure
  IMFT_RADIOCHECK = $00001;
  IMFT_SEPARATOR  = $00002;
  IMFT_SUBMENU    = $00004;

  // fState of IMEMENUITEMINFO structure
  IMFS_GRAYED          = MFS_GRAYED;
  IMFS_DISABLED        = MFS_DISABLED;
  IMFS_CHECKED         = MFS_CHECKED;
  IMFS_HILITE          = MFS_HILITE;
  IMFS_ENABLED         = MFS_ENABLED;
  IMFS_UNCHECKED       = MFS_UNCHECKED;
  IMFS_UNHILITE        = MFS_UNHILITE;
  IMFS_DEFAULT         = MFS_DEFAULT;

  // type of soft keyboard
  // for Windows Tranditional Chinese Edition
  SOFTKEYBOARD_TYPE_T1            = $0001;
  // for Windows Simplified Chinese Edition
  SOFTKEYBOARD_TYPE_C1            = $0002;

implementation

end.
imm.pp (29,961 bytes)

Saeka-jp

2009-02-11 10:18

reporter   ~0025263

Last edited: 2009-02-11 10:20

Imm.pp is missing in current lazarus?
This is needed when using IME-API on only Windows.

Or Imm.pp was renamed ?

(attached imm.pp)

2009-02-19 16:48

 

synedit_pp_18762.patch (2,044 bytes)
Index: synedit.pp
===================================================================
--- synedit.pp	(revision 18763)
+++ synedit.pp	(working copy)
@@ -65,6 +65,10 @@
   {$IFDEF USE_UTF8BIDI_LCL}
   FreeBIDI, utf8bidi,
   {$ENDIF}
+{ #FIX-JP ADD >>}
+  Imm,
+{ << FIX-JP }
+
   Types, FPCAdds, LCLIntf, LCLType, LMessages, LCLProc,
 {$ELSE}
   Windows,
@@ -296,10 +300,15 @@
     procedure WMEraseBkgnd(var Msg: TMessage); message WM_ERASEBKGND;
     procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message WM_GETDLGCODE;
     procedure WMHScroll(var Msg: {$IFDEF SYN_LAZARUS}TLMScroll{$ELSE}TWMScroll{$ENDIF}); message WM_HSCROLL;
-{$IFDEF SYN_MBCSSUPPORT}
+
+{ #FIX-JP ADD >>}
+    fImeCount: Integer;
+{ << FIX-JP }
+
+//{$IFDEF SYN_MBCSSUPPORT}
     procedure WMImeComposition(var Msg: TMessage); message WM_IME_COMPOSITION;
     procedure WMImeNotify(var Msg: TMessage); message WM_IME_NOTIFY;
-{$ENDIF}
+//{$ENDIF}
     procedure WMKillFocus(var Msg: TWMKillFocus); message WM_KILLFOCUS;
     {$IFDEF SYN_LAZARUS}
     procedure WMExit(var Message: TLMExit); message LM_EXIT;
@@ -1894,7 +1903,7 @@
   end;
 end;
 
-{$IFDEF SYN_MBCSSUPPORT}
+//{$IFDEF SYN_MBCSSUPPORT}
 procedure TCustomSynEdit.WMImeComposition(var Msg: TMessage);
 var
   imc: HIMC;
@@ -1940,8 +1949,9 @@
   end;
   inherited;
 end;
-{$ENDIF}
+//{$ENDIF}
 
+
 procedure TCustomSynEdit.IncPaintLock;
 begin
   inc(fPaintLock);
@@ -3851,9 +3861,9 @@
 procedure TCustomSynEdit.UpdateCaret;
 var
   CX, CY: Integer;
-{$IFDEF SYN_MBCSSUPPORT}
+//{$IFDEF SYN_MBCSSUPPORT}
   cf: TCompositionForm;
-{$ENDIF}
+//{$ENDIF}
 begin
   if (PaintLock <> 0)
   {$IFDEF SYN_LAZARUS}
@@ -3884,13 +3894,13 @@
       HideCaret;
       SetCaretPosEx(Handle ,CX + FCaretOffset.X, CY + FCaretOffset.Y);
     end;
-{$IFDEF SYN_MBCSSUPPORT}
+//{$IFDEF SYN_MBCSSUPPORT}
     if HandleAllocated then begin
       cf.dwStyle := CFS_POINT;
       cf.ptCurrentPos := Point(CX, CY);
       ImmSetCompositionWindow(ImmGetContext(Handle), @cf);
     end;
-{$ENDIF}
+//{$ENDIF}
   end;
 end;
 
synedit_pp_18762.patch (2,044 bytes)

Saeka-jp

2009-02-19 16:54

reporter   ~0025582

We can input Japanese Characters correctly by this patch + imm.pp on Windows.
This patch is available to newest svn today, (18762) , only windows.

Martin Friebe

2009-02-19 17:32

manager   ~0025583

@Saeka: Can you tell me the last version of FPC or Lazarus (which one) that contained imm.pp?

I need to be sure it wasn't removed for some reason (like copyright / clean room)

Saeka-jp

2009-02-21 00:35

reporter   ~0025603

Last edited: 2009-02-21 00:38

Attached imm.pp was downloaded some years ago, with graphics components for FreePascal.
It seems to be a part of RTL of FPC (according to comment of it), but current lazarus or FPC is not include it.
For instance, In WinCE, the same functions header of IME is included in. ( WinCE directory, coredll.inc )

It is only dll-header. If is there any probrem, shall I recreate it in clean room ?

Martin Friebe

2009-02-23 00:50

manager   ~0025646

I'll have to find out myself what the best way is to get the file added (imm.pp) I only joined lazarus a short while back.

best is to go to the fpc mailing list (I did a quick post, see the answer at http://lists.freepascal.org/lists/fpc-devel/2009-February/016375.html ).

You may ask the FPC team yourself, what the best way is.
(Sorry not to be of more help at the moment, simply not enough time...)

Saeka-jp

2009-02-23 22:16

reporter   ~0025691

@Martin
Thank you very much.

Vincent Snijders

2010-12-28 14:14

manager   ~0044653

Dmitry created an imm unit, which can be found at in the fpc packages:
packages\winunits-base\src\imm.pas

Zeljan Rikalo

2012-02-11 20:01

developer   ~0056759

@Martin, what about this one ?

Martin Friebe

2012-02-13 01:58

manager   ~0056787

Last edited: 2012-03-11 01:45

Anyone wanting to try:
compile with WinIME defined. Very basic, only sets the position of the IME editor, nothing else. But at least it isn't in the corner of the screen.

EDIT: no define needed, anymore

Martin Friebe

2012-03-17 23:40

manager   ~0057803

Please test and close if ok

The windows IDE has an option in Editor/General/Misc to change the level of integration

Issue History

Date Modified Username Field Change
2009-02-09 14:12 Saeka-jp New Issue
2009-02-09 14:12 Saeka-jp Widgetset => Win32
2009-02-09 14:39 Martin Friebe Relationship added related to 0011819
2009-02-09 14:42 Martin Friebe Status new => assigned
2009-02-09 14:42 Martin Friebe Assigned To => Martin Friebe
2009-02-09 14:44 Martin Friebe LazTarget => 1.0
2009-02-09 14:53 Dmitry Boyarintsev Note Added: 0025225
2009-02-09 15:16 Saeka-jp Note Added: 0025226
2009-02-11 10:17 Saeka-jp File Added: imm.pp
2009-02-11 10:18 Saeka-jp Note Added: 0025263
2009-02-11 10:20 Saeka-jp Note Edited: 0025263
2009-02-19 16:48 Saeka-jp File Added: synedit_pp_18762.patch
2009-02-19 16:54 Saeka-jp Note Added: 0025582
2009-02-19 17:32 Martin Friebe Note Added: 0025583
2009-02-21 00:35 Saeka-jp Note Added: 0025603
2009-02-21 00:37 Saeka-jp Note Edited: 0025603
2009-02-21 00:38 Saeka-jp Note Edited: 0025603
2009-02-23 00:50 Martin Friebe Note Added: 0025646
2009-02-23 22:16 Saeka-jp Note Added: 0025691
2010-12-28 14:14 Vincent Snijders Note Added: 0044653
2012-02-11 20:01 Zeljan Rikalo Note Added: 0056759
2012-02-11 20:01 Zeljan Rikalo Status assigned => feedback
2012-02-13 01:58 Martin Friebe Note Added: 0056787
2012-03-09 21:44 Martin Friebe Relationship added related to 0021450
2012-03-11 01:45 Martin Friebe Note Edited: 0056787
2012-03-17 23:40 Martin Friebe Status feedback => resolved
2012-03-17 23:40 Martin Friebe Fixed in Version => 0.9.31 (SVN)
2012-03-17 23:40 Martin Friebe Resolution open => fixed
2012-03-17 23:40 Martin Friebe Note Added: 0057803
2012-03-17 23:40 Martin Friebe Target Version => 1.0.0