Jump to content


Problems with Win32 compatibility in Visual Studio 2005 with MVC++ 6.0


12 replies to this topic

#1 pa1

    New Member

  • Members
  • PipPip
  • 14 posts

Posted 07 March 2007 - 02:30 PM

Hi.
I just got Microsoft Visual Studio 2005 and I can't make even really basic programs (Win32) to compile. I tried to compile a program that in Visual C++ 6.0 has 0 errors and 0 warnings, but in this new version that doesn't happen. The short program named 'main.cxx' is:


#include<windows.h>


long FAR PASCAL WndProc (HWND hwnd, UINT message,                          

						 UINT wParam, LONG lParam)

{

	static HWND ewin;


	switch (message)

	{

		case WM_CREATE:

		{

			ewin = CreateWindowEx(0,"button","Exit",

				WS_CHILD | WS_VISIBLE | SS_CENTER,                   

				0,400,400,60, 

				hwnd,(HMENU)2, 

				(HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE),

				NULL);


			return 0;

		}

		break;

		case WM_COMMAND:

		{

			switch (wParam)

			{

				case 2:

				PostQuitMessage (0);

				break;

			}

			return 0;

		}

		break;

		case WM_DESTROY:

		{

			PostQuitMessage (0);

			return 0; 

		}

		break;

	}

	return DefWindowProc (hwnd, message, wParam, lParam);

}



int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

					LPSTR lpszCmdParam, int nCmdShow) 

{

	static char szAppName[] = "Win32Cone";

	HWND        hwnd ;

	MSG         msg ;

	WNDCLASS    wndclass ;


	if (!hPrevInstance)

	{

		wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

		wndclass.lpfnWndProc   = WndProc ;

		wndclass.cbClsExtra    = 0 ;

		wndclass.cbWndExtra    = 0 ;

		wndclass.hInstance     = hInstance;

		wndclass.hIcon         = LoadIcon(NULL,IDI_APPLICATION);

		wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);         

		wndclass.lpszMenuName  = NULL;

		wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);

		wndclass.lpszClassName = szAppName;

		RegisterClass (&wndclass);

	}


	hwnd = CreateWindowEx ( 0,szAppName,

		"Draw Window",

		WS_OVERLAPPEDWINDOW,

		CW_USEDEFAULT,

		CW_USEDEFAULT,

		400,

		480,

		NULL,

		NULL,

		hInstance,

		NULL);


	ShowWindow (hwnd, nCmdShow);

	UpdateWindow (hwnd);

	while (GetMessage (&msg, NULL, 0, 0))

	{     

		TranslateMessage (&msg);

		DispatchMessage (&msg);

	}

	return msg.wParam;

}


and the errors are:

error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'const char [7]' to 'LPCWSTR'

error C2440: '=' : cannot convert from 'char [10]' to 'LPCWSTR', Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'char [10]' to 'LPCWSTR'

and I get some warnings like:
warning C4312: 'type cast' : conversion from 'LONG' to 'HINSTANCE' of greater size

I see that the errors are related to the way the characters are interpreted, that is when I use ' char array[] = "WindowName" ' in CreateWindow(), this function expects to receive a LPCWSTR.

Anyway, how can I set Visual Studio 2005 to compile the way Visual C++ 6.0 did it (or how can I make these character interpretation problem to be solved)?

Thank you.

#2 dave_

    Senior Member

  • Members
  • PipPipPipPip
  • 584 posts

Posted 07 March 2007 - 03:00 PM

It is set to use unicode. I don't have 2005 on my PC but you need to turn that off.

Probably in the project settings under character set. Change it to multibyte (it works fine with single byte character sets)

#3 Reedbeta

    DevMaster Staff

  • Administrators
  • 4782 posts
  • LocationBellevue, WA

Posted 07 March 2007 - 03:42 PM

Or you can just make all your string literals unicode, by writing L"hello" instead of "hello". The L instructs the lexer to generate a unicode string.
reedbeta.com - developer blog, OpenGL demos, and other projects

#4 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 907 posts

Posted 07 March 2007 - 03:46 PM

Or you can use unicode strings. It's quite simple, just put an 'L' (literal) in front of your constant strings, eg. L"button", L"Exit", etc.

Note that Windows uses unicode internally, so when you provide it with ansi strings it has to waste cycles converting them to unicode. This of course isn't a big deal with window or button names, but it is good to know.

