1

I'm am dealing with the exact same situation as This Question.

There were no answers and the question was too old, so I could not leave any comments seeing if the OP found a solution.

I am just now learning the basics of p/invoke, and hardly understand it at the least.

I have been doing quite a bit of searching. I found This question which linked me to This question/answer but am still not able to understand what I need to do.

I guess i'm asking for a way to manipulate the WM_IME commands, or atleast disable the WM_IME_ENDCOMPOSITION on mouse clicks.

Thank you in advance

Community
  • 1
  • 1
Erick Ely
  • 269
  • 1
  • 7
  • 16
  • possible duplicate of [Windows IME: custom Korean virtual keyboard](http://stackoverflow.com/questions/7679249/windows-ime-custom-korean-virtual-keyboard) ... sorry, a dupe is a dupe. "question was too old" should make no difference to one's ability to add comments. – spender Feb 21 '12 at 15:40
  • I didn't want to add an "answer" because it is not an answer. There is no link for "add comment" which is what it is, a comment. – Erick Ely Feb 21 '12 at 15:47

2 Answers2

1

No expert in IME, but couldn't you just override the 'WndProc' but not pass the "message" as it were preventing other applications / controls from processing it? WndProc captures the hundreds of 'Windows Messages' that are generated by the operating system that can be captured to 'whoever' is listening, one approach would be to selectively ignore that message when the conditions are right...

protected override void WndProc(ref Message m)
  {
    switch(m.Msg)
    {
      case WM_IME_ENDCOMPOSITION :
        // Gobble this up or ignore
        break;
      default:
        // Continue as normal
        base.WndProc (ref m);
        break;
    }
  }

For instance, if you're dealing with a Control, you could override the WndProc for the control, capture the mouse down event (or WM_MOUSEDOWN), set a variable to ignore the WM_IME_ENDCOMPOSITION and then reenable that variable on the mouse up (or WM_MOUSEUP)? Alternatively you could utilise a MouseHook but this might be a bit of overkill...

SeanCocteau
  • 1,838
  • 19
  • 25
  • I think I can do everything you explained except setting a variable to ignore WM_IME_ENDCOMPOSITION. well.. you pretty much showed me everything.. haha. how would I go about ignoring the command? – Erick Ely Feb 21 '12 at 16:53
  • Er - nothing. By not calling the 'base.WndProc' and passing the message across, you have effectively consumed the message. In the above example you don't do anything with it. You will encounter other examples that will process the message with a custom method, but if you want other processes to be shown that message you pass the message back... – SeanCocteau Feb 21 '12 at 17:06
  • Hmmm.. it's actually has no affect on my application. Is there a way for me to see the window messages as they fire? (Just to clarify, I am using the proper constant for WM_IME_ENDCOMPOSITION [0x10E]) – Erick Ely Feb 21 '12 at 17:54
  • I found a way around it. Thank you for your help though =D – Erick Ely Feb 21 '12 at 20:10
  • Awesome - I believe in the spirit of the 'knowledge-base' it might be beneficial to specify what you did. Add it as an answer and I'll unmark my response as the answer... – SeanCocteau Feb 22 '12 at 10:18
0

What I ended up doing, as WM_IME_ENDCOMPOSITION apparently wasn't firing, I tried disabled the mouseactivate winproc instead.

        private const int WM_MOUSEACTIVATE = 0x0021;
        private const int MA_NOACTIVATEANDEAT = 0x0004;

        protected override void WndProc(ref Message m)
        {
            if (mousestatus == 0)
            {
                if (m.Msg == WM_MOUSEACTIVATE)
                {
                    m.Result = (IntPtr)MA_NOACTIVATEANDEAT;
                    return;
                }
                base.WndProc(ref m);
            }
        }

and then changed all my panel click event handlers to mouse over events. Because there were parts of the application that did need to be clicked, I added a mousestatus variable so that only when mousestatus was 0 would the mouse clicks be disabled. This was defined by mouse position (as with the mouseclicks disabled, I wouldn't be able to click anything to enable it).

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

    private void timer1_Tick(object sender, EventArgs e)
    {
        if ((Cursor.Position.X - Location.X) >= 904 && (Cursor.Position.X - Location.X) <= 963 && (Cursor.Position.Y - Location.Y) >= 145 && (Cursor.Position.Y - Location.Y) <= 167)
        {
            mousestatus = 1;

            mouse_event(MOUSEEVENTF_LEFTDOWN, Cursor.Position.X, Cursor.Position.Y, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, Cursor.Position.X, Cursor.Position.Y, 0, 0);


            timer4.Start();

        }
    }

I was pretty sure that the click would come before the mousestatus=1 was defined, so just to make sure the spot I needed was clicked, I put in a virtual mouse click. the timer4 was just a timer that set mousestatus back to 0.

The code may be a bit messy, and i'm sure there are some shortcuts I could have used, but as of now, it works for what I need. =D

Erick Ely
  • 269
  • 1
  • 7
  • 16