I'm trying to send a message to an AfxMessageBox. I want to simulate an <OK> button press.
The reason is, that we are using a scanner to scan an <OK> barcode instead of pressing the <OK> button itself.
This works when the AfxMessageBox is an MB_OK type and MyMessage is WM_CLOSE.
If the type is MB_YESNO or others, this does not work. If the messages are others than WM_CLOSE, this does not work.
I would like to be able to simulate a <YES> button press og <NO> button press for a MB_YESNO MessageBox type.
Since you are restricting the message box to AfxMessageBox, you can make certain assumptions with regard to the buttons.
You know that there will be a minimum of 1 and a max of 3 buttons (including a help button).
The buttons will always be in the same location, so its 'ordinal' will always be the same.
I've used the code below to close system dialogs before. In it's day it was very reliable for closing message box dialogs. The method takes a hwnd to the messagebox (or AfxMessageBox) and an enum to the button type.
Code:
const LPCTSTR BTN_CLASS = _T("Button");
//+-----------------------------------------------------------------------
// Private Helper Method: FindErrorWindow
//
// Purpose: Searches the system for this object's error
// window.
// Restrictions:
//
// Parameters: Parent hWnd (hwnd to the dialog)
// enum of buttons
//
//
// Return: Captured window hWnd, NULL if window not found
//------------------------------------------------------------------------
void CWindowTrap::HandleButton(HWND hWnd, _BTNType nButton)
{
Tstring sBtnText;
Tstring sAltBtnText;
switch(nButton)
{
case WTBTN_YES: sBtnText = _T("&Yes"); sAltBtnText = _T("Yes"); break;
case WTBTN_NO: sBtnText = _T("&No"); sAltBtnText = _T("No"); break;
case WTBTN_CLOSE: sBtnText = _T("&Close"); sAltBtnText = _T("Close"); break;
case WTBTN_IGNORE: sBtnText = _T("&Ignore"); sAltBtnText = _T("Ignore"); break;
case WTBTN_OK: sBtnText = _T("&Ok"); sAltBtnText = _T("Ok"); break;
case WTBTN_CANCEL: sBtnText = _T("&Cancel"); sAltBtnText = _T("Cancel"); break;
case WTBTN_TERMINATE: sBtnText = _T("&Terminate"); sAltBtnText = _T("Terminate"); break;
case WTBTN_DONT_SEND: sBtnText = _T("&Don't Send"); sAltBtnText = _T("Don't Sent"); break;
case WTBTN_WMCLOSE:
PostMessage(hWnd, WM_CLOSE, 0,0);
return; // Exit here, no need to click buttons
}
HWND hBtn = ::FindWindowEx(hWnd, NULL, BTN_CLASS, sBtnText.c_str());
if (hBtn != NULL)
PostMessage(GetParent(hBtn),WM_COMMAND, GetDlgCtrlID(hBtn),long(hBtn));
else
{
hBtn = ::FindWindowEx(hWnd, NULL, BTN_CLASS, sAltBtnText.c_str());
PostMessage(GetParent(hBtn),WM_COMMAND, GetDlgCtrlID(hBtn),long(hBtn));
}
}
Notice how GetParent and GetDlgCtrlID are used in conjuction with PostMessage to close the dialog? This is code you'll be able to reuse.
Now the difference in what you are trying to achieve is that you don't know the button text (i.e. Yes, OK, etc.). The good news is that instead of searching for an exact text match, you can search for the 1st button that is a child of the dialog using FindWindowEx:
Bookmarks