Solved

Extact message from a message box

Posted on 2010-09-20
8
619 Views
Last Modified: 2012-05-10
I need to read the actual message text from a standard Message Box using VBA (Access 2000)

The message box may be thrown up by my app or some other app but either way I CAN find the HWnd of the message box I am interested in but using sendmessage with WM_GetText or GetWindowText both bring back the Title Bar Text.

I Have tried virtually every suggestion on the web but still get the title!

How can I bring back the actual message text?
0
Comment
Question by:MikeGribble
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
8 Comments
 
LVL 120

Expert Comment

by:Rey Obrero (Capricorn1)
ID: 33716041
most of this app generated messages are error description,
if this is what you are after, you can get a list of this errors and description

see this link
http://support.microsoft.com/kb/105666
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 33716167
You only obtain the title because you have to go deeper into the static area of the dialog.
Dim hDlg As Long
hDlg = FindWindowW(StrPtr("#32770"), 0)
Debug.Print GetDialogText(hDlg, ID_STATIC)

Option Explicit

Private Const WM_GETTEXT As Long = &HD&
Private Const SMTO_NORMAL As Long = &H0&
Private Const ID_STATIC As Long = &HFFFF&

Private Declare Function FindWindowW Lib "user32" ( _
  ByVal lpClassName As Long, _
  ByVal lpWindowName As Long) As Long
  
Private Declare Function GetDlgItem Lib "user32" ( _
  ByVal hDlg As Long, _
  ByVal nIDDlgItem As Long) As Long
  
Private Declare Function SendMessageTimeoutW Lib "user32.dll" ( _
  ByVal hWnd As Long, _
  ByVal Msg As Long, _
  ByVal wParam As Long, _
  ByVal lParam As Long, _
  ByVal fuFlags As Long, _
  ByVal uTimeout As Long, _
  ByRef lpdwResult As Long) As Long
  
Public Function SendDlgItemMessageTimeout( _
  ByVal hWnd As Long, _
  ByVal Msg As Long, _
  ByVal wParam As Long, _
  ByVal lParam As Long) As Long

  Dim Success     As Long
  Dim lpResult    As Long
  
  Success = SendMessageTimeoutW(hWnd, Msg, wParam, lParam, _
    SMTO_NORMAL, 1000, lpResult)
  
  SendDlgItemMessageTimeout = lpResult
End Function

Public Function GetDialogText( _
  ByVal hDlg As Long, _
  ByVal dwId As Long) As String
  
  ' Returns text associated with the control.
  Dim Buffer(1024 * 2)  As Byte
  Dim cbSize            As Long
  Dim hWndId            As Long
  
  hWndId = GetDlgItem(hDlg, dwId)
  cbSize = SendDlgItemMessageTimeout(hWndId, WM_GETTEXT, 1024, VarPtr(Buffer(0)))
  
  If cbSize <> 0 Then
    GetDialogText = Left$(Buffer, cbSize)
  Else
    GetDialogText = vbNullString
  End If
  Erase Buffer
  
End Function

Open in new window

0
 
LVL 20

Expert Comment

by:darbid73
ID: 33716235
<GetWindowText both bring back the Title Bar Text.>

Then the handle you are using for the GetWindowText is the handle to the title and not the actual message text.

Looking at a standard Message Dialog in Access 2003 - I see 3 parts to it.  The Dialog has a handle - its text is the title.  Then there are 2 children of this one - the first is the OK button and the 2nd is the text.

Try getting a handle on the child of handle that shows the title text.  What text does this handle have?

Do you have some code?


0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:MikeGribble
ID: 33719338
I've tried your solution but get a zero length string

An Excel save changes message box is up when running your solution
hDlg = FindWindowW(StrPtr("#32770"), 0) returns 1706052
 and I have no reason to doubt this is correct because when I run it against a message box generated by my own app I know it returns the handle to that message box
I has hoped that GetDlgItem was what would help me but....

Debug.Print GetDialogText(hDlg, ID_STATIC) Returns a zero length string

