How can I make calculator using (native Win32 API)? - winapi

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...

Related

QLocale detects system language incorrectly on Windows with language pack installed

I am attempting to detect current system language with QLocale:
QLocale::Language sysLangId = QLocale::system().language();
However, it's not working correctly. I'm on Russian Windows 7 with English language pack applied, but language() returns Russian instead of English. Is there any workaround?
When I was working on Localization in Qt, I used
QString locale = QLocale::system().name();
When I tested getting the locale, I found it was dependent on the Format in the Region and Language settings:
Control Panel > Region and Language > Format
Hope that helps.
I've found 2 ways to solve my problem. The Qt way is to use QLocale::system().uiLanguages().
On my system it returns a list with a single item "en-US". The problem with that is I need a language name, like "english", so I'd have to add a map for converting language code to language name. It's no big deal, but I've decided to use WinAPI:
QString sysLangName;
const LANGID langId = GetUserDefaultUILanguage();
WCHAR langName[1000] = {0};
if (GetLocaleInfoW(MAKELCID(langId, SORT_DEFAULT), LOCALE_SENGLANGUAGE, langName, sizeof langName / sizeof langName[0] - 1) != 0)
sysLangName = QString::fromWcharArray(langName);
I had the same problem and I solved with this code.
QString local = QLocale::languageToString(QLocale::system().language());
To get the language name you can simply use QLocale::languageToString(QLocale::system().language()); or maybe QLocale::system().nativeLanguageName(); but the real problem is as you mentioned that the QLocale::system() does not always match the actual system locale on windows. This can be observed if you change the locale during program execution. In this case the QLocale::system() does not get up-to-date and returns the old value. Here is a workaround I used in Qt5:
class WinEventFilter : public QAbstractNativeEventFilter
{
public:
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result)
{
if (((MSG*)message)->message == WM_WININICHANGE )
{
// Workaround - in Qt5 the system locale is not up to date and we have to manually update it.
#ifdef _DEBUG
QLibrary lib("Qt5Cored.dll");
#else
QLibrary lib("Qt5Core.dll");
#endif
void (* func)() = lib.resolve("?updateSystemPrivate#QLocalePrivate##SAXXZ");
if (func)
func();
else
qDebug()<<"! Unable to resolve updateSystemPrivate()";
// Workaround end
qDebug()<<"WM_WININICHANGE"<<QLocale::languageToString(QLocale::system().language());
}
return false;
}
};
and my application class constructor looks like this:
MyApplication::MyApplication( int & argc, char ** argv )
: QApplication(argc, argv)
{
WinEventFilter *pFilter = new WinEventFilter(this);
installNativeEventFilter(m_pEventFilter);
}
Hope this helps.

Display the char* value in VS textbox C++

I apologise beforehand if this has been asked many times but the problem is I cannot find the exact match to my question on here or Google in general.
I am trying to use VS C++ 2010 (windows form project) and cannot find a reasonable way to display a simple string (using char *variablename) in a textbox.
I pretty much worked out how to get anything else into the textbox:
String^ word1 = "hello";
int num1 = 23;
double num2 = 24.6;
float num3 = 25.9;
//The above 4 work but the next 2 do not
char *word2 = "hello";
string word3 = "hello"; //I have included <string>!
textBox1->Text = Convert::ToString(variablename);
If I use char* it outputs "true" and if I use string it just does not seem to be able to convert it.
The reason why I want to use either char* or string is because you cannot use String^ in a class! If I could use String^ in a class then I would but it is managed code.
Could anyone inform me as to how I get around this problem?

EnumWindows strange behaviour

I am trying to use MFC with visual Studio 2012 on Windows 8.
I have the following code:
BOOL CALLBACK EWP(HWND hwnd, LPARAM lParam)
{
int txtlen = GetWindowTextLengthW(hwnd);
std::wstring s;
s.reserve(txtlen + 1);
GetWindowText(hwnd, const_cast<wchar_t*>(s.c_str()), txtlen);
return TRUE;
}
EnumWindows(EWP, 0);
What happens is that the very first string comes out as "Task Switchin" and the rest come out as "". I get about 330 of these strings. I have tried without using that weird string method too with just char buff[300], same story.
Can someone please tell me whats going on?
Your last argument to GetWindowText() is off-by-one. From the MSDN article description of that argument:
Specifies the maximum number of characters to copy to the buffer, including the NULL character. If the text exceeds this limit, it is truncated.
Pass txtlen+1 to fix.

How to use VerQueryValue?

