2015-05-23 63 views
0

我有一個使用EnumWindows的類。由於需要一個回調我包裹它變成一個不錯的小工具類與此類似:一個WinFunctor的通用std ::函數成員

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)*/ 

實施例:所需界面的

bool EnumByWindowName(HWND WinHandle,const std::wstring& WinName) 
{ 
    wchar_t Temp[1024]{L'\0'}; 
    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存儲爲成員,以便稍後在回調中調用它,但是我不能只爲模板創建模板,因爲這需要我每次創建新工具實例時都需要t o尋找一個不同的窗口(和工具類擁有比EnumWindows更多的功能)。Functor必須總是接受一個hWnd,但是可以使用任何想要的方式處理這些數據,並且可以傳遞其他需要作用的參數(如WindowName sting)。無論如何存儲函子並且不必每次創建類的新實例。感謝您的幫助

+0

使用'的std :: function'和'的std :: bind()的'可能會派上用場對於這樣的用例。 –

+0

不是'std :: function' generic *足夠*? –

+0

如果我知道調用者將要使用的函數,並且他們只使用一種類型的函數,那麼是的,我可以單獨使用std ::函數,但我無法弄清楚如何接受一般函子。 IE仿函數應該做的「這是一個hWnd,你告訴我如何確定它是否是正確的,並將它推入我的向量」 –

回答

1

解決方案作爲發表的Piotr S.

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"));