【发布时间】: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 显然不适用于这里。请适当地标记您的帖子。