How can i check for specific window name while enumerating EnumChildProc in WinApi? - c++

So far i have been using GetClassName() to get a window handle with the class name that interested me while enumerating with EnumChildProc() but right now i am in situation where plenty of HWND's use the same classname so only way to identify my window i assume would be with its name which is unique.
So while i am enumerating i was thinking to use something like...
If getwindowname() == what i need... but i have no idea what function can i use for this, is there a function like getwindowname() that i can use in this enumeration?

GetWindowText ?

this.. worked
TCHAR winname[MAX_PATH];
long lenght;
HWND hwndineed;
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) {
lenght = SendMessage(hwnd, WM_GETTEXT, 99, (LPARAM)winname);
if(wcscmp(winname, _T("caption i needed")) == 0)
{
hwndineed= hwnd;
return FALSE; // end enumeration
}
}

Related

Win32/Qt - Can one Enumerate all the toplevel windows belonging to the calling process?

I want to detect all the top-level windows in order to send messages to it's Descendants.
How can I do that?
The following code seems to not be detecting Qt top level window, I don't know why.
static BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM lParam) {
WORD far wndProcessID;
WORD currentProcessID = GetCurrentProcessId();
std::vector<HWND> *topWindowList = (std::vector<HWND> *)lParam;
if (topWindowList != NULL &&
GetWindowThreadProcessId(hwnd, NULL) == currentProcessID) {
printf("Found a top level window");
fflush(stdout);
topWindowList->push_back(hwnd);
}
return TRUE;
}
void enumAllDesktopChildWindow() {
std::vector<HWND> topWindowList;
EnumChildWindows(GetDesktopWindow(), EnumWindowsProc, LPARAM(&topWindowList));
}
First, the GetWindowThreadProcessId API returns a Thread ID (TID) not a Process ID (PID)
Second, if you want to enumerate all top-level Windows, you should use EnumWindows, not EnumChildWindows. If you want to use EnumChildWindows, pass NULL as the first parameter.

Accessing multiple Editboxes in MFC

I am writing a MFC program in which I have a a lot of Editboxes and I want to get all their text values and put them in a container. How can I achieve this without writing a line for each ID. I'm using this code for each ID:
CEdit *edit;
edit = reinterpret_cast<CEdit *>(GetDlgItem(IDC_NAME1));
But if I use that method I would have to write it 45 times. That doesn't seem right.
Is there a way of getting all the Editboxes in a container so I can use them that way or something like that?
You can certainly create an array (or other container) or pointers to CEdit: CEdit edits[45]; If the values of IDC_NAME1 through IDC_NAME45 are contiguous, you can just do something like:
for (int i=0; i<45; i++)
names[i] = reinterpret_cast<CEdit *>(GetDlgItem(IDC_NAME1 + i));
If those identifiers may not be contiguous, then you can put them in an array, and just index into that array as needed.
One caution: unless they're something like a grid of otherwise nearly identical edit controls, 45 on a screen may well be a bit much. If they are like a grid, you might want to look at one of the many available grid controls instead.
You do not have to use controls IDs.
Use EnumChildWindows and get test only for edit controls. Snippet follows.
Add following in dialog’s header:
afx_msg LRESULT OnFoundEdit(WPARAM wParam, LPARAM lParam);
And this to cpp:
#define WM_U_FOUND_EDIT WM_APP + 0x100
BEGIN_MESSAGE_MAP(CEditCtrlFishingDlg, CDialog)
ON_MESSAGE(WM_U_FOUND_EDIT, OnFoundEdit)
.
.
.
.
END_MESSAGE_MAP()
Write this line in the place you want to start edit text collection:
EnumChildWindows(m_hWnd, EnumChildProc, (LPARAM)m_hWnd);
Enum child procedure:
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
CString csBuffer;
LPTSTR pBuf = csBuffer.GetBufferSetLength(MAX_PATH);
GetClassName(hwnd, pBuf, MAX_PATH);
csBuffer.ReleaseBuffer();
if(!csBuffer.CompareNoCase(_T("edit")))
{
SendMessage((HWND)lParam, WM_U_FOUND_EDIT, 0, (LPARAM)hwnd);
}
return TRUE;
}
and the handler:
LRESULT YourDlg::OnFoundEdit(WPARAM wParam, LPARAM lParam)
{
CWnd *pWnd = FromHandle((HWND)lParam);
CString csTxt;
pWnd->GetWindowText(csTxt);
// do what you need with text here
return 0;
}

