public bool ProcessEvent(TwIdentity dataSourceId, ref WINMSG message, ref TwMSG result)
      {
        TwEvent evtmsg;
        evtmsg.Message = 0;
        evtmsg.EventPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINMSG)));
        Marshal.StructureToPtr(message, evtmsg.EventPtr, false);

        TwRC rc = LibTwain32.DSevent(fApplicationId, dataSourceId, TwDG.Control, TwDAT.Event, TwMSG.ProcessEvent, ref evtmsg);

        Marshal.FreeHGlobal(evtmsg.EventPtr);
        result = evtmsg.Message;

        return (bool)(rc == TwRC.DSEvent);
      }
      // IMessageFilter
      public bool PreFilterMessage(ref Message m)
      {
        bool handled = false;

        if(IsActive())
        {
          int pos = LibUser32.GetMessagePos();

          WINMSG message = new WINMSG();
          message.hwnd = m.HWnd;
          message.message = m.Msg;
          message.wParam = m.WParam;
          message.lParam = m.LParam;
          message.time = LibUser32.GetMessageTime();
          message.x = (short)pos;
          message.y = (short)(pos >> 16);

          TwMSG msgCode = 0;

          if(fTwain.ProcessEvent(fIdent, ref message, ref msgCode))
          {
            switch(msgCode)
            {
              case TwMSG.XFerReady:
                {
                  bool success = TransferPictures();

                  if((success == false) || (fSettings.ShowSettingsUI == false))
                  {
                    Stop(); // Need this only if UI is not enabled
                  }
                }
                break;

              case TwMSG.CloseDS:
              case TwMSG.CloseDSOK:
              case TwMSG.CloseDSReq:
                {
                  Stop(); // This happens only if UI is enabled
                }
                break;

              case TwMSG.DeviceEvent:
                break;

              default:
                break;
            }

            handled = true;
          }
        }

        return handled;
      }