How to copy data from a stream to a LPCTSTR variable? - c++

I'm absolutely new to programming. I searched for this question online but couldn't find it anywhere
I'm trying to create window based MFC application using Visual studio 13. I have implemented an OpenFileDialog and obtained the path and file name in a stream.
Now I need to make it appear in a edittext box using the function SetWindowText. It accepts parameter of type LPCTSTR. So how do I make the conversion or Is there any other better approach for this problem?
Thanks in advance!

Don't mess around with dynamic allocation here. Simply get the string of the stream and put it into a CString.
It has an operator LPCTSTR for this purpose.
#include <atlstr.h> //CString
CString csText;
.SetWindowText(csText);

Related

Winapi - passing LPWCSTR as LPCSTR

I use CreateWindowEx which expands to CreateWindowExA. That function uses LPCSTR types. I would like to pass as a second argument MSFTEDIT_CLASS (from Richedit.h):
#define MSFTEDIT_CLASS L"RICHEDIT50W"
The following casting doesn't work:
(LPCSTR)MSFTEDIT_CLASS
CreateWindowEx returns NULL. It works when I pass the second argument this way:
"RICHEDIT50W"
but I don't want to copy a string from the header. How to fix that ?
There is only a single, viable solution here: Call CreateWindowExW, either directly or by defining the UNICODE preprocessor symbol and have the generic-text mapping CreateWindowEx expand to CreateWindowExW.
The window you are creating is a Unicode window, always. The character set used for communicating with a window is set at class registration time. The window class named "RICHEDIT50W" is registered using RegisterClassExW by the system. You don't have control over this.
Since you are eventually going to have to talk to the window using messages, you will need to use the Unicode variants of the message handling functions (GetMessageW, DispatchMessageW, etc.). You cannot use the ANSI versions, unless you are happy with an application, that sometimes doesn't fail.

MFC C++ CListBox get selected item

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.

MFC C++ VS 2010 : Edit Box to accept only alphabets, backspace and spaces

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!

Cannot match the parameter list for MessageBox::Show

I'm attempting to display the Error message denoted by the code given to me by GetLastError() and formatted by FormatMessage() within a MessageBox. (Using C++/CLI)
However for some reason I just can't match the argument list of MessageBox::Show.
I'm attempting to replicate a solution provided by Doron Moraz in this forum thread:
http://forums.codeguru.com/showthread.php?478858-GetLastError()-in-a-MessageBox()
However when I attempt to compile my code I get:
'System::Windows::Forms::MessageBox::Show' : none of the 21 overloads could convert all the argument types
1> c:\program files (x86)\reference assemblies\microsoft\framework\.netframework\v4.0\system.windows.forms.dll: could be 'System::Windows::Forms::DialogResult System::Windows::Forms::MessageBox::Show(System::String ^,System::String ^,System::Windows::Forms::MessageBoxButtons,System::Windows::Forms::MessageBoxIcon)'
1> c:\program files (x86)\reference assemblies\microsoft\framework\.netframework\v4.0\system.windows.forms.dll: or 'System::Windows::Forms::DialogResult System::Windows::Forms::MessageBox::Show(System::Windows::Forms::IWin32Window ^,System::String ^,System::String ^,System::Windows::Forms::MessageBoxButtons)'
1> while trying to match the argument list '(int, LPCTSTR, const wchar_t [6], long)'
As you can see below my code is fairly similar to the solution provided at the link. only I get the above error. The question is, Why? (see my code below).
if((m_hglrc = wglCreateContext(m_hDC)) == NULL)//if the creation of a wgl context fails
{
MessageBox::Show("wglCreateContext Failed");//let us know
void* lpBuffer; //create a buffer to hold our error message
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, // It´s a system error
NULL, // No string to be formatted needed
::GetLastError(), // Hey Windows: Please explain this error!
MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), // Do it in the standard language
(LPTSTR)&lpBuffer, // Put the message here
0, // Number of bytes to store the message
NULL);
System::Windows::Forms::MessageBox::Show( NULL, (LPCTSTR)lpBuffer, _T("Error"),MB_OK|MB_ICONWARNING);
// Free the buffer.
if(lpBuffer)LocalFree(lpBuffer);
return 0;
}
In case it's relevant, my includes are:
#pragma once
#include <Windows.h>
#include <GL/gl.h>
#include<tchar.h>
using namespace System::Windows::Forms;
Thanks in advance,
Guy
It looks like you've solved this by switching to the unmanaged API, but here's how you'd use the managed one.
If you're going to use the a managed API, you'll want to use managed objects. In your call to MessageBox::Show, you have several unmanaged objects. According to the error message, it interpreted your parameters like this:
MessageBox::Show( NULL, (LPCTSTR)lpBuffer, _T("Error"),MB_OK|MB_ICONWARNING);
// seen by compiler as: int, LPCTSTR, const wchar_t [6], long
Here's the method I think you're trying to call in the MessageBox class:
Show(IWin32Window^ owner, String^ text, String^ caption,
MessageBoxButtons buttons, MessageBoxIcon icon)
NULL is generally #defined as 0, which is an integer. To produce a proper null pointer in C++/CLI, you want to use nullptr.
Both lpBuffer and "Error" need to be managed string objects.
For lpBuffer, you can just do gcnew String(lpBuffer), and it'll invoke the proper constructor (the one that takes a wide or narrow character pointer).
For "Error", just remove the _T(). The compiler will figure out that you want a managed string object and will provide one containing "Error".
In the managed API, the buttons & icon are contained in separate enums. You're referencing the unmanaged integer values here. You'll want to replace this with separate parameters for MessageBoxButtons and MessageBoxIcon.
Once all that is done, here's the final call:
MessageBox::Show(nullptr, gcnew String(lpBuffer), "Error",
MessageBoxButtons::OK, MessageBoxIcon::Warning);
However, we can do a little better: If you're not going to pass in a owner window, don't call the API that has a owner window parameter, call the API that doesn't.
MessageBox::Show(gcnew String(lpBuffer), "Error",
MessageBoxButtons::OK, MessageBoxIcon::Warning);

visual c++ copy textbox content

how to copy textbox->Text content in a char array?
i m working in vc++.
Use CWnd::GetWindowText()
CString str;
CWnd* pWnd = GetDlgItem(IDC_WHATEVER);
pWnd->GetWindowText(str);
Puts the contents of the control into the CString or you can use the array version:
TCHAR sz[10];
int nRet = pWnd->GetWindowText(sz, 10);
Your query is unclear, so I'll have to assume things.
Assuming you are using MFC, add a control type variable to your edit box (say m_Edit), and use m_Edit.GetWindowText() to get the text.
Or if you're using plain Win32, use the GetWindowText() Win32 API.
On an additional note, like another user pointed out, stop using things like fixed-size character arrays to store strings if you are using c++. Use something like std::string or use CString if you're using MFC. By doing so, you can manipulate strings much easily and your code will be less error prone.
Cheers, Rajesh. MVP, Visual C++
You can also try like this.....
CString csTbxName;
GetDlgItemText(IDC_EDIT1,csTbxName);
const char* pchTbxName = csTbxName.GetBuffer();
char chTbxNameDup[5000];
ZeroMemory(chTbxNameDup,5000);
if(csTbxName.GetLength() < 5000)
{
memcpy(chTbxNameDup,(void*)pchTbxName,csTbxName.GetLength());
}