The 'LONG' to 'HINSTANCE' conversion warning is triggered because vc2005 checks for 64-bit incompatabilities. A long in native 64-bit mode is only 32-bits wide, but a HINSTANCE (a pointer) is 64-bits wide, so if you try to convert between these types you lose half of the pointer address, and eventually end up with a bad pointer and an exception is thrown when attempts to access that invalid address occurs. To correct this, just use LONG_PTR instead, its size is always the same as a pointer.
"Stupid bug! You go squish now!!" - Homer Simpson

#5 pa1

    New Member

  • Members
  • PipPip
  • 14 posts

Posted 07 March 2007 - 04:13 PM

Thank you guys, the UNICODE part is fixed with the 'L' s, but I still can't remove the warning about 'type cast' : conversion from 'LONG' to 'HINSTANCE' of greater size, because if I change (HINSTANCE) for (LONG_PTR) I get an error. What I have to do then?
Thanks again.

#6 pater

    Valued Member

  • Members
  • PipPipPip
  • 117 posts

Posted 07 March 2007 - 04:27 PM

You'll probably have the "Detect 64Bit portability issues" (VS2003 naming, but VS2005 should be similar) flag checked in project settings. This will issue a warning whenever you try to convert a type that is 64bit on a 64bit system to 32 bit (i.e. when you try to assign a pointer to an int). Unless you're really using a 64 bit System and OS (and build target), you can set this flag to "no".

#7 Rubicon

    Member

  • Members
  • PipPip
  • 90 posts

Posted 07 March 2007 - 05:15 PM

And then at some point later, you'll probably realise that yet another shitty default setting is to build a DLL as opposed to an EXE.

Unless you are indeed going for a DLL, you'll want to link against the "multithreaded" libs instead of "multithreaded DLL" libs.

Note there are no single-threaded options in case you felt you needed them. You don't anymore.
Regards, Paul Johnson
www.rubicondev.com
My Free 3D Tower Defence Game

#8 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 907 posts

Posted 07 March 2007 - 06:38 PM

You were supposed to change LONG to LONG_PTR ;)
"Stupid bug! You go squish now!!" - Homer Simpson

#9 Reedbeta

    DevMaster Staff

  • Administrators
  • 4782 posts
  • LocationBellevue, WA

Posted 07 March 2007 - 06:42 PM

Rubicon said:

And then at some point later, you'll probably realise that yet another shitty default setting is to build a DLL as opposed to an EXE.

Unless you are indeed going for a DLL, you'll want to link against the "multithreaded" libs instead of "multithreaded DLL" libs.

Note there are no single-threaded options in case you felt you needed them. You don't anymore.

I don't understand what you mean. Using the DLL version of the runtime library doesn't make your program a DLL, it just means it links with msvcrt8.dll rather than linking with the runtime statically. It is certainly not a default setting to build a DLL rather than an EXE. I always use the DLL runtime library to avoid code bloat, since pretty much every Windows system has that DLL already anyway.
reedbeta.com - developer blog, OpenGL demos, and other projects

#10 Rubicon

    Member

  • Members
  • PipPip
  • 90 posts

Posted 07 March 2007 - 06:46 PM

That's interesting to know.

I've never got as far as that tbh, as when I make a default project with these settings then copy my stub files over, it moans like buggery with a million linker errors every time (all system looking stuff). Changing to exe as expected makes it all work.

Next time I do this, I'll look more closely what the errors are and maybe give this a whirl. Many thanks!
Regards, Paul Johnson
www.rubicondev.com
My Free 3D Tower Defence Game

#11 Reedbeta

    DevMaster Staff

  • Administrators
  • 4782 posts
  • LocationBellevue, WA

Posted 07 March 2007 - 09:34 PM

If you're using Visual Studio 2005, have you followed the instructions on this page? If you haven't done Step 4, then you would probably get a crapload of linker errors.
reedbeta.com - developer blog, OpenGL demos, and other projects

#12 Rubicon

    Member

  • Members
  • PipPip
  • 90 posts

Posted 07 March 2007 - 09:41 PM

I'm using the full fat version, but it's probably the same problem.

Thanks for pointing this out. I probably won't actually use it but it's nice to know what's going on :)
Regards, Paul Johnson
www.rubicondev.com
My Free 3D Tower Defence Game

#13 pa1

    New Member

  • Members
  • PipPip
  • 14 posts

Posted 16 March 2007 - 05:21 PM

I found out how to disable the Unicode definition in Visual C++ 2005:

1) Place

#ifdef UNICODE
#undef UNICODE
#endif

before any references of a string, or

2) go to Project-> <project_name> properties...->Configuration Properties->C/C++ -> Preprocessor->Preprocessor Definitions->...-> and uncheck 'Inherit from parent or project defaults'.

:yes:





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users