Why is my mousehook inside dll unable to recognize simple BOOL?

#pragma data_seg(".shared") // ".shared" is defined in exports.def to allow
HWND m_hHwndMouse = 0;
HHOOK m_hHookMouse = 0;
BOOL hover = true;
#pragma data_seg()
this section is managed with .def file
EXPORTS
SetValuesMouse
MouseProc
SECTIONS
.shared READ WRITE SHARED
I am directing this dll(adding values) + trying to change the BOOL hover = true; by changing this value trough autoit dll call
DllCall(".\simplemousehook.dll", "int", "SetValuesMouse", "hwnd", $main, "hwnd", $hhMouse[0], "BOOL", 0)
this simply makes the
HWND m_hHwndMouse = 0;
HHOOK m_hHookMouse = 0;
from the shared section changed in the function SetValuesMouse
void WINAPI SetValuesMouse(HWND hWnd, HHOOK hk, BOOL ho)
{
m_hHwndMouse = hWnd;
m_hHookMouse = hk;
hover = ho;
}
Ok, so now my mouse hook inside DLL knows where to send messages(m_HWNDMOuse)
LRESULT CALLBACK MouseProc( int nCode, WPARAM wParam, LPARAM lParam )
{
case WM_MOUSEMOVE:
wParm = AU3_WM_MOUSEMOVE;
PostMessage(m_hHwndMouse, wParm,(WPARAM)( (MOUSEHOOKSTRUCT*) lParam )->hwnd, LPARAM(fromp));
This works perfectly fine and my gui(which is hHwndMouse ) normally receives the message from the dll, so obviously i am able to change it trough setvaluesmouse function
BUT...
if i do this
if (hover = 1)
{
.. do something here
}
and prior to that i change the BOOL hover to 0 trough the function SetValuesMouse the dll ignores that hover is 0 and "does something here"...
Why is it unable to read the bool properly and ignore the ...do something here...?
I know i am probably making totally stupid mistake here but i can't help it but to ask for help.
You are missing an = in the if condition, it should be if (hover == 1).
One = sign in C means assignment, when you incorrectly perform that if-check, you're actually mutating the value of hover and triggering the event unexpectedly.
== is the equality operator in C.

Cannot add items to Win32 List Box Control

Backstory: I'm creating an Extension for Game Maker, a popular game development suite. An extension is a DLL that adds new functions to the built in scripting language, but is written in C or Pascal or whatever. Typically, it's used to allow games to use external libraries.
In my case, I'm adding FMOD support. This isn't relevant. What's relevant is that for debugging purposes, I am also adding a dialog that I display at runtime that shows me the internal state of my library. I need help with this window. I have literally done absolutely no raw Win32 forms programming before today (.NET WinForms 4eva), so I'm probably doing something really clueless.
Anyway. I have a listbox, and I want to add things to the list box, but when I try to add them, it fails. My code:
extern DebugDialog * debugDialog;
DebugDialog::DebugDialog(HWND owner, HINSTANCE hInst) {
this->hWnd = 0;
HWND hWnd = CreateDialogParam(hInst,
MAKEINTRESOURCE(IDD_DEBUGDIALOG),
owner,
DialogProc,
reinterpret_cast<LPARAM>(this));
ShowWindow(hWnd, SW_SHOW);
}
DebugDialog::~DebugDialog(void) {
DestroyWindow(this->getHWnd());
debugDialog = NULL;
}
BOOL CALLBACK DebugDialog::DialogProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
DebugDialog * self;
if(message == WM_INITDIALOG) {
self = reinterpret_cast<DebugDialog *>(lParam);
self->hWnd = hWnd;
SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(self));
} else {
self = reinterpret_cast<DebugDialog*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
}
if(self) {
return self->HandleMessage(message, wParam, lParam);
} else {
return FALSE;
}
}
BOOL DebugDialog::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch(uMsg) {
case WM_INITDIALOG:
MessageBox(this->getHWnd(), "Okay!", "Debug", 0);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam)) {
case ID_CLOSE:
case IDOK:
case IDCANCEL:
delete this;
return TRUE;
default:
return FALSE;
}
return TRUE;
}
return false;
}
void DebugDialog::loadedSound(FMODGM_Sound * sound) {
HWND hwndList = GetDlgItem(this->getHWnd(), IDC_LIST);
LPARAM sound_text = (LPARAM)sound->file.c_str();
LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, sound_text);
SendMessage(hwndList, LB_SETITEMDATA, lResult, (LPARAM)sound);
}
DebugDialog is a simple class that wraps the window, and lets me manipulate it from the outside. Basically, at some other point, I do this:
debugWindow = new DebugDialog(owner, hInst);
And then as I execute and do interesting things, I do this:
FMODGM_Sound * sound = ...;
if(debugWindow) debugWindow->loadedSound(sound);
In loadedSound, I send a message to the list box saying "Hey, here's an item. Go ahead and make with the adding.", and it doesn't return an error. However, it also doesn't add anything to the box. It returns 0 each and every time I call it. According to the documentation, 0 means that it added an item, whose index is 0. However, that item doesn't exist.
I have a theory as to why it's not working. I have no control over the message pump that Game Maker runs, so if it's doing anything funky, I don't know about it, nor can I change it. That said, everything else about the dialog works, including moving it, clicking on my Close button, and drawing the marquee thing inside the listbox with the mouse.
Someone, please tell me what I'm doing horribly wrong :(
Edit: Someone asked about the FMODGM_Sound struct, so here it is:
struct FMODGM_Sound {
FMOD::Sound * sound;
std::vector<FMOD::Channel*> channels;
std::string file;
public:
FMODGM_Sound() {
sound = NULL;
}
};
Nothing particularly fancy.
Can you show a declaration of FMODGM_Sound structure and file field?
What happen if replace
LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, sound_text);
with ?
LRESULT lResult = SendMessage(hwndList, LB_ADDSTRING, NULL, "some constant text");
Does the your DLL compiled as Unicode version or multibytes version?
If it is Unicode, the sound_text should be an Unicode string. I guess the file is a std::string, so file.c_str() will return a multibytes string.
I had a very similar problem, which was solved. Basically, you have to pass it as a c-style string instead (str.c_str()). Though I am a complete newbie, after googling around how to use that, it worked.
Though the code I'm using serves an entirely different function than yours, maybe it will be a good example.
int i = res->getInt("ID");
std::string str = boost::lexical_cast<std::string>(i);
char *cstr = new char[10];
strcpy_s(cstr, 10, str.c_str());
SendDlgItemMessage(hwnd, IDC_lbList, LB_ADDSTRING, 0, (LPARAM)cstr);
EDIT: Wow, I did not even look at the dates. I'm a necromancer...