Stepping through the GetDialogText function shows hDlg as 1706052 and dwId as 65535

hWndId = GetDlgItem(hDlg, dwId) returns hWndId as 0

cbSize = SendDlgItemMessageTimeout(hWndId, WM_GETTEXT, 1024, VarPtr(Buffer(0)))  thus naturally returns 0

0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 33719417
The example will find the first dialog with class name #32770 which means if there is more than one window available with the classname the handle could be one of the other windows. This is common as #32770 is the static classname for all dialogs in windows.
You can verify it works but to do that you will need to narrow the search to ensure you return the correct handle to the dialog your looking for you can do that by enumerating the windows or specify the title of the message box.

hDlg = FindWindowW(StrPtr("#32770"), StrPtr("messagebox title/caption"))

Open in new window

0
 

Author Comment

by:MikeGribble
ID: 33719510
Both hDlg = FindWindowW(StrPtr("#32770"), 0) and hDlg = FindWindowW(StrPtr("#32770"), StrPtr("Microsoft Excel"))
return the same handle as expected (I do not have a problem with identifying which dialog belongs to the handle

I had expected GetDialogText to return "Do you want save the changes to ........................

but I am getting a zero length string - that is the problem
 
0
 
LVL 29

Accepted Solution

by:
nffvrxqgrcfqvvc earned 500 total points
ID: 33719846
The dialog you refer to is a custom dialog by excel not the traditional messagebox you would get if you did MsgBox(etc..) which the previous code was expecting.
 MsgBox GetDialogTextEx

Option Explicit

Private Const BUF_SIZE As Long = 1024
Private Const WM_GETTEXT As Long = &HD&
Private Const SMTO_NORMAL As Long = &H0&

Private Declare Function FindWindowExW Lib "user32" ( _
  ByVal hwndParent As Long, _
  ByVal hwndchildAfter As Long, _
  ByVal lpszClass As Long, _
  ByVal lpszWindow As Long) As Long
  
Private Declare Function SendMessageTimeoutW Lib "user32.dll" ( _
  ByVal hWnd As Long, _
  ByVal Msg As Long, _
  ByVal wParam As Long, _
  ByVal lParam As Long, _
  ByVal fuFlags As Long, _
  ByVal uTimeout As Long, _
  ByRef lpdwResult As Long) As Long

Public Function GetDialogTextEx() As String
  Dim Buffer(BUF_SIZE * 2)  As Byte
  Dim hWindow               As Long
  Dim dwResult              As Long
  Dim cbSize                As Long
  
  hWindow = FindWindowExW(0, 0, StrPtr("#32770"), 0)
  hWindow = FindWindowExW(hWindow, 0, StrPtr("MSOUNISTAT"), 0)
  
  If hWindow = 0 Then
    Debug.Print "No Dialog exists"
    Exit Function
  End If
  
  Call SendMessageTimeoutW(hWindow, WM_GETTEXT, BUF_SIZE, _
    VarPtr(Buffer(0)), SMTO_NORMAL, 1000, dwResult)
    
  If dwResult <> 0 Then
      GetDialogTextEx = Left$(Buffer, dwResult - 1)
    Else
      GetDialogTextEx = vbNullString
  End If
  
End Function

Open in new window

0
 

Author Comment

by:MikeGribble
ID: 33719972
Perfect - works fine and gives me exactly what I need - Thanks & well done

Makes the subscription worth it
0

Featured Post

Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preparing an email is something we should all take special care with – especially when the email is for somebody you may not know very well. The pressures of everyday working life stacked with a hectic office environment can make this a real challen…
Access developers frequently have requirements to interact with Excel (import from or output to) in their applications.  You might be able to accomplish this with the TransferSpreadsheet and OutputTo methods, but in this series of articles I will di…
With Microsoft Access, learn how to specify relationships between tables and set various options on the relationship. Add the tables: Create the relationship: Decide if you’re going to set referential integrity: Decide if you want cascade upda…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question