Hello,

I am trying to get the properties of a Microsoft's Notepad.exe window. I have an instance of this application running when I execute the code below.

#include <iostream>
#include <windows.h>

using namespace std;

BOOL CALLBACK PropEnumProcEx(HWND hwnd, LPTSTR lpszString, HANDLE hData, ULONG_PTR dwData) {
  cout << "Property Label: " << lpszString << "." << endl;
  return true;
}

int main()
{
    HWND hNote = FindWindow("Notepad", NULL);
    cout << "Notepad's handle: " << hNote << endl;
    EnumPropsEx(hNote, PropEnumProcEx, 0);
    cout << "Done" << endl;
    return 0;
}

The output is:

Notepad's handle: 0x7e0b7e
Property Label:

Then i receive a "properties.exe has encountered a problem and needs to close. We are sorry for the inconvenience." Windows error message.

{P.S. my program is called properties.exe}

If I don't have a reference to lpszString in the callback function then the code executes as expected through to the end. I suspect I am not using the pointer of the string correctly...?

If someone could shed some light that would be appreciated.

Thanks,

Dani AI

Generated

Good catch, — and ’s NULL-check advice was a sensible first step. The crash happens because EnumPropsEx hands you either a pointer to a NUL-terminated name or a small integer packed into a pointer (an atom). Streaming that integer value with cout makes the runtime try to read from a low, invalid address and causes an access violation.

Prefer the standard resource test and a portable atom check rather than relying on HIWORD. On 64-bit builds and when using the Unicode macros, pointer-sized checks are required. Use IS_INTRESOURCE() (or test (ULONG_PTR)name <= 0xFFFF) to tell atoms from strings, then call GetAtomName (or print the numeric atom) only for atoms. Also use cout vs wcout consistently with your ANSI/UNICODE build so you don’t mix narrow/wide output.

Example approach (illustrative):

// inside your EnumPropsEx callback:
if (IS_INTRESOURCE(name)) {
    ATOM a = (ATOM)(ULONG_PTR)name;
    TCHAR buf[128] = {0};
    if (GetAtomName(a, buf, sizeof(buf)/sizeof(buf[0])))
        // print buf with cout or wcout depending on UNICODE
    else
        // print numeric atom value
} else if (name) {
    // safe to print the string
} else {
    // name == NULL
}

If Winspector/Spy shows two integer atoms but your run reports one, common causes are: you’re examining a different HWND than Winspector (compare the hex handle and PID), one atom belongs to a child control (Notepad’s edit control) rather than the top-level window, or a property was transient/removed before enumeration. To debug, enumerate child windows (or call EnumPropsEx on each child), print both the HWND and atom numeric values, and only call GetAtomName when the atom is present. Finally, treat hData as opaque — it may be a pointer valid only in the other process and must not be dereferenced.

Recommended Answers

All 2 Replies

Then i receive a "properties.exe has encountered a problem and needs to close. We are sorry for the inconvenience." Windows error message.

Appears as if lpszString would be NULL, so try adding a check against that condition ...

BOOL CALLBACK PropEnumProcEx(HWND hwnd, LPTSTR lpszString, HANDLE hData, ULONG_PTR dwData) {

  LPTSTR pszPropLabel = lpszString ? lpszString : "not available";
 
  cout << "Property Label: " << pszPropLabel << "." << endl;
  return true;
}

Yes, indeed it is an atom; namely, an integer atom.

I changed the callback procedure to the following:
Code:

BOOL CALLBACK PropEnumProcEx(HWND hwnd, LPTSTR lpszString, HANDLE hData, ULONG_PTR dwData) {
  if (HIWORD(lpszString) == 0) {
    WORD the_atom = LOWORD(lpszString);
    char buffy[100] = {0};
    GetAtomName(the_atom, buffy, 100);
    cout << "It is an atom: " << buffy << endl;
    cout << "Data: " << hData << endl;
  }else {
    cout << "Property Label: " << lpszString << "." << endl;
  }
  return true;
}

I have a follow-up.


1. Winspector Spy shows there are two integer atoms, but I only get 1. What is going on here?

thanks for your help

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.