How to get readable classname and title from HWND handle? in WinApi c++

I am using the following enumchild proc to get hwnd of each window, the problem is that i am unable to somehow detect any info from each hwnd so i can do what i want with the ones that are detected as the ones i need.
For example, how could i get window class name and the title of each window in the enum bellow?
I tried something like..
EDITED: copy pasted(if that helps)
TCHAR cName[MAX_PATH];
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam) {
TCHAR cName[MAX_PATH];
GetClassName(hwnd, cName, _countof(cName));
cout << cName << endl;
return TRUE;
}
int _tmain(int argc, _TCHAR* argv[])
{
HWND hwnd = FindWindow(0, TEXT("reference"));
EnumChildWindows(hwnd, EnumChildProc, 0);
system("PAUSE");
return 0;
}
It just returns the hexadec handle info and every single time it is same, shouldnt the GetClassName func change the cName into new handle each time?
Also GetClassName function returns number of chars written to cName, i dont really see how this is useful to me? I need to get my cName in some readable format so i can do something like
if(className == TEXT("classnameiamlookingfor" && hwndtitle = TEXT("thetitlethatinterestsme") DOSOMETHINGWITHIT();
But all i get here is hexadec mess.
Isn't it Unicode build?
Check again with below:
TCHAR className[MAX_PATH];
GetClassName(hwnd, className, _countof(cName));
_tprintf(cName);