I got simple function which is defined like this:
void addEndText(HWND hEdit, LPCWSTR newText)
{
int TextLen = SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0);
SendMessage(hEdit, EM_SETSEL, (WPARAM)TextLen, (LPARAM)TextLen);
SendMessage(hEdit, EM_REPLACESEL, FALSE, (LPARAM)newText);
}
when I call it in this way:
addEndText(editHandler1, L"TEST TEXT")
everything seems to be good and work properly. But when i just do
this in this way:
addEndText(editHandler1, (LPCWSTR)buff)
where buff is char array, in my edit box appears weird characters instead of what was in buff. I know this is because of coding schema. But I dont know how can I make it working. Thanks for any respond
Assuming buff is a char[] or char*, you cannot simply type-cast it to a LPCWSTR (ie const wchar_t*). You have to convert its data from char to wchar_t, such as with MultiByteToWideChar().
Related
I am a new member and joined this site after referring to it loads of times when i was stuck with some programming problems. I am trying to code a media player (Win32 SDK VC++ 6.0) for my college project and I am stuck. I have searched on various forums and msdn and finally landed on the function GetShortPathName which enables me to play through folders and files which have a whitespace in their names. I will paste the code here so it will be much more clearer as to what i am trying to do.
case IDM_FILE_OPEN :
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFilter = "Media Files (All Supported Types)\0*.avi;*.mpg;*.mpeg;*.asf;*.wmv;*.mp2;*.mp3\0"
"Movie File (*.avi;*.mpg;*.mpeg)\0*.avi;*.mpg;*.mpeg\0"
"Windows Media File (*.asf;*.wmv)\0*.asf;*.wmv\0"
"Audio File (*.mp2;*.mp3)\0*.mp2;*.mp3\0"
"All Files(*.*)\0*.*\0";
ofn.lpstrFile = szFileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_CREATEPROMPT;
ofn.lpstrDefExt = "mp3";
if(GetOpenFileName(&ofn))
{
length = GetShortPathName(szFileName, NULL, 0);
buffer = (TCHAR *) malloc (sizeof(length));
length = GetShortPathName(szFileName, buffer, length);
for(i = 0 ; i < MAX_PATH ; i++)
{
if(buffer[i] == '\\')
buffer[i] = '/';
}
SendMessage(hList,LB_ADDSTRING,0,(LPARAM)buffer);
mciSendString("open buffer alias myFile", NULL, 0, NULL);
mciSendString("play buffer", NULL, 0, NULL);
}
return 0;
using the GetShortPathName function i get the path as : D:/Mp3z/DEEPBL~1/03SLEE~1.mp3
Putting this path directly in Play button case
mciSendString("open D:/Mp3jh/DEEPBL~1/03SLEE~1.mp3 alias myFile", NULL, 0, NULL);
mciSendString("play myFile", NULL, 0, NULL);
the file opens and plays fine. But as soon as i try to open and play it through the open file dialog box, nothing happens. Any input appreciated.
It looks like the problem is that you're passing the name of the buffer variable to the mciSendString function as a string, rather than passing the contents of the buffer.
You need to concatenate the arguments you want to pass (open and alias myFile) with the contents of buffer.
The code can also be much simplified by replacing malloc with an automatic array. You don't need to malloc it because you don't need it outside of the block scope. (And you shouldn't be using malloc in C++ code anyway; use new[] instead.)
Here's a modified snippet of the code shown in your question:
(Warning: changes made using only my eyes as a compiler! Handle with care.)
if(GetOpenFileName(&ofn))
{
// Get the short path name, and place it in the buffer array.
// We know that a short path won't be any longer than MAX_PATH, so we can
// simply allocate a statically-sized array without futzing with new[].
//
// Note: In production code, you should probably check the return value
// of the GetShortPathName function to make sure it succeeded.
TCHAR buffer[MAX_PATH];
GetShortPathName(szFileName, buffer, MAX_PATH);
// Add the short path name to your ListBox control.
//
// Note: In C++ code, you should probably use C++-style casts like
// reinterpret_cast, rather than C-style casts!
SendMessage(hList, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(buffer));
// Build the argument string to pass to the mciSendString function.
//
// Note: In production code, you probably want to use the more secure
// alternatives to the string concatenation functions.
// See the documentation for more details.
// And, as before, you should probably check return values for error codes.
TCHAR arguments[MAX_PATH * 2]; // this will definitely be large enough
lstrcat(arguments, TEXT("open"));
lstrcat(arguments, buffer);
lstrcat(arguments, TEXT("alias myFile"));
// Or, better yet, use a string formatting function, like StringCbPrintf:
// StringCbPrintf(arguments, MAX_PATH * 2, TEXT("open %s alias myFile"),
// buffer);
// Call the mciSendString function with the argument string we just built.
mciSendString(arguments, NULL, 0, NULL);
mciSendString("play myFile", NULL, 0, NULL);
}
Do note that, as the above code shows, working with C-style strings (character arrays) is a real pain in the ass. C++ provides a better alternative, in the form of the std::string class. You should strongly consider using that instead. To call Windows API functions, you'll still need a C-style string, but you can get one of those by using the c_str method of the std::string class.
I'm beginner in Win32Api, I tried to make calculator but I failed because of conversion of data types between each other
Example:
int N1 = GetDlgItemText(WID,IDC_N1,NULL,NULL);
int N2 = GetDlgItemText(WID,IDC_N2,NULL,NULL);
int RESULT = N1+N2;
MessageBox(NULL,RESULT,L"Message",MB_OK);
The example in above tell me the following error
(cannot convert parameter 2 from 'int' to 'LPCWSTR')
And the reason for this error is conversion of data types between each other
Please anybody help me
Here is correct code for your task:
wchar_t Str1[100], Str2[100], ResStr[100];
GetDlgItemText(WID, IDC_N1, Str1, 100);
GetDlgItemText(WID, IDC_N2, Str2, 100);
int N1 = _wtoi(Str1);
int N2 = _wtoi(Str2);
int RESULT = N1 + N2;
_itow(RESULT, ResStr, 10);
MessageBox(NULL, ResStr, L"Message",MB_OK);
Useful links:
http://msdn.microsoft.com/en-us/library/ms645489(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ms645505(v=vs.85).aspx
You need to pass unicode string instead of int to MessageBox.
wchar_t ResStr[100]; //define string
_itow(RESULT, ResStr, 10); //convert int result to string
MessageBox(NULL, ResStr, L"Message",MB_OK); //now display string
There is an API for this. Use GetDlgItemInt.
Your project isn't set to use Unicode, but you're passing a wide string to MessageBox. You can:
1) Change your project settings so that it defaults to Unicode; or
2) Explicitly call MessageBoxW; or
3) Remove the L, and use the non-Unicode API.
Looks like you just need to go to project>properties>configuration properties>and change 'character set' to Multi-Byte. It will probably be at Unicode, I think this will work because that's the error I always get when I try to use the WinAPI MessageBox() before changing the character set. Maybe you're trying to do something different? But this should help...
I'm trying to convert a char* to a BSTR*, and my char* has special characters in it from being encrypted. I have tried several approaches found on the web, but back in the calling vb code, I always end up with something different. I'm pretty sure this has to do with the special characters, because if I don't have them in, it seems to be ok....
my code is something along these lines...
_export myFunction(BSTR *VBtextin, BSTR *VBpassword, BSTR *VBtextout, FPINT encrypt) {
BSTR password = SysAllocString (*VBpassword);
char* myChar;
myChar = (char*) password //is this ok to cast? it seems to remain the same when i print out.
//then I encrypt the myChar in some function...and want to convert back to BSTR
//i've tried a few ways like below, and some other ways i've seen online...to no avail.
_bstr_t temp(myChar);
SysReAllocString(VBtextout, myChar);
any help would be greatly greatly appreciated!!!
Thanks!!!!
If you're manipulating the buffer, you probably don't want manipulate the char * directly. First make a copy:
_export myFunction(BSTR *VBtextin, BSTR *VBpassword, BSTR *VBtextout, FPINT encrypt) {
UINT length = SysStringLen(*VBpassword) + 1;
char* my_char = new char[length];
HRESULT hr = StringCchCopy(my_char, length, *VBpassword);
If that all succeeds, perform your transformation. Make sure to handle failure as well, as appropriate for you.
if (SUCCEEDED(hr)) {
// Perform transformations...
}
Then make a copy back:
*VBtextout = SysAllocString(my_char);
delete [] my_char;
}
Also, have a read of Eric's Complete Guide to BSTR Semantics.
I tried this:
int editlength;
int buttonid = 3324; // id to button, the numbers dont mean anything
int editid = 5652; // id to edit
LPTSTR edittxt;
HWND button; // created in wWinmain as a button
HWND edit; // created in wWinMain as an edit control
// LRESULT CALLBACK WindowProc
switch(uMsg)
{
case WM_COMMAND:
if(wParam == buttonid)
{
filedit = GetDlgItem(hwnd, editid); // I tried with and without this
editlength = GetWindowTextLength(filedit);
GetWindowText(filedit, edittxt, editlength);
MessageBox(hwnd, edittxt, L"edit text", 0);
}
break;
}
But I get don't see any text in the message box.
The last argument to GetWindowText() is the size of your buffer. Since you set it to the length of the string, you are telling the function that your buffer is too small because there's no room for the null terminator. And nothing gets copied.
In addition, you must already allocate the buffer to hold the copy of the text. What does edittxt point to? I don't even see where you initialize it.
Correct usage would look something like this:
TCHAR buff[1024];
GetWindowText(hWndCtrl, buff, 1024);
edittxt needs to be a pointer to a buffer that gets the text.. so try this...
char txt[1024];
....
GetWindowText(filedit, txt, sizeof(txt));
You may have to adjust for unicode.. sorry its been a while since I did raw win32.
i have a function like this:
BOOL WINAPI MyFunction(HDC hdc, LPCWSTR text, UINT cbCount){
char AnsiBuffer[255];
int written = WideCharToMultiByte(CP_ACP, 0, text, cbCount, AnsiBuffer , 0, NULL, NULL);
if(written > -1) AnsiBuffer[written] = '\0';
if(written>0){
ofstream myfile;
myfile.open ("C:\\example.txt", ios::app);
myfile.write(AnsiBuffer, sizeof(AnsiBuffer));
myfile.write("\n", 1);
myfile.close();
}
....
When i display the input LPCWSTR text with MessageBoxW(), the text shows up fine. When i try to convert it to multibyte, the return value looks normal (ex: 22, 45, etc), but the result is strings of gibberish (ex ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ). Suggestions?
I see two problems;
1) You are passing '0' to WideCharToMultiByte for the size of the multibyte buffer. If you read the documents this results in the function returning the NUMBER of bytes needed but performing no actual conversion. (This is to allow you to subsequently allocate a buffer of the correct size and recall the function).
2) in file.write sizeof(AnsiBuffer) will result in 255 bytes being written regardless of what is in the buffer. sizeof is a compile-time calculation that returns the size of a variable. You should replace this with the 'written' variable that represents the length of the string.
You need to pass the length of the buffer to the API, instead of passing 0. When you pass 0, the function returns the required length of the buffer, but doesn't write to it. You're seeing the results of the uninitialized array.
Here's the right call, with the 255 in the right place:
int written = WideCharToMultiByte(CP_ACP, 0, text, cbCount, AnsiBuffer , 255, NULL, NULL);