I am working with CDialogs and mfc. My dialog loads, and there are two input boxes and a button. When i click the button I want to have the values in the input boxes change. My current attempt is this
void
CInstanceNumberDlg::updateLeftRange(int i) {
GetDlgItem(IDC_2NDDERIV_WT)->SetWindowText((LPCTSTR)i);
UpdateData(false);
UpdateWindow();
}
I have also tried with other combinations of including UpdateData() and UpdateWindow(). This method is being reached with a valid integer, and that ID should be valid.
How can i get the value in the input box to be modified?
Thank you
Your problem is this line:
GetDlgItem(IDC_2NDDERIV_WT)->SetWindowText((LPCTSTR)i);
i is not a pointer to a string and so you should not be casting it to an LPCTSTR. What you need to do convert the value of i to a string and then pass a pointer to the resulting string to SetWindowText(). And I don't believe you need UpdateData() or UpdateWindow(). For example:
void CInstanceNumberDlg::updateLeftRange(int i)
{
TCHAR tszValue[32];
StringCchPrintf(tszValue, _countof(tszValue), TEXT("%d"), i);
GetDlgItem(IDC_2NDDERIV_WT)->SetWindowText(tszValue);
}
Related
My code:
//the auto generated stuff (by right-click on editbox add variable to control option)
CEdit edit_name;
void CSendMessageWithActualDataDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT_NAME, edit_name);
}
Looks OK so far, right?
void dofoo()
{
//IDE shows error squiggle at dot "name.GetWi" with no pop-up
//details given except the object's blurb text
CString foostring= edit_name.GetWindowTextW();
//error C2661: 'CWnd::GetWindowTextW': no overloaded function takes 0 arguments
// or instead with no parentheses added:
// no IDE error indication
CString foostring= edit_name.GetWindowTextW;
//error C3867: 'CWnd::GetWindowTextW': non-standard syntax; use '&' to create a pointer to member
}
According to:
Read text from edit control in MFC and VS2010
You can then retrieve the text in the edit box like this:
CEdit m_EditCtrl;
// ....
CString filePath1 = m_EditCtrl.GetWindowText()
.
.
.
// Yes, now it works...
I swear, this is like pulling teeth.
Apparently, this is all about convenience. Since you already know how to call CWnd::GetWindowText, but find it too cumbersome to use, just wrap everything up in a free function:
CString GetWindowText(CWnd const& wnd) {
CString s;
wnd.GetWindowText(s);
return s;
}
You can call that, passing in any object that (publicly) derives from CWnd (such as the CEdit edit_name) and get a CString object you can use any which way. (C++17 introduced guaranteed copy elision, meaning that s will never need to get copied.)
If you need to pass it into other Windows API functions that expect an LPCTSTR, CString implements operator PCXSTR that implicitly converts things as needed, e.g.
AfxMessageBox(GetWindowText(edit_name));
When you add a EDIT control to a dialog, and you go to map it to a variable, you have two choices:
Control
Value
If you select Value, then you can map it to a CString:
This creates the DDX_Text entry that was referred to in the comments:
void CTestDialogDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_strText);
}
Or, you can use GetDlgItemText if you want to just get the value directly from the control, and avoid creating a variable. This shows both:
void CTestDialogDlg::OnBnClickedButton1()
{
// This way you get the current text value from the edit control, without even creating a CEdit control member variable
CString strText;
GetDlgItemText(IDC_EDIT1, strText);
AfxMessageBox(strText);
// This way we use our mapped CString to the EDIT control
UpdateData(TRUE);
AfxMessageBox(m_strText);
}
If you do decide to map to a CEdit (a Control instead of a Value) then as you found out:
// Get the value from the control
m_editText.GetWindowText(strText);
AfxMessageBox(strText);
I assume your linked article is incorrect as GetWindowText does not return a CString.
By the way, with Visual Assist (a third-party extension) it shows the options correctly for Intellisense:
By the way, you may find this article useful (Dialog box controls and variable types). If you look at the table and find EDIT:
The above is with the previous rows on the table stripped out. As you can see, you can map the EDIT to more types of variables than just a CString.
this suffices:
class GetWindowText
{
CString s;
public:
GetWindowText(CWnd &w){w.GetWindowText(s);}
~GetWindowText() {}
CString operator()() {return s;}
};
just call like this:
MessageBoxW(GetWindowText(edit_name)());
hello guys I was plc programmer just trying to start C++ programmer
I am trying to convert to this code to function
m_file.Open(posText[7], CStdioFile::modeRead);
m_file.ReadString(posValue[7]);
UpdateData(TRUE);
dlg.s_PostionZ2 = posValue[7];
UpdateData(FALSE);
m_file.Close();
and this my function but it didn't work
void mainDial::opeFile(CString path, CString value, CString location)
{
slaveDialog dlg;
m_file.Open(path, CStdioFile::modeRead);
m_file.ReadString(value);
AfxMessageBox(location);
UpdateData(TRUE);
location = value;
UpdateData(FALSE);
m_file.Close();
}
what I am trying to do is just open a file and save to value and change location value
the problem is the location is in the other dialog (SlaveDialog dlg;)
it is ok by just simply enter dlg.S_position
but if I want it to do with using a function to pass the location like this
opeFile(posText[0], posValue[0], _T("dlg.s_PostionX1"));
or
opeFile(posText[0], posValue[0], dlg.s_PostionX1);
it didn't work both way so how can I change to my function work
thank you for reading
what I am trying to do is just open a file and save to value and change location value
You are passing in the function's output parameters by value, so they make copies of the caller's values. Any changes the function makes to the parameters is done to the copies and not reflected back to the caller.
To do what you want, you need to pass in the output parameters by reference instead, eg:
void mainDial::opeFile(CString path, CString& value, CString& location)
if I have a CustomContainer with 2 Text Areas, is it possible to update the text for those text areas at run-time? please note that the custom container is in a scroll list.
Yes it is possible. Maybe this late answer can help someone.
I have a screen with a list of custom widgets of actual failures.
The custom container has 4 text areas: date, time, error component, error text.
Here I set the texts in 3 ways, the text for date and time is generated from a numeric time value, the text for the caption is read from the resource, and the text for the error details text is read from the resource but values are filled in afterwards.
After the content on the screen is invalidated, either by scrolling or by calling invalidate, a callback function xxxUpdateItem is called automatically from touchgfx runtime. You have to override and implement it in your view class of the screen.
This function is called with a reference to your custom widget and the actual index of the current item, like this:
void MessageScreenView::scrollList1UpdateItem(CustomContainerFailureOrInfo& item, int16_t itemIndex)
From this you call a function of the custom widget which sets the new texts, e.g.:
void CustomContainerFailureOrInfo::setDetails(uint16_t itemIdx, uint32_t dateTime, uint16_t captionTextId, uint16_t detailTextId, const char16_t * templateF1, float f1, const char16_t * templateF2, float f2)
{
setDateTime(dateTime);
setCaption(captionTextId);
setDetailText(detailTextId, templateF1, f1, templateF2, f2);
}
Text for Date and time is generated from a time_t value.
The caption is read from the resource with the text widget's setTypedText function, e.g.:
void CustomContainerFailureOrInfo::setCaption(TypedTextId t)
{
caption.setTypedText(TypedText(t));
caption.setWideTextAction(WIDE_TEXT_WORDWRAP);
caption.invalidate();
}
I had the problem, that some error messages should show error related values, while others should only show plein text. I solved it by using value wildcards and passing a format string and a value:
void CustomContainerFailureOrInfo::setDetailText(TypedTextId t, const char16_t * templateF1, float f1, const char16_t * templateF2, float f2)
{
text.setTypedText(TypedText(t));
Unicode::snprintf(textBuffer1, TEXTBUFFER1_SIZE, "");
if (templateF1)
{
if (awiStrUtil::isPrintfFloatContained16(templateF1))
{
Unicode::snprintfFloat(textBuffer1, TEXTBUFFER1_SIZE, reinterpret_cast<const Unicode::UnicodeChar *> (templateF1), f1);
}
else
{
// attention: (const char16_t*)
Unicode::snprintf(textBuffer1, TEXTBUFFER1_SIZE, reinterpret_cast<const Unicode::UnicodeChar *> (templateF1));
}
}
// similar code removed: if (templateF2) ...
text.setWideTextAction(WIDE_TEXT_WORDWRAP);
text.invalidate();
}
Alright so I have an edit control and a static text control. When the user clicks a button, I want the program to take the text from the edit control and add it to the text in the static text control and then set that new value as the text in the static control. So I have a function that appends the buffers to one another but my program doesn't seem to be working. This is what I have:
//when button message is recieved:
SendMessage(hwndEditControl, WM_GETTEXT,255,(LPARAM)editbuffer);
GetWindowText(hwndTextControl, (LPWSTR)allText, GetWindowTextLength(hwndTextControl));
allText = appendStrings((char*)editbuffer, (char*)allText);
SetWindowText(hwndTextControl, (LPCWSTR)allText);}
// where appendStrings is defined as:
char* appendStrings (char* buffer1, char* buffer2)
{
std::string string1(buffer1), string2(buffer2);
std::string string3 = string1 + string2;
return (char*)string3.c_str();
}
//and
static char* editbuffer = new char;
static char* allText = new char; //these are defined as so
So anyway, when I push the button, I'm pretty sure that the appendStrings function is working because I think it takes what is in the editbox and adds it to the Text box. The reason I say "i think" though is because the string in the text box is always just jibberish. Its sometimes random symbols or just these "l's" (or what look like "L"s). I think it's a problem with my pointers but I'm not sure. I'm new to this so if there is an easier way, please tell me.
You're returning a pointer to a temporary that's being destroyed before the function returns.
Instead of returning a char *, return a std::string.
The following snippet is from the OnChange() handler of a multiline CEdit control, which has "WantReturn" set.
void DLG::OnChangeEditPrepareTape()
{
CString ss;
std::vector<char> aTape;
m_prepareTape.GetWindowText(ss);
m_prepareTape.SetWindowText(ss);
}
If the SetWindowText() is commented out, the user’s text builds up on the right, and all is well. But, with it in, the text insertion point moves to the left edge, and the user’s characters go in to the left of the existing characters..
I want to put some tinkering text between the two calls, and can get what I want by subclassing CEdit. But I’d be interested to know if there is a way of doing it by Get() & Set().
I’m using Visual C++ 6, with Service Pack 5. Eleven years old now, but then “Software does not wear out” as they say:-).
The insertion point is reset by SetWindowText() because, from the control's point of view, its whole text content has just been reset (possibly to the empty string), and both the insertion point and the current selection might not be meaningful enough to keep them around.
You can use GetSel() and SetSel() to implement this behavior yourself:
void DLG::OnChangeEditPrepareTape()
{
CString ss;
std::vector<char> aTape;
int start, end;
m_prepareTape.GetSel(start, end);
m_prepareTape.GetWindowText(ss);
// Tinker with the text...
m_prepareTape.SetWindowText(ss);
m_prepareTape.SetSel(start, end);
}
You can you use GetSel to retrieve the cursor position before you replace the text, and SetSel to place it in the same location afterwards.
void DLG::OnChangeEditPrepareTape()
{
CString ss;
int start, stop;
std::vector<char> aTape;
m_prepareTape.GetWindowText(ss);
m_prepareTape.GetSel(&start, &stop);
m_prepareTape.SetWindowText(ss);
m_prepareTape.SetSel(start, stop);
}
If you modify the text before you put it back in the text box, you can increment or decrement start (and end) accordingly.