Win32 - Chinese/Korean/?

I followed a tutorial to make a simple Win32 application. I followed the steps exactly except for 2 things, which I'll bold in the code I post. The reason they are there is because the program wouldn't compile in Microsoft Visual Studio unless I did the cast. Here's the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <windows.h>

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM); //Prototype for action function

#define IDBUTTON 102

char szClassName[] = "MyFirstFrogram";
HINSTANCE g_hInst;

int WINAPI WinMain(HINSTANCE hThisInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpszArgument,
				   int nFunsterStil) {
   HWND hwnd; //Handle for window
   MSG messages; //Messages sent to application
   WNDCLASSEX wincl; //Window Class

   g_hInst = hThisInstance; //Save the instance in global variable
   wincl.hInstance = hThisInstance; //Register instance to the class
   wincl.lpszClassName = (LPCWSTR)szClassName; //Set class name
   wincl.lpfnWndProc = WindowProcedure; //Set procedure function
   wincl.style = CS_DBLCLKS; //Set style?
   wincl.cbSize = sizeof(WNDCLASSEX); //Set Size?

   wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION); //Set defauly icon
   wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION); //Set default small icon
   wincl.hCursor = LoadCursor(NULL, IDC_ARROW); //Set default cursor
   wincl.lpszMenuName = NULL; //No menu
   wincl.cbClsExtra= 0; //No extra bytes?
   wincl.cbWndExtra = 0; //?

   wincl.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); //Background color

   if(!RegisterClassEx(&wincl)) {
	   return 0;
   }

	hwnd = CreateWindowEx(
			0, //?
			(LPCWSTR)szClassName, //Class Name
			(LPCWSTR)"My First Program =O", //Title
			WS_OVERLAPPEDWINDOW, //Default window?
			CW_USEDEFAULT, //These two are for
			CW_USEDEFAULT, //the window's placement
			230, //height
			75, //width
			HWND_DESKTOP, //The desktop is the parent
			NULL, //No Menu
			hThisInstance, //The program instance
			NULL); //No creation data?

	ShowWindow(hwnd, SW_SHOW); //Show Window
	UpdateWindow(hwnd); //Update window data?

	while(GetMessage(&messages, NULL, 0, 0)) {
		TranslateMessage(&messages); //Translate
		DispatchMessage(&messages); //Send to procedure
	}

	return messages.wParam; //Should be 0 from PostQuitMessage()
}

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
	HWND hwndButton;
	switch(message) {
		case WM_COMMAND: {
			if(((HWND)lParam) && (HIWORD(wParam) == BN_CLICKED)) {
				int iMID;
				iMID = LOWORD(wParam);
				switch(iMID) {
					case IDBUTTON: {
						MessageBox(hwnd, (LPCTSTR)"You just pushed me!", (LPCTSTR)"My Program =)",
							MB_OK|MB_ICONEXCLAMATION);
						break;
					}
					default:
						break;
				}
			}
			break;
		}
		case WM_DESTROY: {
			PostQuitMessage(0); //Send Message to Shut Down Program
			break;
		}
		case WM_CREATE:{
			hwndButton = CreateWindowEx(0,
										TEXT("BUTTON"), //Class name
										TEXT("Push Me"), //Button Text
										WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON, //Styles
										10, //Position from left
										10, //position from top
										200, //Width
										30, //Height
										hwnd, //Parent window
										(HMENU)IDBUTTON, //Action Command
										g_hInst, //Applicaton instance
										NULL); //?
			break;
		}
		default: {
			return DefWindowProc(hwnd, message, wParam, lParam); //default actions
		}
	}

	return 0;
}


The code works fine, but when I launch the debug and it loads, all the text besides the works "Push Me" on the button are displayed in something like Korean or Chinese or something like that.

Is there a reason for this? If so, how can I make it English?
Is there a reason for this?


Yes. You're doing a bad cast.

Never cast around compiler errors unless you're sure it's the right solution. Compiler errors are telling you that there's a problem. If you just cast the problem away, you're telling the compiler "shut up, I know what I'm doing".

The problem is your project is set up to be a Unicode build and you're not being Unicode friendly. Either change it to an ANSI build, or get Unicode friendly.

See this article:

http://cplusplus.com/forum/articles/16820/
I read through that page and I think I see what's going on.

I was using a tutorial and just following it's directions. They didn't do anything about the Unicode thing, so I didn't even know it was an issue =/

Thanks for that link though, really helpful.

What I've done to fix it is these three steps:

1) Removed casts on lines 40, 41, and 72 (the tutorial actually had the ones on 72).

2) Changed char szClassName[] = "MyFirstFrogram"; to wchar_t szClassName[] = L"MyFirstProgram"; on line 7.

3) Add L in front of "My First Program =O" on line 41, and the two strings on 72 that previously had the cast.

Those edits made it English, and I'm hoping those are the correct steps.

Obviously, that tutorial is not a very good one, so I won't be using it anymore.

Thank you for your help.
1) Removed casts on lines 40, 41, and 72 (the tutorial actually had the ones on 72).


Ugh... really? Yeah I guess that tutorial author didn't know the first thing about the whole TCHAR thing.



You're taking the wchar_t route which is fine, but then ANSI builds won't work (not that that's a big deal).

It might be better to go the TCHAR route so you can make ANSI or Unicode builds. You already have some TCHAR stuff in your program (see line 88).


A different way to fix would be:

1) Remove the casts as you did
2) change char szClassName[] = "MyFirstProgram"; to TCHAR szClassName[] = _T("MyFirstProgram"); (or TEXT() instead of _T())
3) Put _T() (or TEXT()) around "My First Program =O" on line 41 and 72


the idea is that TCHAR can be either char or wchar_t depending on whether or not it's a Unicode or ANSI build.

But if you're always building Unicode then it doesn't matter, and the wchar_t approach will be fine.
You'll find that the link suggests declaring strings as _T("my string") rather than L"my string".

I'd also suggest using TCHAR rather than wchar_t and define _UNICODE on the command line, or select Unicode Project if using Visual Studio.

This is the conventional way to do it in Window.
Last edited on
I wouldn't just throw away that tutorial if I were you. If its the one I'm thinking its not a bad tutorial (the Forger's one?). What the issue really is, is that you are likely using Visual Studio Express, and that is setup to default to UNICODE builds, so if you paste tutorial code in it that isn't using the TCHAR macros there will be problems.
I actually was thinking about using the TCHAR, but the prototypes for the functions took LPCWSTR, and that link talked about LPCTSTR with the T for TCHARs, but I get it now. I'm going to use TCHARs instead of what I did.

I am using Visual Studio Express, so that explains all of that.

Thank you all for your help and suggestions, you're helping me understand everything a lot better.
LPCWSTR is a long pointer to a constant wide string, always a wide string.
LPCTSTR is a long pointer to a constant string, wide if _UNICODE defined, ASCII if it's not.

The long is historical, you can ignore it.
Topic archived. No new replies allowed.