I've an exe that will need to retrieve version infomation from a specific dll (ex : FileDescription). My codes already called the GetFileVersionInfoSize and GetFileVersionInfo. But I'm not sure how to apply the VerQueryValue, even after going through http://msdn.microsoft.com/en-us/library/ms647464(v=vs.85) and other examples.
Can someone explain/shed some light on how to apply VerQueryValue and its usage? Thanks.
To get the FileDescription via VerQueryValue, just copy and paste the example code from the VerQueryValue documentation, and modify it as appropriate.
The basic idea behind that example code is:
Use the second form (\VarFileInfo\Translation) to get the list of translations.
Then use the third form (\StringFileInfo\lang-codepage\string-name) to get the string(s).
(The first form () is just for the VS_FIXEDFILEINFO, a set of numerical values for parts of the version number, the flags, etc.)
The example code gets the FileDescription for each language. If you know you only have one language (e.g., because you're looking at your own app, and it isn't translated), you can skip the loop and just return the first one. For more general use, you want to pick the best match for the user's language and return that one.
This is a working example, after many try and errors. I'm using Borland C++, so minor details may need to be changed for incompabible environments.
#include <Windows.h>
std::string GetAppVersion()
{
DWORD dwHandle;
TCHAR fileName[MAX_PATH];
GetModuleFileName(NULL, fileName, MAX_PATH);
DWORD dwSize = GetFileVersionInfoSize(fileName, &dwHandle );
TCHAR buffer[dwSize];
VS_FIXEDFILEINFO* pvFileInfo = NULL;
UINT fiLen = 0;
if ((dwSize > 0) && GetFileVersionInfo(fileName, dwHandle, dwSize, &buffer))
{
VerQueryValue(&buffer, L"\\", (LPVOID*)&pvFileInfo, &fiLen);
}
if (fiLen > 0)
{
char buf[25];
int len = sprintf(buf, "%hu.%hu.%hu.%hu",
HIWORD(pvFileInfo->dwFileVersionMS),
LOWORD(pvFileInfo->dwFileVersionMS),
HIWORD(pvFileInfo->dwFileVersionLS),
LOWORD(pvFileInfo->dwFileVersionLS)
);
return std::string(buf, len);
}
else
{
return std::string("(Unknown)");
}
}

scanf_s throws exception

Why does the following code throw an exception when getting to the second scanf_s after entering an number to put into the struct.
This by no means represents a complete linked list implementation.
Not sure how to get onto the next scanf_s when having entered the value? Any ideas?
EDIT: Updated code with suggested solution, but still get an AccessViolationException after first scanf_s
Code:
struct node
{
char name[20];
int age;
float height;
node *nxt;
};
int FillInLinkedList(node* temp)
{
int result;
temp = new node;
printf("Please enter name of the person");
result = scanf_s("%s", temp->name);
printf("Please enter persons age");
result = scanf_s("%d", &temp->age); // Exception here...
printf("Please enter persons height");
result = scanf_s("%f", &temp->height);
temp->nxt = NULL;
if (result >0)
return 1;
else return 0;
}
// calling code
int main(array<System::String ^> ^args)
{
node temp;
FillInLinkedList(&temp);
...
You are using scanf_s with incorrect parameters. Take a look at the examples in the MSDN documentation for the function. It requires that you pass in the size of the buffer after the buffer for all string or character parameters. So
result = scanf_s("%s", temp->name);
should be:
result = scanf_s("%s", temp->name, 20);
The first call to scanf_s is reading garbage off the stack because it is looking for another parameter and possibly corrupting memory.
There is no compiler error because scanf_s uses a variable argument list - the function doesn't have a fixed number of parameters so the compiler has no idea what scanf_s is expecting.
You need
result = scanf_s("%d", &temp->age);
and
result = scanf_s("%f", &temp->height);
Reason is that sscanf (and friends) requires a pointer to the output variable so it can store the result there.
BTW, you have a similar problem with the parameter temp of your function. Since you're changing the pointer (and not just the contents of what it points to), you need to pass a double pointer so that the changes will be visible outside your function:
int FillInLinkedList(node** temp)
And then of course you'll have to make the necessary changes inside the function.
scanf() stores data into variables, so you need to pass the address of the variable (or its pointer)Example:
char string[10];
int n;
scanf("%s", string); //string actually points to address of
//first element of string array
scanf("%d", &n); // &n is the address of the variable 'n'
%19c should be %s
temp->age should be &temp-age
temp->height should be &temp->height
Your compiler should be warning you
about these errors
I believe you need to pass parameters to scanf() functions by address. i.e. &temp->age
otherwise temp-age will be interpreted as a pointer, which will most likely crash your program.

Resources