我想将一些DropHandler代码提取到一个单独的函数中,但是不知道在使用接口指针或一般C ++时该怎么做。我只想使用单独的功能获取DragEnter
中的第一项。
HRESULT drop_handler::GetFirstItem(IDataObject* p_data_obj, IShellItemArray* items, IShellItem* first_item)
{
HRESULT hr = SHCreateShellItemArrayFromDataObject(p_data_obj, IID_PPV_ARGS(&items));
if (hr != ERROR_SUCCESS)
{
return E_INVALIDARG;
}
DWORD item_count;
items->GetCount(&item_count);
if (item_count != 1)
{
items->Release();
return E_INVALIDARG;
}
hr = items->GetItemAt(0, &first_item);
if (hr != ERROR_SUCCESS)
{
items->Release();
return E_INVALIDARG;
}
return ERROR_SUCCESS;
}
HRESULT drop_handler::DragEnter(IDataObject* p_data_obj, DWORD gtf_key_state, POINTL pt, DWORD* pdw_effect)
{
IShellItemArray* items = nullptr;
IShellItem* dragged_item = nullptr;
HRESULT hr = GetFirstItem(p_data_obj, items, dragged_item);
if (hr != ERROR_SUCCESS)
{
return E_INVALIDARG;
}
//...use dragged_item
此代码尝试会使Explorer崩溃。我不确定应该使用哪种类型的函数签名和指针。
修改:每个安德斯的固定答案
HRESULT drop_handler::GetFirstItem(IDataObject* p_data_obj, IShellItemArray*& items, IShellItem*& first_item)
{
HRESULT hr = SHCreateShellItemArrayFromDataObject(p_data_obj, IID_PPV_ARGS(&items));
if (hr != ERROR_SUCCESS)
{
return E_INVALIDARG;
}
DWORD item_count;
hr = items->GetCount(&item_count);
if (hr != ERROR_SUCCESS || item_count != 1)
{
items->Release();
return E_INVALIDARG;
}
hr = items->GetItemAt(0, &first_item);
if (hr != ERROR_SUCCESS)
{
items->Release();
return E_INVALIDARG;
}
return ERROR_SUCCESS;
}
HRESULT drop_handler::DragEnter(IDataObject* p_data_obj, DWORD gtf_key_state, POINTL pt, DWORD* pdw_effect)
{
IShellItemArray* items;
IShellItem* dragged_item;
HRESULT hr = GetFirstItem(p_data_obj, items, dragged_item);
if (hr != ERROR_SUCCESS)
{
return E_INVALIDARG;
}
//...use dragged_item
答案 0 :(得分:1)
您对IShellItemArray*
和IShellItem*
的处理是错误的。 GetFirstItem
将在失败时释放IShellItemArray*
,但在成功时您将泄漏它,并且first_item
将永远不会正确返回。 items
中的first_item
和DragEnter
将永远无效。
IShellItemArray*
应该是GetFirstItem
中的局部变量。
IShellItem* first_item
参数必须为IShellItem** first_item
或IShellItem*& first_item
,以便指针值正确返回给调用者。
您永远不会检查GetCount
的返回值。
由于指针存在问题,您可能需要在使用它们之前添加一些assert
来验证接口指针是否为非空。