ryancheung / ImeSharp

C# wrapper for Windows IME APIs
MIT License
71 stars 12 forks source link

Calling ITfCompositionView.Dispose() too many. #18

Open punigram opened 1 month ago

punigram commented 1 month ago

Thank you for your very useful component. Because IME and TSF's informations is very rare. It's hard to develop my original text input UI system if this component didn't exist.

I'm using ImeSharp as my original customized verison. But I have a problem. System.AccessViolationException happened when end composition timing.

Happened here: TextStore.cs

        public Result RequestLock(TsfSharp.TsLfFlags dwLockFlags)

            hrSession = _sink.OnLockGranted(dwLockFlags);  // <<HERE

On ImeSharp.Demo the problem doesn't happened. So I researched and found a bug(?).

TextStore.cs

      public void OnEndComposition(ITfCompositionView view)

          view.Dispose()
          foreach(var item in _compViews)
                item.Dispose();
         _comvVIews.Clear();

On windows TSF sample https://github.com/microsoft/Windows-classic-samples/blob/7af17c73750469ed2b5732a49e5cb26cbb716094/Samples/Win7Samples/winui/tsf/tsfapp/context.cpp

In CTSFEditWnd::OnStartComposition() calling ITfCompositionView.AddRef() In CTSFEditWnd::OnEndComposition() calling ITfCompositionView.Release()

COM object's reference counter are incremented and decremented.

But in TextStore.cs, No view.AddRef() calling but calling view.Dispose(). And also _compViews item's Dispose() called (I think it same ITfCompositionView object). Dispose() calls Release() internally, so the reference counter unmatched.

I fixed it like this:

Adding OnStartComposition()

view.AddRef()

And remove OnUpdateComposition()

 _compViews.Add(view)

And replace OnEndComposition()

_compViews.Remove(view)
view.Dispose()

I don't know well sharpgen's COM convert system. So I might be misunderstanding the problem.