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.
Related
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);
I had a propertysheet where I am facing an issue in hiding the sheet.I will briefly explain what I had done.
In the PropertySheet OnWizardFinish() I am trying hide the sheet and do the following ,
BOOL CSecondEditpage::OnWizardFinish()
{
BOOL bAsyRet = ShowWindowAsync(m_hWnd,SW_HIDE);
int MsgRet = ::MessageBox(NULL,L"Do you want to restart",L"Test",MB_YESNO | MB_ICONINFORMATION);
if(IDYES == MsgRet)
{
SystemRestart();
}
else
{
//Do Nothing..
}
return CPropertyPage::OnWizardFinish();
}
So here only the message box should be visible and the sheet should be hidden this is what I am expecting that ShowWindowAsync does.But in the background sheet still exists.
Same thing I tried with a dialog based application there it is working as expected like as,the background window is hidden and only message box is shown .
For more details:
And now when I click finish the sheet should be hidden and should show a message box something like this,
Can anyone please let me know how can achieve this in propertysheet wizard.
You're trying to hide PropertyPage not a PropertySheet.
Do like this.
CPropertySheet* prop = (CPropertySheet*)GetParent();
ShowWindowAsync(prop->m_hWnd, SW_HIDE);
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);
How do I get cursor when dialog is start at OnInitDialog function,
without user to move click it, like as follow pic
enter link description here
Other problem is, when the editbox already fill with text, how do I select the text ?
On OnInitDialog function, I see as follow description,
// return TRUE unless you set the focus to a control
so I define a variable to the editbox, the set focus on it,
then return false in OnInitDialog function.
BOOL CInputTestPoint::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: 在此加入額外的初始化
m_editTestPointName.SetFocus();
//return TRUE; // return TRUE unless you set the focus to a control
return false;
// EXCEPTION: OCX 屬性頁應傳回 FALSE
}
For select whole text method is as follow
define CEdit to the edit box and m_editTestPointName.SetSel(0, strTestPointName.GetLength(), true);
((CEdit *)GetDlgItem(IDC_EDIT_INPUT_TP))->SetSel(0, strTestPointName.GetLength(), true);
I want to use two ribbon category buttons to switch between two different views, but I found it can't add event handler to the button.
Is there any hint to solve this problem? Better if there is some sample, actually I'm new to MFC.
You could try hooking into this event?
AFX_WM_ON_CHANGE_RIBBON_CATEGORY
An option I have found successful was to subclass CMFCRibbonBar and override PreTranslateMessage and check for mouse clicks. Below are the steps I took which have thus far worked well.
Subclass CMFCRibbon - in my example I created CCustomRibbonBar
Override PreTranslateMessage, and add an int value to keep track of the tab
Create a custom windows message that your applications MainForm handles -WM_ACTIVE_RIBBON_TAB_CHANGED in my example
Inside of PreTranslateMessage check for Left Mouse Up event
In the event of a left mouse button up, let the Ribbon finish handling the message and then query the Active Category.
Post the active category to MainForm (or other form)
In your MainForm, handle the category and take into account that with most events the category will not have changed.
Then in my override I check for the mouse up event and retrieve the Active category
Inside Class Declaration
virtual BOOL PreTranslateMessage(MSG* pMsg);
int m_LastActiveCategory;
Inside Class Definition
BOOL CCustomRibbonBar::PreTranslateMessage(MSG* pMsg)
{
//If command was finishing a click
if(pMsg->message == WM_LBUTTONUP && pMsg->wParam == 0)
{
//Allow ribbon to handle itself first
BOOL result = CMFCRibbonBar::PreTranslateMessage(pMsg);
//Get new active tab
int activeTab = GetCategoryIndex(GetActiveCategory());
//If tab has changed, forward message
if(activeTab != m_LastActiveCategory)
{
//forward message to parent
::SendMessage(GetParentFrame()->GetSafeHwnd(),WM_ACTIVE_RIBBON_TAB_CHANGED,activeTab,0);
m_LastActiveCategory = activeTab;
}
return result;
}
//Otherwise handle like normal
return CMFCRibbonBar::PreTranslateMessage(pMsg);
}