MFC/BCGP: Update CEditView's tab label without changing the contents of the CEditView? - mfc

When I have a SDI Document-View MFC application which uses CBCGPTabView as the main view, one of the tabs is a CEditView. If I send a custom message to the CBCGPTabView derived class and use GetTabControl().SetTabLabel() it not only changes the tab label but contents of the CEditView. Is there a way to prevent that?

This is the workaround I have for now:
// hack to work around ceditview getting its window contents changed
CView* pview=GetView(tabi);
if (pview->IsKindOf(RUNTIME_CLASS(CEditView))) {
CString strexistingtext;
pview->GetWindowText(strexistingtext);
// change label
tabctrl.SetTabLabel(tabi, strlabel);
// put back text
pview->SetWindowText(strexistingtext);
}
else {
// change label
tabctrl.SetTabLabel(tabi, strlabel);
}
}

Another method is to override
virtual CString CBCGPMDIChildWnd::GetFrameText() const
And put / set there what you need.

Related

How to set text below the QToolButton in QT not below the icon

I'm using QToolButton and I set the icon.
Now I want Text "below the QToolButton", "Not below the icon".
Is there any way to achieve this in C++,QT in Linux ?
I've found myself in the same position a while back ago while I was making an application for an embedded Linux system.
I haven't found a straight forward solution (I was searching for a way to achieve it with CSS).
What I ended up doing, was creating a new QWidget (using the designer). Then placing the button in it with a QLabel under it.
Then added a simple static function
static void wdgCustomButton::create(const QString iconPath, const QString text)
{
// create a new button here, create some modification functions for
// text, image and optionally QStyleSheets.
// Call those here (pass the arguments)
// Then return the button
// pseudo code, (not tested):
wdgCustomButton button = new wdgCustomButton( /* could pass a parent */ );
button->setIcon( iconPath ); // function simply calls the ui->button->setIcon
button->setText( text ); // function simply calls the ui->label->setText
return button;
}
And then add those new QWidgets to your pannel using code (maybe someone knows how to get it in the default toolbar, but I haven't searched for that myself yet since I never needed it).
this->menuButtons[menuBtnsCount] = wdgCustomButton::create( ":/Images/Warning.png", "Delete everything" );
this->menuButtons[menuBtnsCount]->setGeometry( QRect( /* size and position here */ ) );
this->menuButtons[menuBtnsCount]->show();
I hope this might give you an idea to fix it in an easy way!
Edit:
I'm sorry, I forgot to add something about the click event. The click event was mainly why I made a QWidget out of it!
I just used the connect function [I belive on the whole button like: connect(this->menuButtons[0], ...]

Display the input of QLineEdit in a different window and or dialog?

I am writing a small QT gui application where there is a QLineEdit in my mainwindow.ui and I want to display the entered text in a separate dialog and or window when a button is pressed.
Now, I have stored the input in a variable, and I am also able to show this string on a label within this same mainwindow,
void MainWindow::on_GoButton_clicked()
{
QString mytext = ui->lineEdit_1->text();
ui->label_1->setText(mytext);
}
Now, I want to open a popup dialog (can be a window also), for example SecDialog;
SecDialog secdialog;
secdialog.setModal(true);
secdialog.exec();
and display the text of mainwindow->mytext string variable in a label of the SecDialog. How can I do that ??? I know it is a basic level question, but I think it will help clear lot of my doubts reagrding moving values of variables in between forms and classes.
Situation
So this is your situation:
From your code, the dialog is a modal dialog:
SecDialog secdialog;
//secdialog.setModal(true); // It's not needed since you already called exec(), and the
// dialog will be automatically set to be modal just like what
// document says in Chernobyl's answer
secdialog.exec();
Solution
To make the dialog display the text from the Window,
the concept is to pass the information(text) from the Window
to the dialog, and use a setter function from the dialog to display it.
Like Floris Velleman's answer, he passed the mytext string (by reference) to a customized dialog constructor and called the setter theStringInThisClass(myString) at once.
The implementation detail of this function is complemented by Chernobyl's answer (use the name setLabelText instead):
void SecDialog::setLabelText(QString str)
{
ui->label->setText(str); // this "ui" is the UI namespace of the dialog itself.
// If you create the dialog by designer, it's from dialog.ui
// Do not confuse with the ui from mainwindow.ui
}
Chernobyl suggested another way which calls the setter in the slot function and it bypasses the need of defining another constructor, but basically the concept is the same:
void MainWindow::on_GoButton_clicked()
{
QString mytext = ui->lineEdit_1->text();
ui->label_1->setText(mytext);
SecDialog secdialog;
secdialog.setLabelText(myText); // display the text in dialog
secdialog.exec();
}
Comment
I try to illustrate the concept as clear as possible, because from my previous experience on your question, you just "copy & paste" codes from answers and took them as your final solution, which is not right. So I hope this summary could help you understand the concept and then you may write your own code.
This task can be easy done with getter/setter method or with signal and slot, but setter is more suitable here. In SecDialog header:
public:
void setLabelText(QString str);
//in cpp
void SecDialog::setLabelText(QString str)
{
ui->label->setText(str);//it is label dialog
}
Usage:
secDialog.setLabelText(myText);
Also line where you set modal to true is not necessary because
This property holds whether show() should pop up the dialog as modal
or modeless. By default, this property is false and show() pops up the
dialog as modeless. Setting his property to true is equivalent to
setting QWidget::windowModality to Qt::ApplicationModal. exec()
ignores the value of this property and always pops up the dialog as
modal.
Assuming SecDialog is a custom class with an interface file as well you might want to pass it as a constructor argument or pass it by using another function.
So in the SecDialog constructor you could have something like:
SecDialog::SecDialog(QWidget* parent, const QString& myString)
: QDialog(parent),
theStringInThisClass(myString)
{}
And then you could call it like:
SecDialog secdialog(this, mytext);

Editing label on different dialog qt C++

I made another window pop up using:
SecondDialog object;
object.setModal(true);
object.exec();
I added a label on the second dialog using the design form editor. However I would like to use a QString variable from the original dialog to use for that label. Is that possible? And if so how would I do it? Any input would be greatly appreciated.
You should provide a name for the label in your second dialog. You can do it in the designer's Object inspector (upper right corner by default), left column. Then, create a method
void SecondDialog::SetLabelText (QString &text)
{
ui.myLabel->setText (text);
}
Then call it from the first dialog before exec'ing.

How change edit control's text?

I have a button and text control in MFC dialog window, when I click on button, in edit control must be replaced for example "hello world".
but if I write
edit="hello wordl"
it doesn't change, how can I change?
First you should add a variable to edit.To do that right click on the edit and choose Add Variable... in Add Member variable Wizard change Category from Control to Value after that in the Variable name field type a name like m_EditValue then click finish.from now you can change the Edit Control simply by following code.
void CAboutDlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
m_EditValue = L"Hello World";
UpdateData(FALSE);
}
Use the SetWindowText method:
edit.SetWindowText( _T("Hello, World!") );
First you need a CEdit member variable of the dialog. Use 'Add Variable' in the dialog editor. If you name this variable m_helloedit then in your button click function
m_helloedit.SetWindowText(_T("hello world!"));

Clicking in an MFC edit box

I've created a read-only edit box in an MFC dialog box. I'm trying to have it so a user clicks in the edit box, which is read-only, it opens a file dialog, and then puts this value into the text box using UpdateData. I'm catching the ON_EN_SETFOCUS message but pressing OK on the file dialog respawns it, so I get caught in an infinite loop.
UpdateData(TRUE);
CFileDialog fileDialog(TRUE,NULL, NULL,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST, _T("Text Files(*.txt)|*.txt||"));
if( fileDialog.DoModal() == IDOK )
{
configFile=fileDialog.GetPathName(); //Note to self, this includes filename, getPathName includes filename and path.
}
else
{
return;
}
UpdateData(FALSE);
If you've got any ideas on how this should be done, I would be very grateful.
Alright Mr. Lister I guess I'll add an answer.
First off I would preface this with I would probably simply add a button name "..." to launch the file dialog to the right of the edit box for opening the file dialog as that's the simplest solution and what most windows users will expect.
Another option however is to extend an MFC control. When deciding to extend a control you want to pick one that mostly has the desired behavior and that has a virtual destructor which lends itself to being a subclass. Since you want button like behavior CButton may be a good choice.
Your class interface might look something like this:
class CPathButton : public CButton
{
public:
enum { ID /*= IDC_BUTTON1*/ };
const CString GetPath() const;
const CString GetFileName() const;
const CString GetDirectory() const;
const CString GetExtension() const;
// other useful methods for setting file filters etc
protected:
// add ON_CONTROL(BN_CLICKED, ID, &OnClick) or ON_BN_CLICKED(ID, &OnClick)
DECLARE_MESSAGE_MAP()
// CFileDialog fdlg.DoModal(), m_path = fdlg.GetPathName(), SetWindowText(fdlg.GetFileTitle()), etc
afx_msg void OnClick();
// additional message handlers etc
private:
CString m_path; // save full path for after dialog is closed
};
You can add as much or as little customization as you want depending on if the control will be created dynamically, via the resource file, or whatever. The basic idea being that you display the currently selected file name on the button while storing the full path for other uses as a member so the user doesn't need to see the clutter of a long path with nested directories.
If you don't like the way it looks by default you can override OnPaint and handle WM_PAINT messages and use a custom font, size, or add ellipsis for a long file title. You could also handle re-sizing the button to fit the file title by using text metrics and GetTextExtent to ensure the name fits or simply display a CToolTipCtrl when they hover the mouse over the button so they can see the full name. The CMFCButton from the MFC feature pack in VS2008+ has tool tip functionality built in so if you inherit from that instead of CButton displaying a tool tip would be as simple as calling SetTooltip(m_path)
If you want to get really fancy you could use some of the uxtheme API or new windows animation API.
You can override PreTranslateMessage() in your dialog class, and determine if the edit control was clicked that way:
CEdit m_CEditCtrl;
// ...
BOOL YourDialogClass::PreTranslateMessage(MSG *pMsg)
{
if((pMsg->wParam == VK_LBUTTON) && (m_CEditCtrl.m_hWnd == pMsg->hwnd))
{
// open your file dialog
return TRUE; // Return that the message was translated and doesn't need to be dispatched
}
return CDialog::PreTranslateMessage(pMsg);
}
Update: You can also (and it may be a better idea) to override your CEdit control's CWnd::PreTranslateMessage() function. This would require deriving a class from CEdit.
If you are using VS2008 SP1 or above, the easiest way to ask for a path is with CMFCEditBrowseCtrl. It displays an edit control with a button. The steps to use it are:
Change your edit control's class to CMFCEditBrowseCtrl
Call EnableFileBrowseButton to tell it that you want to browse for files, not folders (you can set a filter and default extension)
When the user clicks the button, a file dialog appears, and when you click OK in it, the selected path is written in the edit control.