将指针作为LPARAM传递给EnumWindowsProc .....如何?

时间:2010-12-16 12:56:39

标签: c++

我有一个使用EnumWindows函数的问题。

我想做什么:

我想调用EnumWindows,然后调用EnumVisiWindowTitles函数。 EnumVisiWindowTitles将得到所有可见窗口的每个句柄和标题,并将它们存储在“lumpi”结构中。

稍后在主要内容我想访问“lumpi”并搜索特定的字幕字符串。

我的问题是我无法将指向lumpi[0]的指针传递给EnumVisiWindowTitles LPARAM

也许我的genaral计划不是那么明亮,所以如果你们中的任何人可以帮助我,或者告诉我一个执行相同任务的解决方案,我将非常高兴你的帮助!

我的主要看起来像这样:

int _tmain(int argc, _TCHAR* argv[])

{
 MYHANDLES lumpi[10];
 EnumWindows(EnumVisiWindowTitles, (LPARAM) &lumpi[0]);

blabla
}

Myhandles定义为:

#ifndef handlestruct_H
#define handlestruct_H
struct MYHANDLES
 { public:
  MYHANDLES();  //MYHANDLEconstructor.cpp
  HWND haendchen;
  int count;
  char title[200];
 };

#endif

我的EnumWindowsProc看起来像这样:

using namespace std;
 BOOL CALLBACK EnumVisiWindowTitles(HWND hWnd, LPARAM lumpi) 
{  

 TCHAR String[200]; 

 if (!hWnd)
  return TRUE;// Not a window, return TRUE to Enumwindows in order to get the next handle
 if (!::IsWindowVisible(hWnd))
  return TRUE;// Not visible, return TRUE to Enumwindows in order to get the next handle 
 if (!SendMessageW(hWnd, WM_GETTEXT, sizeof(String), (LPARAM)String))
  return TRUE;// No window title, return TRUE to Enumwindows in order to get the next handle

 lumpi[lumpi[0].count].haendchen = hWnd;

   for (int n=0; n<201; n++)//copy the caption to lumpi struct
    {
     lumpi[lumpi[0].count].title[n] = String[n];
    }

   lumpi[0].count++;  //Increase counter

   wcout<<String<<'\n';
   return true;   //return true to get next handle   
}

我在每个[0]

处得到一个“表达必须有对象类型的指针”

·阿尔

3 个答案:

答案 0 :(得分:9)

首先,将您的通话更改为EnumWindows()

int _tmain(int argc, _TCHAR* argv[])
{
    MYHANDLES lumpi[10];
    EnumWindows(&EnumVisiWindowTitles, reinterpret_cast<LPARAM>(lumpi));
    // ...
}

标准C ++要求您使用&符号传递指向函数的指针。 reinterpret_cast<>()告诉编译器将MYHANDLES数组的指针按原样传递给LPARAM的{​​{1}}参数。

然后,在你的回调中:

EnumWindows()

然后我们再次使用BOOL CALLBACK EnumVisiWindowTitles(HWND hWnd, LPARAM ptr) { MYHANDLES* lumpi = reinterpret_cast<MYHANDLES*>(ptr); // ... } 检索原始指针。然后,您可以对reinterpret_cast<>()采取行动,就像它是一个数组一样,因为它实际上是一个数组。

这个问题有助于,我看到其他问题。你显然使用第一个元素来存储计数,这很奇怪。只需将其放入另一个lumpi

struct

请注意,这最多只能容纳10个窗口。为什么不使用struct MyHandles { public: MyHandles(); HWND haendchen; char title[200]; }; struct ListOfMyHandles { public: int count; MyHandles handles[10]; }; int _tmain(int argc, _TCHAR* argv[]) { ListOfMyHandles lumpi; ::EnumWindows(&EnumVisiWindowTitles, reinterpret_cast<LPARAM>(&lumpi)); // ... } BOOL CALLBACK EnumVisiWindowTitles(HWND hWnd, LPARAM ptr) { ListOfMyHandles* lumpi = reinterpret_cast<ListOfMyHandles*>(ptr); if(lumpi != 0 && lumpi->count < 10) // Avoid going past the array { lumpi->handles[lumpi.count] = //... // ... ++lumpi->count; return TRUE; } return FALSE; } 代替,它会在向其添加元素时动态增长?

答案 1 :(得分:3)

你需要施放指针。 LPARAM定义为32位长和64位__int64,因此将指针转换为LPARAM并再次返回是完全可以的。

更重要的是,你真的需要在这里使用一个小的面向对象。绝对没有必要维护自己的计数器或有限的内存管理等。

typedef std::basic_string<TCHAR> tstring;
class Handles {
public:
    struct window_data {
        tstring caption;
        HWND handle;
    };
private:
    std::vector<window_data> stuff;
    BOOL add_window(HWND hwnd) {
        TCHAR String[200] = {0};
        if (!hwnd)
            return TRUE;// Not a window, return TRUE to Enumwindows in order to get the next handle
        if (!::IsWindowVisible(hwnd))
            return TRUE;// Not visible, return TRUE to Enumwindows in order to get the next handle 
        LRESULT result = SendMessageW(hwnd, WM_GETTEXT, sizeof(String), (LPARAM)String);
        if (!result)
            return TRUE;// No window title, return TRUE to Enumwindows in order to get the next handle
        window_data data;
        data.handle = hwnd;
        for(int i = 0; i < result; i++)
            data.caption.push_back(String[i]);
        stuff.push_back(data);
        return TRUE;
    }
    static BOOL CALLBACK EnumWindowsProcCallback(HWND hwnd, LPARAM lparam) {
        Handles* ptr = reinterpret_cast<Handles*>(lparam);
        return ptr->add_window(hwnd);
    }
public:
    Handles& enum_windows() {
        stuff.clear();
        if(!EnumWindows(EnumWindowsProcCallback, reinterpret_cast<LPARAM>(this))) {
            // Error! Call GetLastError();
        }
        return *this;
    }
    std::vector<window_data>& get_results() {
        return stuff;
    }
};

int _tmain(int argc, TCHAR* argv[]) {
    std::vector<Handles::window_data> results = Handles().enum_windows().get_results();
}

漂亮,简单的界面,自动化的内存管理 - 史诗般的胜利。

答案 2 :(得分:1)

LPARAM不是指针 - 你需要投射它:

BOOL CALLBACK EnumVisiWindowTitles(HWND hWnd, LPARAM lumpi) {

MYHANDLES * mh = (MYHANDLES *) lumpi;
....
mh[mh[0].count].title[n] = String[n]
}
但是,我不能说出这种语义的正确性。