无法通过回调永久更改类的状态

时间:2018-07-28 14:52:42

标签: c++ winapi callback state

这是我要使用此 WinAPI 函数执行的操作:

EnumWindows(
    _In_ WNDENUMPROC lpEnumFunc,
    _In_ LPARAM      lParam
);

从此类FeedWindowsHandlesList的{​​{1}}函数(在此简化)中调用它。

WinFinder

class WinFinder { WinFinder(); ~WinFinder(); std::vector<HWND> winHandles; void FeedWindowsHandlesList(); }; 函数调用FeedWinDowsHandlesList,依次为找到的每个句柄触发一个回调。此处,EnumWindows被添加到正在调用的HWND实例的winHandles成员中。我面临的挑战是访问调用WinFinder实例的成员。我尝试了两种方法,它们都以相同的方式失败。


方法1 :(由SO post启发而来)

呼叫功能:

WinFinder

回调(简体):

void WinFinder::FeedWindowsHandlesList() {
    LPARAM param = reinterpret_cast<LPARAM>(this);
    EnumWindows(EnumWindowsProc, param);
}

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) { WinFinder thisWF = *(reinterpret_cast<WinFinder*>(lParam)); thisWF.winHandles.push_back(hWnd); return TRUE; } 级别的断点让我看到发生了添加,并且push_back的大小达到了vector。但是下次我进入回调时,1为空。 vector完成后,EnumWindows完全为空。


我也这样尝试过

方法2:

呼叫功能:

vector

回调:

void WinFinder::FeedWindowsHandlesList() {
    WinFinder * wf =this;
    EnumWindows(EnumWindowsProc,(LPARAM)wf);    
}

那么,您认为我如何做才能在不丢失任何内容的情况下访问调用BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) { WinFinder thisWF= *((WinFinder*)lParam); thisWF.winHandles.push_back(hWnd); return TRUE; } 的{​​{1}}类的vector成员?

1 个答案:

答案 0 :(得分:2)

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    // WinFinder thisWF = *(reinterpret_cast<WinFinder*>(lParam));
    // in the above line you're creating a copy of the object pointed to by lParam
    // what you want instead is just a pointer of type WinFinder to simplify access:
    WinFinder *thisWF = reinterpret_cast<WinFinder*>(lParam);
    // thisWF.winHandles.push_back(hWnd);
    // since thisWF is a pointer you have to use -> to access the members:
    thisWF->winHandles.push_back(hWnd);
    return TRUE;
}

计划B:使用参考(由@SoronelHaetir建议):

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    WinFinder &thisWF = *reinterpret_cast<WinFinder*>(lParam);
    thisWF.winHandles.push_back(hWnd);
    return TRUE;
}

最小示例:

#include <iostream>
#include <vector>
#include <Windows.h>

struct WinFinder
{
    std::vector<HWND> winHandles;
    void FeedWindowsHandlesList();
};

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
    WinFinder *thisWF = reinterpret_cast<WinFinder*>(lParam);
    thisWF->winHandles.push_back(hWnd);
    return TRUE;
}

void WinFinder::FeedWindowsHandlesList()
{
    LPARAM param = reinterpret_cast<LPARAM>(this);
    EnumWindows(EnumWindowsProc, param);
}

int main()
{
    WinFinder wf;
    wf.FeedWindowsHandlesList();

    for (auto const & w : wf.winHandles)
        std::cout << w << '\n';
}