Hi again. I am stuck on a project.
I am having difficulties in retrieving specific information in a MessageBox. I am writing an application that will be monitoring another application. We're all familiar with the following:
int MessageBox(
HWND hWnd, // handle of owner window
LPCTSTR lpText, // address of text in message box
LPCTSTR lpCaption, // address of title of message box
UINT uType // style of message box
);
but my question is, how do I retrieve and compare LPCTSTR lpText in the Target application?
I have successfully been able to obtain the MessageBox's handle by using the following:
invoke FindWindow, 0, ADDR winname
cmp eax, 0 ; if window does not exist
je @notThere ; goto end
mov targethandle, eax ; Prog handle
and I have been able to successfully CLOSE the MessageBox by Sending a WM_CLOSE Message (thanks to this forum).
But in between these, I want to compare the Text of the MessageBox.
I have tried things like:
invoke GetDlgItemText,targethandle,??,offset textcheck, SIZEOF textcheck
no luck. I suppose if I knew how, I could Hook the MessageBox somehow, but I am hoping there is an easier way.
I know that MessageBox's have their own MessageProc. Does this have something to do with the reason I cannot get to the MessageBox's Text parameter or something?
Any help would be terrific. I have been stuck on this for many hours (going on days) now.
Here is my skeleton program I have:
; MessageBox Monitor
;
; --------------------------------------------------------------------
.486
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
winname db "Status", 0
wrongText db "Application Has Finished!", 0
appName db "DebugMessage",0
appCaption db "We found the MessageBox Text!",0
notfound db "Cant find it",0
buffer db 128 dup(0)
textcheck db 128 dup(0)
.data?
targethandle dd ? ; handle to the program
.code
start:
invoke FindWindow, 0, ADDR winname
cmp eax, 0 ; if window does not exist
je @notfound ; goto end
mov targethandle, eax ; store handle
// THIS Dont work:
// invoke GetDlgItemText,targethandle,0,offset textcheck, SIZEOF textcheck
// i dont know how to get the control id of the text, if there even IS one
// THIS IS WHERE I NEED HELP
//
invoke lstrcmp, ADDR textcheck, ADDR wrongText
cmp eax, 0
je @notfound
; found it, now close it and continue.
; .
; .
; .
; invoke SendMessage, eax, WM_CLOSE, 0, 0
@end:
; ----------------------------
invoke ExitProcess, 0
@found:
invoke MessageBox, 0, ADDR appName, ADDR textcheck, 0 ;
jmp @end
@notfound:
invoke MessageBox, 0, ADDR notfound, ADDR appName, 0 ;
jmp @end
end start
Thanks Again!!
Trope
No, you can use EnumChildWindows to enumerate the static box, as well as the buttons from the hWnd of the MessageBox.
Then you can use GetWindowInfo to compare the style to see if it is a static. (Personally i don't know any styles unique to STATIC class)
Then once you have the hWnd, you can use GetWindowText to get the text.
Quote from: Infro_X on March 07, 2005, 05:31:34 PM
No, you can use EnumChildWindows to enumerate the static box, as well as the buttons from the hWnd of the MessageBox.
Then you can use GetWindowInfo to compare the style to see if it is a static. (Personally i don't know any styles unique to STATIC class)
Then once you have the hWnd, you can use GetWindowText to get the text.
Maybe you can also use
GetClassName
to find the "Static" classname
Labels are STATIC, editboxes are not.
Paul
I think this post from a VB forum is on the right track - actually, if we could convert it to ASM it would be perfect!
'put in declarations part of a form
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Sub Form_Load()
Dim x As Long, staticx As Long, MyStr As String
x = FindWindow("#32770", vbNullString)
staticx = FindWindowEx(x, 0&, "static", vbNullString)
MyStr = String(100, Chr$(0))
GetWindowText staticx, MyStr, 100
MyStr = Left$(MyStr, InStr(MyStr, Chr$(0)) - 1)
MsgBox MyStr
End Sub
'--
this will msgbox you the text contained in the first message box found, to test it open up another instance of VB and in the form_load proc just put msgbox "Hey there"
then run this program, it will display a message box of the text it grabbed from the other message box.
and here is my attempt at converting it:
.code
start:
invoke FindWindow, ADDR winClassname, NULL
.IF eax==NULL
invoke MessageBox, NULL,ADDR notfound,ADDR appName,MB_OK
.ELSE
mov targethandle, eax
invoke FindWindowEx, ADDR targethandle, 0, ADDR szStatic, NULL
.IF eax!=NULL
mov myBuffer, eax
invoke MessageBox, NULL,ADDR buffer,ADDR appName,MB_OK
.ENDIF
.ENDIF
@end:
; ----------------------------
invoke ExitProcess, 0
end start
again... no luck.
Any ideas where to try from here?
Just a small mistake you have there. variable "targethandle" is the HANDLE to the dialog window, you don't have to use ADDR
invoke FindWindowEx, targethandle, 0, ADDR szStatic, NULL
Be careful if the MessageBox use an icon. It also STATIC, so you have to loop for the STATIC class to find the LABEL, not an ICON. Also WM_CLOSE will not close MessageBox, if the MessageBox using MB_YESNO or MB_ABORTRETRYIGNORE
Edit:
Oops sorry, there is another mistake :green It should code like this
mov hChild, FUNC( FindWindowEx, targethandle, 0, ADDR szStatic, NULL )
invoke GetWindowText, hChild, addr szBuffer, LengthOf szBuffer
COOL. Trying this now.
But can you tell me , how would I know that the class name is #32770?
Where is this stuff documented?
I used Ice's TUT #24 , his hook program, and it confirms the MessageBox indeed uses that class.
I don't know where is the complete doc exactly, but this one clearly stated
The window class name for dialog boxes is "#32770".
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msaa/msaapndx_49q0.asp
We are close on this one I believe.
Getting a syntax error on this line:
mov hChild, FUNC( FindWindowEx, targethandle, 0, ADDR szStatic, NULL )
here is the whole code so far:
; MessageBox Monitor
;
; --------------------------------------------------------------------
.486
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
winClassname db "#32770", 0
wrongText db "Application Has Finished!", 0
appName db "Debug Message",0
appCaption db "We found the MessageBox Text!",0
notfound db "Cant find it",0
szStatic db "static",0
; A buffer
szBuffer db 128 dup(0)
.data?
; Special handles
targethandle dd ? ; handle to the MESSAGEBOX
hChild dd ? ; handle to the STATIC
.code
start:
invoke FindWindow, ADDR winClassname, NULL
.IF eax==NULL
invoke MessageBox, NULL,ADDR notfound,ADDR appName,MB_OK
.ELSE
mov targethandle, eax
mov hChild, FUNC( FindWindowEx, targethandle, 0, ADDR szStatic, NULL )
invoke GetWindowText, hChild, addr szBuffer, LengthOf szBuffer
.IF eax!=NULL
invoke MessageBox, NULL,ADDR szBuffer,ADDR appName,MB_OK
.ENDIF
.ENDIF
@end:
; ----------------------------
invoke ExitProcess, 0
end start
As a new user to MASM, that syntax is not familiar to me ( yet ).
Any ideas where the syntax is wrong?
Sorry about that. I didn't see your complete code earlier. You must include the macro file
include \masm32\macros\macros.asm
Or if you don't want to use macro, you can change it to this
invoke FindWindowEx, targethandle, 0, ADDR szStatic, NULL
mov hChild, eax
:clap:
Works like a charm!!!!!!!!!!! )ignore my PM, plz.
Thank you for you help. As a newbie, I really appreciate this.
Okay, that is fine, I will ignore it :toothy
You are welcome :U