Changing the title of the MessageBox for DDX_Text() - c++

The message box which is displayed when validation has the title same as that of the project.
I searched MSDN and in google for changing the title of the message box for DDX_Text().
Below is the code snippet form
void CPower_Module::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_POWER_TXT_IGNITION_OFF_DELAY, delayOffWhenIgnitionIsOff);
}
When the user tries to delete the data in the text box, he will be shown a message Box as
with the application name as the title.
How do I change the title of the message box keeping the functionality same?

Internally AfxMessageBox is called. This function always uses the application title as a title for the message box. The value is stored in CWinApp::m_pszAppname. It is just a LPCTSTR.
Just create a class like this.
class CChangeAppTitle
{
public:
CChangeAppTitle(LPCTSTR pszNewTitle)
: m_strTitle(pszNewTitle)
, m_pszOldTitle(AfxGetApp()->m_pszAppTitle)
{
AfxGetApp()->m_pszAppTitle = m_strTitle;
}
~CChangeAppTitle()
{
AfxGetApp()->m_pszAppTitle = m_pszOldTitle;
}
private:
CString m_strTitle;
LPCTSTR m_pszOldTitle;
};
In DoDataExchange or before you call UpdateData just activate the class:
{
CChangeAppTitle appTitle(_T("my app title");
UpdateData();
...
Be aware that all message boxes that my be initiated by a timer, while this dialog is open, will show the new app title. Also a COM automation that is activated during this class is active will also return the changed app title.

Just Set Your Caption in MessageBox Parameter.
CString v1_sMessageToDisplay;
v1_sMessageToDisplay.Format(_T("Saved Successfully to C:/IniGui/"));
MessageBox(v1_sMessageToDisplay, _T("Your Caption"), MB_ICONINFORMATION);

Related

MDI Tab names changing back... / Taskbar Preview not selecting

I'm creating an MDI application, WITHOUT the Document/View.
I am also using MDITabbedGroups.
I had a problem, because I have to name may tabs dynamically (names are in the DB and user created), meaning I couldn't use resources for the names.
I create all the tabs as 'Program name', then rename them by calling the following after create:
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_COMMAND(ID_SET_COLOR, CCOnSetColor)
END_MESSAGE_MAP()
PostMessage(WM_COMMAND, (WPARAM)ID_SET_COLOR);
void CChildView::CCOnSetColor()
{
CMDIChildWndEx* pFrame = (CMDIChildWndEx*)GetParent();
CMFCTabCtrl* pTabCtrl = pFrame->GetRelatedTabGroup();
if (pTabCtrl != NULL)
{
pTabCtrl->SetTabBkColor(pTabCtrl->GetActiveTab(), GetTabCol());
pTabCtrl->SetTabLabel(pTabCtrl->GetActiveTab(), GetTabName());
pTabCtrl->RedrawWindow();
}
}
But the problem was that when I switched tabs the names would change back to 'Program Name'.
I managed to avoid this by skipping over CMDIChildWndEx in the OnMDIActivate call as so:
void CChildFrame::OnMDIActivate(BOOL bActivate, CWnd* activated, CWnd* disbled)
{
CWnd::OnMDIActivate(bActivate, activated, disbled);
}
I know, I know, bad. However:
This worked fine, all other functionality seemed to be working, tabs were switching, active window was correct etc etc...
Until I noticed that on mouse over of the task bar, I got a preview of all open tabs, and if I clicked on one of the inactive tabs things went wrong.
Now the active frame / view (GetActiveFrame() / GetActiveView() in MainFrame) was the one I click on, but it is not drawn and the tab not switched to.
So I tried:
void CChildFrame::OnMDIActivate(BOOL bActivate, CWnd* activated, CWnd* disbled)
{
CMDIChildWndEx::OnMDIActivate(bActivate, activated, disbled);
CMFCTabCtrl* pTabCtrl = GetRelatedTabGroup();
if (pTabCtrl != NULL)
{
pTabCtrl->SetTabBkColor(pTabCtrl->GetActiveTab(), m_wndView.GetTabCol());
pTabCtrl->SetTabLabel(pTabCtrl->GetActiveTab(), m_wndView.GetTabName());
// pTabCtrl->SetTabIcon(pTabCtrl->GetActiveTab(), 2);
pTabCtrl->RedrawWindow();
}
}
&&&
void CChildFrame::OnMDIActivate(BOOL bActivate, CWnd* activated, CWnd* disbled)
{
CMDIChildWndEx::OnMDIActivate(bActivate, activated, disbled);
m_wndView.PostMessage(WM_COMMAND, (WPARAM)ID_SET_COLOR);
if(disbled) ((CChildFrame*)disbled)->m_wndView.PostMessage(WM_COMMAND, (WPARAM)ID_SET_COLOR);
}
Now the tab switches correctly, but only the tab being activated gets the correct name, all inactive tabs go back to 'Program Name'
interestingly the color remains correct.
So the Question:
Can I permanently change the name some how / where.
I saw in MS Documentation that it can be set in CDocument, but I don't have a Document...
Alternatively what call / calls do I need to catch to set my name every time?
Also Bonus Q:
Can I make the Preview show only the 'Active' Tab, and not the others?
After much hunting around in the AFX source files, I found this:
CString CMDIChildWndEx::GetFrameText() const
{
ASSERT_VALID(this);
CString strText;
GetWindowText(strText);
return strText;
}
& this
void CMDIFrameWnd::OnUpdateFrameTitle(BOOL bAddToTitle)
{
if ((GetStyle() & FWS_ADDTOTITLE) == 0)
return; // leave it alone!
... // rest of func
}
so it is as simple as removing the style flag the MS puts in automatically (via wizard create project), on the func BOOL PreCreateWindow(CREATESTRUCT& cs).
Then setting the title of the Frame via SetWindowText(title);

How can I get notified when the property page changes in view class

I have a property sheet (CPropertySheet derived class) and its pages (CPropertyPage derived class) in CView derived view class. I need to get notice at CView derived class when the property page changes.
In my case, handling the PSN_SETACTIVE notification will not work.
The problem is by changing the page I need to update the data in the page from one resource. If that resource is not active then I need to close the view and restart the view again.
CPropertySheet does not receive information about tab changes.
PSN_SETACTIVE and PSN_KILLACTIVE is sent to CPropertyPage instead. You have to handle these messages in each PropertyPage when tab is selected/un-selected.
In MFC you can handle this as follows:
class CMyPropertyPage: public CPropertyPage
{
BOOL OnSetActive();
BOOL OnKillActive();
...
};
BOOL CMyPropertyPage:OnSetActive()
{
BOOL res = CPropertyPage::OnSetActive();
TRACE("CMyPropertyPage tab selected\n");
return res;
}
BOOL CMyPropertyPage:OnKillActive()
{
BOOL res = CPropertyPage::OnKillActive();
TRACE("CMyPropertyPage tab unselected\n");
return res;
}
See also:
WinAPI property sheet
CPropertyPage::OnSetActive
To send notification to CMyView, you will have to find the handle to your target and pass the message.

How to map help id of a error messagebox in MFC?

I have a dialog box in MFC which has help button.
I am able to map help button with my help content.
on my dialog box, I have a edit box also i which user can enter anything.
i am validating the edit control box that if something wrong user enters it will open
error message box which display error and having help button too.
i wanted to map this error message box helpid to my content (which different from parent dialog box) but whenever click help button it shows me parent help content.
NOTE: i tried both APIs Afxmessagebox and Messagebox.
Solution from my side , (i don't know if it is correct )
Create another dialog box and mapp to help id as i di fro parent dialog box.
and treat this dialog box as a error messagebox with domodal.
I feel i we can do this with messagebox itself but didn't find anything on web.
What i tried -
I tried following link but couldn't get success.
http://www.codeproject.com/Articles/562/Add-a-Help-Button-to-a-MessageBox
VOID CALLBACK MsgBoxCallback(LPHELPINFO lpHelpInfo)
{
CString str = AfxGetApp()->m_pszHelpFilePath;
AfxGetApp()->WinHelp(lpHelpInfo->dwContextId);
}
UINT AfxMessageBox(HWND hWnd, LPCTSTR szText, UINT nType, UINT nIDHelp = 0)
{
MSGBOXPARAMS mbp;
memset(&mbp, 0, sizeof mbp);
mbp.cbSize = sizeof MSGBOXPARAMS;
mbp.hwndOwner = hWnd;
mbp.hInstance = AfxGetInstanceHandle();
mbp.lpszText = szText;
AfxGetApp()->m_pszHelpFilePath = "C:\\Program Files (x86)\\\HELP\\130.htm";
// if you wanted to specify a different caption, here is where you do it
mbp.lpszCaption = AfxGetAppName();
// if Help ID is not 0, then add a help button
if (nIDHelp != 0)
{
mbp.dwStyle = nType | MB_HELP;
}
else
{
mbp.dwStyle = nType;
}
// mbp.lpszIcon = ; // note, you could provide your own custom ICON here!
mbp.dwContextHelpId = nIDHelp;
mbp.lpfnMsgBoxCallback = &MsgBoxCallback;
mbp.dwLanguageId = 0x0409;
return ::MessageBoxIndirect(&mbp);
}
Here's how to do it:
Create a string resource for each message box.
Be sure to name the resource with an IDP_ prefix. Although IDS_ also corresponds to strings, the makehm command-line tool will not look for IDS_ when it builds the HTMLDefines.h file.
Change your message box call(s) to AfxMessageBox(IDP_FOO, MB_OK|MB_HELP, IDP_FOO), substituting in other flags, as needed.
(Note: I had another answer, but it was way off, so I decided to start clean with a new answer instead of updating it.)

C++ MFC - Not receiving CBN_EDITCHANGE message on CBS_DROPDOWN combobox in a toolbar

I have an mfc application where my mainframe contains multiple CDockablePanes.
In some of the CDockablePanes I have a CMFCToolbar and a CTreeView.
When I receive the AFX_WM_RESETTOOLBAR message in my mainframe class, I use CMFCToolBar::ReplaceButton to add a CMFCToolBarComboBoxButton to my toolbar.
This works fine and I am able to use the combobox as expected however I want to receive a notification each time the combo box's edit control's text is changed (Each key press etc) but I have not been able to catch a CBN_EDTITCHANGE message at all.
I have been using this line in my message map:
ON_CBN_EDITCHANGE(ID_TREEVIEWFILTER_COMBOBOX, Test)
But not hitting the function 'Test'. I have managed to catch other combo box messages eg. ON_CBN_DROPDOWN from in the toolbar class but not CBN_EDITCHANGE.
In my CMFCToolBarComboBoxButton derived class I override the CMFCToolBarComboBoxButton::CreateCombo function as shown:
CComboBox* FilterComboButton::CreateCombo(CWnd* pWndParent, const CRect& rect)
{
CComboBox* pCombo = new CComboBox();
if (!pCombo->Create(CBS_DROPDOWN | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | WS_CHILD, CRect(25,0,175,FILTERTOOLBARHEIGHT), pWndParent, ID_TREEVIEWFILTER_COMBOBOX))
{
LOG("Failed to create FilterComboBox");
delete pCombo;
pCombo = NULL;
}
return pCombo;
}
Adding the code: BOOL bSuccess = pCombo->ModifyStyle(CBS_DROPDOWNLIST, NULL); after the call to CComboBox::Create causes me to receive the CBN_EDITCHANGE, but interferes with the function of the combobox.
I have managed to catch the edit controls message EN_UPDATE but not EN_CHANGE. This is so close but so far away...
Any help would be much appreciated, thanks in advance!

help with the edit box/Input Box

I created a simple dialog with a label and edit box, then created a class, CInputDlg, added member variables for the label and edit box, and called it
CInputDlg dialog
dialog.m_label = TEXT("Enter a number:");
if (dialog.DoModal() == IDOK) {
// Do something
}
Now how do I display the text which is entered into the edit box?
Try WM_GETTEXT
http://msdn.microsoft.com/en-us/library/ms632627(v=VS.85).aspx
In the Handler for the OK button on the Dialog, you should get the TextBox.GetText(), and put it back into a public CString member m_InputString. Then, from the calling function, you can read dialog.m_InputString.