none
a quesiont about how to use IFEDictionary::RegisterWord in c# RRS feed

  • Question

  • Hello



    I have a quesiont about how to use IFEDictionary::RegisterWord in c#,please help me.



    I had defined the IMEWRD structure like this in my c# code:



    ///the struct is define in MsIme class

    [StructLayout(LayoutKind.Explicit)]

        public struct IMEWRD

        {

            [FieldOffset(0), MarshalAs(UnmanagedType.LPWStr)]

            public string pwchReading;

            [FieldOffset(4), MarshalAs(UnmanagedType.LPWStr)]

            public string pwchDisplay;



            [FieldOffset(8)]

            public uint ulPos;

            [FieldOffset(8)]

            public ushort nPos1;

            [FieldOffset(10)]

            public ushort nPos2;



            [FieldOffset(12)]

            public IntPtr rgulAttrs;

            [FieldOffset(16)]

            public int cbComment;

            [FieldOffset(20)]

            public int uct;

            [FieldOffset(24)]

            public IntPtr pvComment;

        }



    then,i give this struct a value like this:



             var imeWord = new MsIme.IMEWRD();

                imeWord.pwchDisplay = "てすと";

                imeWord.pwchReading = "テスト1";

                imeWord.ulPos = 0x00000001;

                imeWord.rgulAttrs = IntPtr.Zero;

                imeWord.cbComment = 0;

                imeWord.uct = 0;

                imeWord.pvComment = IntPtr.Zero;



    then i call the function like this:



            private IFDictionary m_IfeDictionary;

         ///there is some source about how to create m_IfeDictionary instance;

         ///then,we call the function



         var structPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(MsIme.IMEWRD)));

            Marshal.StructureToPtr(imeWord, structPtr, false);

            errCode = m_IfeDictionary.RegisterWord(0, structPtr);



    but the problem is it always feedback me a Error Like this:
    "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
    • Moved by CoolDadTx Friday, November 4, 2011 2:58 AM Office related (From:Visual C# General)
    Thursday, November 3, 2011 11:50 AM

Answers

  • I don't understand how you're getting access to an instance of the IFEDictionary interface.  Based upon what I understand (which is very little when it comes to IME) you first need to get access to the IME object depending upon how you're interacting with it (bringing up IME, etc).  In most cases it is a native method call that gives you the COM interface pointer.  From then on it'll be COM calls (http://msdn.microsoft.com/en-us/library/ee828920(v=office.12).aspx).  However IME seems to support an alternative version when the IME is already open.  So I guess it depends upon how you're working with it. 

    The IME doesn't appear to be installed unless you're running an appropriate version of the OS.  Therefore you'd need to generate the COM interop assembly on an appropriate machine and then use that rather than the COM object directly.  I'm just guessing here though.

    Here's a link (http://social.msdn.microsoft.com/forums/en-US/gametechnologiesdirectx101/thread/32e53d65-4f99-4e47-9207-7254a96af33e/) to a set of articles someone else had for getting IME to work via C#.  I recommend you take a look at them.  Maybe somebody else will be able to better assist you.  I've reached the limits of my knowledge on this subject.  Good luck.

    Michael Taylor - 11/4/2011
    http://msmvps.com/blogs/p3net

     

    • Proposed as answer by Bruce Song Wednesday, November 16, 2011 5:42 AM
    • Marked as answer by Bruce Song Monday, November 28, 2011 9:49 AM
    Friday, November 4, 2011 3:04 PM

All replies

  • Your structure definition is incorrect.  rgulAttrs isn't a pointer, it is an array of uints of size 2. 

    The explicit layout isn't really helping matters either.  You should move the union definition outside the struct.  This adds a layer of abstraction on the .NET side but doesn't impact the memory layout.

    Finally note that the structure has the strings as writable.  If the unmanaged code tries to write to it then it'll probably fail.

    Michael Taylor - 11/3/2011
    http://msmvps.com/blogs/p3net

    Thursday, November 3, 2011 2:48 PM
  • thank you for your answer.

     

    now i define the structure like this:

    [StructLayout(LayoutKind.Sequential)]

        public struct IMEWRD

        {

            [MarshalAs(UnmanagedType.LPWStr)]

            public string pwchReading;

            [MarshalAs(UnmanagedType.LPWStr)]

            public string pwchDisplay;


            public UnionStru uion;     

     

            [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]

            public uint[] rgulAttrs;

            public IntPtr cbComment;

            public int uct;

            public IntPtr pvComment;

        }

     

        [StructLayout(LayoutKind.Explicit)]

        public struct UnionStru

        {

            [FieldOffset(0)]

            public uint ulPos;

            [FieldOffset(0)]

            public ushort nPos1;

            [FieldOffset(2)]

            public ushort nPos2;

        };

    is it right?

     

    then if it is right, according to the http://msdn.microsoft.com/zh-cn/library/ms905983.

    rgulAttrs
    Set the value to NULL. Ignored.

    what is the suitable value for rgulAttrs i should give?


     

    Friday, November 4, 2011 1:21 AM
  • You should initialize rgulAttrs to uint[2].  But I'm not really sure why you need to go through all this anyway.  This is being used for a COM interface.  You shouldn't have to define any of this yourself.  The path you're going down is for P/Invoke which you wouldn't use for COM.

    For a COM interface you would add a reference to the COM object to your project via Add References.  Then VS will auto-generate all the code needed to get the interop working.  All you'll see is the .NET side of the fence.  In fact I think you just need to reference the standard Office component and the interop assembly will have everything you need.  But I don't work with Office so I can't say for certain.  It certainly appears that way given this: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.dictionary.aspx

    I'm moving this post to the Office forums where they will be able to help you better.

    Michael Taylor - 11/4/2011
    http://msmvps.com/blogs/p3net

    Friday, November 4, 2011 2:57 AM
  • Thank you for your answer.

    The document of the interface i used is here,

    http://msdn.microsoft.com/en-us/library/ee815965%28v=office.12%29.aspx

    As you see,i can not find the COM object to Add References.So i have to use the P/Invoke way to make it work.

    there is no much more document about the integerface in internect except msdn,so it trouble me a lot at how to use it.

    hope there is some way to get throught it.

    Best Regards.

     

     

    Friday, November 4, 2011 6:58 AM
  • I don't understand how you're getting access to an instance of the IFEDictionary interface.  Based upon what I understand (which is very little when it comes to IME) you first need to get access to the IME object depending upon how you're interacting with it (bringing up IME, etc).  In most cases it is a native method call that gives you the COM interface pointer.  From then on it'll be COM calls (http://msdn.microsoft.com/en-us/library/ee828920(v=office.12).aspx).  However IME seems to support an alternative version when the IME is already open.  So I guess it depends upon how you're working with it. 

    The IME doesn't appear to be installed unless you're running an appropriate version of the OS.  Therefore you'd need to generate the COM interop assembly on an appropriate machine and then use that rather than the COM object directly.  I'm just guessing here though.

    Here's a link (http://social.msdn.microsoft.com/forums/en-US/gametechnologiesdirectx101/thread/32e53d65-4f99-4e47-9207-7254a96af33e/) to a set of articles someone else had for getting IME to work via C#.  I recommend you take a look at them.  Maybe somebody else will be able to better assist you.  I've reached the limits of my knowledge on this subject.  Good luck.

    Michael Taylor - 11/4/2011
    http://msmvps.com/blogs/p3net

     

    • Proposed as answer by Bruce Song Wednesday, November 16, 2011 5:42 AM
    • Marked as answer by Bruce Song Monday, November 28, 2011 9:49 AM
    Friday, November 4, 2011 3:04 PM
  • thank you very much.

    i will keep on working with this.

    if  i have a answer, i will update this post .

     

    Best Regards.

    Monday, November 7, 2011 1:34 AM
  • Microsoft does not seem to provide TypeLib or IDL for MSIME. So you have to create wrapper class manually from msime.h to use it from C#.

    http://www.microsoft.com/download/en/details.aspx?id=9739

    Friday, November 25, 2011 8:38 AM
  • After you correctly defined wrapper class, to create IFEDictionary instance, use Activator.CreateInstance method with RCW Type for MSIME. The RCW type can be obtained from Type.GetTypeFromProgID with MSIME ProgID ("MSIME.Japan", "MSIME.Japan.11", etc.).

    Friday, November 25, 2011 8:52 AM