I am making a Visual Studio MFC C++ App, and I am having a (hopefully) small problem.
I have an Edit Control text box with ID txtInputBox, and it has a value C-String variable m_inputText assigned to it. After I do a SetDlgItemText(txtInputBox, L"Hello World"); the cursor moves to the front of the text, before the 'H'. How would I get the cursor to be at the end (after the 'd') right after doing a SetDlgItemText?
I read of a SetSel method, but don't know how to implement it if that's the right one.
CEdit control MFC, placing cursor to end of string after SetWindowText
What I have is:
someDlg::someFunction() //this is used in an EN_CHANGE event
{
//some logic stuff to get a result string
SetDlgItemText(txtInputBox, L"Hello World");
//need it to set the cursor to the end
//I tried these, but it didn't recognize (expression must have class type?)
//txtInputBox.SetSel(0, -1);
//txtInputBox.SetSel(-1);
}
void someDlg::EnChangetxtinputbox()
{
someFunction();
}
you said txtInputBox is the ID to your edit control (which should be written like so: IDC_NAME), you can pass IDs to SetDlgItemText.
what they are refering to in the link you posted is a member variable, you can't pass a member variable to SetDlgItemText. you can add a variable to a control by right clicking it in editor and clicking "Add variable".
Related
First let me say that I've been searching for a solution for couple of days now...
I'm trying to get selected item for ListBox. This is my code:
CListBox * pList1 = (CListBox *)GetDlgItem(IDC_LIST1);
CString ItemSelected;
// Get the name of the item selected in the Sample Tables list box
// and store it in the CString variable declared above
pList1->GetText(pList1->GetCurSel(), ItemSelected);
MessageBox(ItemSelected, "TEST", MB_OK);
Now when i try this i get an error message saying "The Parameter is incorect"
Your code looks OK except error handling. Also MessageBox parameters look incorrect. The first parameter should be of type HWND. I believe that this is the root cause of your problems. Use MFC standard AfxMessageBox instead:
CListBox * pList1 = (CListBox *)GetDlgItem(IDC_LIST1);
int nSel = pList1->GetCurSel();
if (nSel != LB_ERR)
{
CString ItemSelected;
pList1->GetText(nSel, ItemSelected);
AfxMessageBox(ItemSelected);
}
If the CListBox is in single selection mode, the CListBox::GetCurSel will return the selected index.
If the CListBox is in multi-selection mode, you should use CListBox::GetSelItems which will return a list of indices.
You cannot mix'n'match the functions.
And always check return codes (as others already wrote).
If You already have a data member MyList(of classCListBox) :
int nSel = MyList.GetCurSel();
CString ItemSelected;
if (nSel != LB_ERR)
{
MyList.GetText(nSel, ItemSelected);
}
CWnd class has a MessageBox function which does not need a HWND parameter. But yes, AfxMessageBox is a little bit more easier to use and can be called anywhere in the MFC code without having a CWnd-derived object. And a beside note: if call a WinAPI function inside MFC code (not needed here, but possible in other cases) it's good to prepend it with scope resolution operator in order to avoid any confusion, mistake and/or name conflict (e.g. ::MessageBox...).
One possible cause for "invalid parameter" error in OP code is that it uses an ANSI string literal ("TEST") in a UNICODE build configuration. This case, must use an UNICODE string literal (L"TEST") or a little bit better, use _T macro (_T("TEST")) that makes it possible to build in both ANSI and UNICODE configurations.
As mentioned in the title, I am currently using VS 2010 C++ , MFC application for my project. Currently new to programming.
I am currently asked to create an edit box to accept names, full names, e.g "Lee Roy Long". I have looked through many other websites but I am confused with which method should I use to do it.
Is there any examples or a guide to how to go about this?
EDIT: I have another question aside from this solved one [ Cannot Post new questions due to the "restrictions"], I am currently using the same edit box to add new names as strings into the SQLite database. I am currently having some trouble converting CString to string
vector<int> userSerialNumber;
vector<string> userName;
vector<int> userID;
vector<int> userTrainingImagesNo;
Program starts here:
CString str,text;
CString Lone = _T("MEEP"); // This one converts it succesffuly...
string ss((CStringA(Lone)));/Only works for declared CStrings?
CEdit* editBox = (CEdit*)GetDlgItem(IDC_EDIT1);
editBox->GetWindowText(str);
Adding the user's input from above into the program below.
userSerialNumber.push_back(newserialnumber);
userID.push_back(newserialnumber);
userName.push_back(ss);
userTrainingImagesNo.push_back(Img);
I have referred to many websites on how to convert CStrings to strings, but none of them worked, including this one.
As I debug the program, the conversion between CString and string did not work as I get "" for string, which causes the database to update a blank "".
CString str = "name";//Name CString gotten from EditBox
std::string newname = ""; //After typing many conversion methods, results ""
Is there something that I did not notice regarding this ?
You can filter the keystrokes going into the edit control by deriving a class from CEdit and handling the WM_CHAR message in your derived class. To accept a key pass it along to CEdit::OnChar, to reject a key simply return without calling the CEdit function.
To connect the edit control to your code you use a standard MFC subclassing technique. Right-click on the control and create a control member variable (a CEdit) in the parent window. Then edit to change the variable from a CEdit to a CYourDerivedCEdit.
There is a tutorial about this and a sample project at http://www.flounder.com/validating_edit_control.htm
As an alternative to trapping each character, you can handle the CWnd::OnKillFocus event for the edit box and interrogate the value once. Validating can be done by using CString::SpanExcluding with numbers and any other character that should not be in the resulting string. For example,
CString stringEnteredByUser = _T("Lee Roy Long");
CString validatedString = stringEnteredByUser.SpanExcluding("0123456789");
if (stringEnteredByUser != validatedString)
AfxMessageBox(_T("Invalid string"), MB_OK);
The 'stringEnteredByUser' variable should contain the string entered by the user. In this example, using SpanExcluding will tell you if they've entered a number. The returned string from the call (validatedString) will not match the string the user typed (stringEnteredByUser) if they've entered a character that is invalid (ie. the character is within the list provided to the SpanExluding call).
If the validatoin fails, simply force the focus back to the edit box.
I'm assuming you know some basic event coding.
Use the Textbox.textchanged event.
Also research ASCII and its conversion (asc function.)
If you need any more help, comment below.
Good luck!
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!"));
Hello everybody reading this. Thanks in advance for your time.
One thing before question: I DO NOT use neither MFC nor Windows Forms, just WinApi in C++.
Well, I am making a polynomial calculator in Visual C++. I added a Dialog to it, which was created in resources (.rc file) using drag'n'drop method. I suppose there would be no such a problem if i created my Dialog with CreateWindowEx (but I don't want to).
My Dialog has a few of Edit Controls. Everything is fine except that when the Dialog is launched, one of Edit controls takes focus to be ready to take keyboard input.
I have included management of EN_KILLFOCUS (Edit sends it to parent when loses focus due to selecting another control).
Here I read from control to wstring (string of wide characters - _UNICODE is defined), use some kind of parser to verify this wstring and remove bad characters, and then put correct string into the same edit control. It works fine, but here is the source of my problem:
When there was no input, parser returns string "0" (not the NULL, string is just set to "0"), as if control had focus and then lost it even before I clicked anything in Dialog.
Due to that, and something else (this is what I have to figure out), at the Dialog launch parser puts this string "0" to edit.
I want to make my edit not be able to take input from keyboard until i click one of the Edits (including this one).
If it is not possible, I want to clear the whole text at the beginning of dialog (being able to take input is not a problem, I just want to prevent parser from entering string "0" at the beginning)
My code:
In DlgProc I have:
//up here is switch to manage all controls
case MyEditID: // here is ID of one of my edits from resources
switch (HIWORD(wParam))
{
case EN_KILLFOCUS: // edit lost focus - another control selected
if (LOWORD(wParam)==MyEditID) //necessary to determine if
// one of allowed Edits sent this message
// because I have also other Edits
{
GetDlgItemText(hPanel, LOWORD(wParam), MyTempWcharArray, 100);
MyTempString.assign(MyTempWcharArray);
w1 = polynomial(MyTempWcharArray); // parser takes the string
// and removes bad chars in constructor
// polynomial is my class - you don't have to care of it
// w1 is declared before as object of polynomial class
MyTempString = w1.ConversionToString();
SetDlgItemText(hDialog, LOWORD(wParam), sw1);
}
break;
}
break;
does it matter what integer number is set to Edit's ID?
I know SetFocus(), and WM_SETFOCUS message. In this case I just can't get this working.
If i haven't included something important to make you see my point please let me know. I'm sorry I'm just a newbie in WinAPI world.
EDIT:
For those with a similar problem: Do not do this:
I made an workaround with global variable ProcessKillFocus set to false indicating that instructions in message management should not be processed, except that at the end (just before break;) I am changing it to true, so next time and later it will be processed:
case EN_KILLFOCUS:
if (ProcessKillFocus && LOWORD(wParam)==MyEditID)
{
// first time global ProcessKillFocus is false so all this is skipped
// 2nd time and later do all the stuff
}
ProcessKillFocus = true;
break;
Huge thanx to Sheyros Adikari for making my question easy to understand!!!
Huge thanx to patriiice for simple answer on a huge messing question!!!
ANSWER:
BTW: patriiice, I tried this:
case WM_INITDIALOG:
SetFocus(GetDlgItem(hDialog, Desired_Control_ID));
return (INT_PTR)FALSE;
break;
IT JUST WORKS!!!
You have to return FALSE to WM_INITDIALOG message and set the correct focus by yourself.
I am using VC9, I've a CEdit control whose contents are reset to default test (say - "fill-in") at the click of a button and then I call SetFocus for the CEdit control. The problem is that the cursor blinks at the start of the default text, and i want it to blink an the end of the default string.
How can this be done?
You can use CEdit::SetSel to accomplish that.
Example:
CEdit* e = (CEdit*)GetDlgItem(IDC_EDIT1);
e->SetWindowText("hello world");
e->SetFocus();
e->SetSel(0,-1); // select all text and move cursor at the end
e->SetSel(-1); // remove selection
You can use CEdit::SetSel to accomplish that:
CEdit* e = (CEdit*)GetDlgItem(IDC_EDIT1);
e->SetWindowText("hello world");
// e->SetSel(0,-1); // you don't need this line
e->SetFocus();
e->SetSel(-1);
It will place the cursor in the end of the string.
I had a strange finding but still relevant to it.
This solution did not work for me initially. Even after calling SetSel(-1) my cursor was moving to the top of the edit box.
Then I did some code reshuffle and it started working.
The learning was that if I update any other control after updating the edit control, the cursor will move to the top of the edit box. But if edit box is the last control updated, the cursor remains in the end of the edit box.
Like I had a code something like
Add text to edit & call SetSel(-1)
update static control
And the cursor would not stay in the end. But when I changed it to
update static control
Add text to edit & call SetSel(-1)
My cursor was displayed in the end of the edit box.
I had it on my mind since the day I had this finding to update the knowledge base here. Hope it helps some random soul whose cursor jumps to top of edit box even after calling the API.