【问题标题】:Is there a way I could cancel and restart a function in my COM object?有没有办法可以取消并重新启动 COM 对象中的函数?
【发布时间】:2015-11-22 04:35:22
【问题描述】:

我的软件现在如何工作:

我有一个 C++ ATL 对象和一个 VB6 客户端应用程序。 COM 对象有一个函数Find,它搜索数据库并通过回调函数报告匹配。当用户使用其 Change 事件将文本输入到 TextBox 时,我从 VB6 调用 Find 函数,并传递文本和回调函数的地址。回调函数将匹配项输出到 ListBox,进行DoEvents 调用,并返回一个指示是否应继续搜索的值。

我要完成的工作:

当用户在搜索已经运行时更改搜索字段中的文本时,我想取消正在运行的搜索,清空 ListBox,并使用更新后的文本开始一个新的搜索。

我遇到的问题:

因为 TextBox 的 Change 事件在回调函数中的 DoEvents 调用期间被触发,所以在回调可以返回“取消”代码之前,新搜索会堆叠在第一个搜索之上。当这个新的搜索有一个匹配时,它会调用回调,取回取消代码,然后结束,此时恢复之前的搜索。

我怎么可能在自动开始新搜索之前取消旧搜索?

代码:

Private Sub txtFind_Change()
    lvResults.ListItems.Clear
    m_customer.CancelFind #' Not useful
    frmMain.appData.Licfile.Find(txtFind.Text, AddressOf FindCallback, ObjPtr(m_customer))
End Sub

Public Function CancelFind()
    If m_bFindRunning Then: m_bCancelFind = True
End Function

Public Function FindCallback(ByVal foundItem As Boolean, _
                             ByVal finished As Boolean, _
                             ByVal index As Long) As Long
Dim record As zLicFileRecord
Dim resultstr As String
Dim error As Long
    If foundItem Then
        frmMain.appData.Licfile.Read(index, record)
        RaiseEvent SearchResult(index, record)
        DoEvents
    Else
        If Not finished Then
            RaiseEvent SearchProgress(index, frmMain.appData.Licfile.RecordCount)
            DoEvents
        Else
            RaiseEvent SearchFinished
        End If
    End If
    If m_bCancelFind Then
        FindCallback = 1
        m_bCancelFind = False
    End If
End Function


STDMETHODIMP CzLicenseFile::Find(BSTR  find, 
                                 LONG  callbackFunction /* fnFindCallback */,
                                 LONG  context,
                                 LONG* win32Error)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    CHECK_PTR(win32Error);

    if (!callbackFunction)
    {
        *win32Error = ERROR_NO_CALLBACK_ACTIVE;
        RETURN_OK;
    }

    fnFindCallback pfnCallback = reinterpret_cast<fnFindCallback>(callbackFunction);

    try 
    {
        DWORD recordCount;
        get_RecordCount(reinterpret_cast<LONG*>(&recordCount));
        if (recordCount == static_cast<DWORD>(-1))
        {
            *win32Error = ERROR_READ_FAULT;
            RETURN_OK;
        }

        QuickMatcher matcher(std::wstring(find, ::SysStringLen(find)));

        for (size_t i = static_cast<size_t>(startIndex); i < recordCount; ++i)
        {
            LicenseFileRecord const& item = m_fileBuf.Get(i);  

            bool match = matcher.match(item);

            if (match)
            {
                if (pfnCallback)
                {
                    LONG result = pfnCallback(VTRUE, VFALSE, i, context);
                    if (result != 0)
                    {
                        break;
                    }
                }
            }
            else if (i % 1000 == 0)
            {
                if (pfnCallback)
                {
                    LONG result = pfnCallback(VFALSE, VFALSE, i, context);
                    if (result != 0)
                    {
                        break;
                    }
                }
            }
        }    
    }
    catch (AutoWinError const& e)
    {
        *win32Error = e.error();
        RETURN_OK;
    }

    if (pfnCallback)
    {
        pfnCallback(VFALSE, VTRUE, -1, context);
    }

    *win32Error = ERROR_SUCCESS;
    RETURN_OK;
}

【问题讨论】:

  • 你的帖子太宽泛了。
  • 不看代码就无法回答你的问题。
  • 我已经删除了 C++ 标签,因为 if 显然不适用于这里。请适当地标记您的帖子。

标签: com callback vb6 activex


【解决方案1】:

我用一个函数和一个Timer 对象解决了这个问题。 txtFind_Change 现在调用这个函数:

Public Sub StartSearch()
Dim error As Long
    lvResults.ListItems.Clear
    If Not m_customer Is Nothing Then
        If Not m_customer.FindRunning Then
            error = frmMain.appData.Licfile.Find(txtFind.Text, AddressOf FindCallback, ObjPtr(m_customer))
        Else
            m_customer.CancelFind
            TimerSearchRestart.Interval = 50
            TimerSearchRestart.enabled = True
        End If
    End If
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 2020-03-03
    相关资源
    最近更新 更多