Passing a pointer as LPARAM to EnumWindowsProc ..... How?

I have a question using the EnumWindows function.

What I'm trying to do:

I want to call EnumWindows and subsequently my EnumVisiWindowTitles function. EnumVisiWindowTitles should get each handle and title of all visible AND STORE THESE windows in the "lumpi" structure.

Later basically I want to access "lumpi" and find a specific signature string.

My problem is that I am unable to pass a pointer pointing to lumpi[0] on EnumVisiWindowTitles as LPARAM .

Perhaps my brilliant plan is not so bright, so if you could help me or show me a solution that performs the same task, I would be very happy for your help!

I have a main view:

 int _tmain(int argc, _TCHAR* argv[]) { MYHANDLES lumpi[10]; EnumWindows(EnumVisiWindowTitles, (LPARAM) &lumpi[0]); blabla } 

Myhandles is defined as:

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

And my EnumWindowsProc looks like this:

 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 } 

I get the expression "Expression must have a pointer to the type of object" specified in each [0]

Arne

+4
source share
3 answers

First of all, change your call to EnumWindows() with the following:

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

The C ++ standard requires you to use the & character to pass a pointer to a function. reinterpret_cast<>() tells the compiler to pass a pointer to your MYHANDLES array as is in the LPARAM EnumWindows() parameter.

Then in your callback:

 BOOL CALLBACK EnumVisiWindowTitles(HWND hWnd, LPARAM ptr) { MYHANDLES* lumpi = reinterpret_cast<MYHANDLES*>(ptr); // ... } 

Then we again return the original pointer using reinterpret_cast<>() . You can then act on lumpi as if it were an array, because it is actually an array.

This question, I see other problems. You obviously use the first item to store the bill, which is strange. Just put this in another struct .

 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; } 

Please note that this will contain up to 10 windows. Why not use std::vector instead, which will dynamically grow when elements are added to it?

+8
source

You need to cast a pointer. LPARAM is defined as a long 32-bit and __int64 on a 64-bit basis, so it's ok to point to a pointer to and from LPARAM.

Moreover, you really need to use the small orientation of the object. There is absolutely no need to maintain your own counters or limited memory management, etc.

 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(); } 

A good, simple interface, automatic memory management - an epic victory.

+3
source

LPARAM is not a pointer - you need to use it:

 BOOL CALLBACK EnumVisiWindowTitles(HWND hWnd, LPARAM lumpi) { MYHANDLES * mh = (MYHANDLES *) lumpi; .... mh[mh[0].count].title[n] = String[n] } 

I can not talk about the semantic correctness of this.

+1
source

Source: https://habr.com/ru/post/1332348/


All Articles