泛型std::函数成员

Generic std::function member

本文关键字:成员 函数 泛型 std      更新时间:2023-10-16

我有一个使用EnumWindows的类。因为这需要一个回调,所以我把它包装成一个漂亮的小工具类,类似于这样:

Class Tools
{
public:
    template<typename WinFunctor>
    std::vector<HWND> FindWindow(WinFunctor Functor);
private:
    BOOL EnumWindowMsgProc(HWND hWnd);
    static BOOL CALLBACK FreeWndProc(HWND hWnd, LPARAM lParam)
    {
        Tools* pThis = (Tools*)lParam;
        return pThis->EnumWindowMsgProc(hWnd);
    }
    std::vector<HWND> m_Windows;
    /*Need to store WinFunctor Here*/
}
BOOL Tools::EnumWindowMsgProc(HWND hWnd)
{
    if(/*Call WinFunctor Member here*/)
    {
        m_Windows.push_back(hWnd);
    }
    return TRUE;
}
template<typename WinFunctor>
std::vector<HWND> Tools::FindWindow(WinFunctor Functor)
{
    m_Windows.clear();
    EnumWindows(FreeWndProc, (LPARAM)this);
    return m_Windows;
}
/*Windows Callbacks must be free (not a class member), 
so I define a static method (free) and forward to my    
member function(not free)*/

WinFunctor示例:

bool EnumByWindowName(HWND WinHandle,const std::wstring& WinName)
{
    wchar_t Temp[1024]{L''};
    GetWindowText(WinHandle, Temp, 1024);
    if (std::wstring(Temp).compare(WinName.c_str()) == 0)
        return true;
    return false;
}

期望的接口示例

Tools ToolInst;
auto Windows=ToolsInst.FindWindow(EnumByWindowName(std::placeholders::_1,"Notepad-Untitled"));

我需要以某种方式将Functor存储为成员,以便我可以稍后在回调中调用它,但是我不能只是模板类,因为这将要求我每次想要搜索不同的窗口时创建一个新的工具实例(并且工具类包含比EnumWindows更多的函数)。Functor必须始终接受hWnd,但随后可以使用它想要的任何方式对该数据进行操作,并可以传递所需的其他参数(例如WindowName sting)。是否可以存储函子而不必每次都创建类的新实例。感谢您的帮助

解决方案

Class Tools
{
public:
    typedef std::function<bool(HWND)> WinFunctor;
    std::vector<HWND> FindWindow(const WinFunctor& Functor);
private:
    BOOL EnumWindowMsgProc(HWND hWnd);
    static BOOL CALLBACK FreeWndProc(HWND hWnd, LPARAM lParam)
    {
        Tools* pThis = (Tools*)lParam;
        return pThis->EnumWindowMsgProc(hWnd);
    }
    std::vector<HWND> m_Windows;
    WinFunctor m_WinFunctor;
}
BOOL Tools::EnumWindowMsgProc(HWND hWnd)
{
    if(m_WinFunctor(hWnd))
        m_Windows.push_back(hWnd);
    return TRUE;
}
std::vector<HWND> Tools::FindWindow(const WinFunctor& Functor)
{
    m_Windows.clear();
    m_WinFunctor=Functor;
    EnumWindows(FreeWndProc, (LPARAM)this);
    return m_Windows;
}

接口:

auto Windows = m_Tools.FindParentWindow(std::bind(&WinEnumFunctors::EnumByWindowName, std::placeholders::_1, L"Some WindowName"));