News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Lost in ATOMS

Started by ramguru, December 02, 2006, 04:28:53 PM

Previous topic - Next topic

ramguru

Hi, I need some help to determine class of specific window. I have window handle & I want to make sure if the window has "EDIT" or "STATIC" or "BUTTON" class
I tried this:

invoke GetClassInfoEx, 0, CADD("BUTTON"), ADDR wcex
mov    eax, wcex.lpszClassName
mov    atom_butt, ax
;..........
        invoke GetClassLong,  active_win, GCW_ATOM
        cmp    ax, atom_butt
;DIDN'T WORK

I tried this:

invoke GlobalFindAtom, CADD("BUTTON")
mov    atom_butt, ax
;..........
        invoke GetClassLong,  active_win, GCW_ATOM
        cmp    ax, atom_butt
;DIDN'T WORK

I tried this:
Quote from: according to PSDK
If the first element is 0xFFFF, the array has one additional element that specifies the ordinal value of a predefined system class. The ordinal can be one of the following atom values.

0x0080
Button
...

        invoke GetClassLong,  active_win, GCW_ATOM
        cmp    ax, 0080h
;DIDN'T WORK


What is the correct way to determine class of specific window?

Tedd

No snowflake in an avalanche feels responsible.

ramguru

The simplest solution is one that didn't come to my mind, thanx Tedd

donkey

Hi ramguru,

I have run into this problem on many occasions, the atom table always seems to yeild incorrect results. For example using GetClassWord on a listbox will give an atom of actual+1 while a button will give actual-1. I have not found a reliable way to identify a window by it's atomic value. I would prefer to use atoms if possible as the compares are much faster (sub atom1,atom2, jz match) but at least in Win2K and XP I can't count on it being right. For example...

invoke GlobalGetAtomName,0C018h,offset buffer,256
PrintString(buffer)
invoke GlobalFindAtom,"button"
and eax,0FFFFh
PrintHex(eax)
invoke GetClassName,[lParam],offset buffer,256
invoke GlobalFindAtom,offset buffer
and eax,0FFFFh
PrintHex(eax)
invoke GetClassLong,[lParam],GCW_ATOM
and eax,0FFFFh
PrintHex(eax)


Has the following output:

Line 169: buffer = Button
Line 172: eax = 0000C018
Line 176: eax = 0000C018
Line 179: eax = 0000C017


Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

ramguru

hmm, very interesting (my test)

invoke GlobalGetAtomName, 0C02Dh, ADDR buf, 256
invoke MessageBox, 0, ADDR buf, 0, MB_OK
invoke GlobalFindAtom, CADD("button")
and    eax,0FFFFh
mov    ecx, eax
invoke dw2hex, ecx, ADDR buf
invoke MessageBox, 0, ADDR buf, 0, MB_OK
invoke GetClassName, active_win, ADDR buf, 256
invoke GlobalFindAtom, ADDR buf
and    eax,0FFFFh
mov    ecx, eax
invoke dw2hex, ecx, ADDR buf
invoke MessageBox, 0, ADDR buf, 0, MB_OK
invoke GetClassLong, active_win, GCW_ATOM
and    eax,0FFFFh
mov    ecx, eax
invoke dw2hex, ecx, ADDR buf
invoke MessageBox, 0, ADDR buf, 0, MB_OK

Result:
Quote
BUTTON
C02D
C02D
C017
So I guess if only GetClassLong worked correctly, we could assume that everything is OK (I didn't know about and eax,0ffffh). Thanks for info donkey...

donkey

The thing about GetClassLong is that it is used extensively in alot of software and the atom table is one of the most accessed portions of Windows so I can't see Microsoft letting this bug through in version after version of Windows from 95 on up. There is obviously something up here as I cannot find a single bug report on the internet or in the knowledge base about GetClassLong. I think I may download an example using it and try to figure this out.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Relvinian

Quote from: donkey on December 02, 2006, 06:16:02 PM
Hi ramguru,

I have run into this problem on many occasions, the atom table always seems to yeild incorrect results. For example using GetClassWord on a listbox will give an atom of actual+1 while a button will give actual-1. I have not found a reliable way to identify a window by it's atomic value. I would prefer to use atoms if possible as the compares are much faster (sub atom1,atom2, jz match) but at least in Win2K and XP I can't count on it being right. For example...

invoke GlobalGetAtomName,0C018h,offset buffer,256
PrintString(buffer)
invoke GlobalFindAtom,"button"
and eax,0FFFFh
PrintHex(eax)
invoke GetClassName,[lParam],offset buffer,256
invoke GlobalFindAtom,offset buffer
and eax,0FFFFh
PrintHex(eax)
invoke GetClassLong,[lParam],GCW_ATOM
and eax,0FFFFh
PrintHex(eax)


Has the following output:

Line 169: buffer = Button
Line 172: eax = 0000C018
Line 176: eax = 0000C018
Line 179: eax = 0000C017


Donkey

Donkey,

The only thing I can think of at this moment is the GetClassLong with GCW_ATOM is it is returning the ATOM that was used when you called RegisterClassEx...So if this window is a dialog or just plain window with a BUTTON in it, that is why you are seeing two different results.  What is the [lParam] (HWND) really defined as?  What window handle?

Relvinian

donkey

Hi Relvinian,

I agree that it could be that the atom number for a specific class may be altered during the startup of Windows but it sounds rather dubious to me. The atom table is AFAIK static and each time a string value is added it is issued a unique atomic number (actually in programming jargon atom means "unique ID"), when it is deleted it's atom is not recycled. Even if I am wrong and the atom is recycled, it would mean that the atom of a particular string can change at any time, for example "Button" is 0C14h and at some point due to alterations in another part of the global atom table changes to 0C16h without any notification. The result would be chaotic, since the internal window structure for every window contains the atom for it's class name and not the actual string, a change in the atom of the string would require a search of all windows for that atom and changing it. Race conditions could make identification of a given window class problematic and subject to the machinations of other processes that are completely unrelated to yours. Windows generally takes the path of least resistance and that is to not allow the atom in the global table to change, and since these classes are registered by Windows at startup and never deleted, they should always be present and stable. I think the problem must lie somewhere else.

Donkey
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

ramguru

I probably will assume that the following table is correct for values I get using GetClassLong(hWnd, GCW_ATOM) and will be using it instead of szCmp x 10


C017 - Button
C018 - Edit
C019 - Static
C01A - ListBox
C01B - ScrollBar
C01C - ComboBox
C03B - ToolbarWindow32
C043 - SysListView32
C047 - SysTabControl32
C049 - SysTreeView32