Hello, I am new to this community but you seemed to be knowlegable with this error so I thought you could help me.

I am more of a hobbiest programmer. I get by with doing as little as possible to accent my graphic design abilities. I am currently working on a modern FPS/RPG game using the open source Quake 3 engine. The engine modifications are complete (both renderer and game code) but as we began to finish a few loose ends my programmers wife got very sick. I have been getting by with my limited programming skills to modify my programmers code.

Recently I decided to try to create a simple launcher for the game. I am modifying the code for a launcher that was created for a Q2 engine mod. I decided to do this because I got it to work in the past a few years ago but that was with MSVC++2005.

Upon first compile I got 53 errors. They have all been resolved except for 2. They are one line apart and are the same problem. C2228. Since the code is not my own and is free I have no problem posting it. It consists of a header file a cpp file and a rc file.

Thank you for your help.

cwndinfo.h

#include <string.h>

// CWndInfo: Holds the base information for any window
class CWndInfo
{
private:
	HWND hwnd;				// window handle
	char wndClassName[100]; // window classname
public:
	// constructors
	CWndInfo() { hwnd = NULL; strcpy(wndClassName, "Launcher"); }
	CWndInfo(char cname[]) { hwnd = NULL; strncpy(wndClassName, cname, 99); }

	// set functions
	HWND set_hwnd(HWND h) { return hwnd = h; }

	// fetch functions
	HWND get_hwnd() { return hwnd; }
	char* get_cname() { return wndClassName; }
};

Main.cpp (this is where the error occures)

#include <stdio.h>
#include <windows.h>
#include "cwndinfo.h"
#include "resource.h"

#define WND_WIDTH 680	// window width
#define WND_HEIGHT 365	// window height

#define EXECUTABLE		"xrevelation.exe"
#define XVersion		"1.0"
#undef UNICODE

// PROTOTYPES //
ATOM RegisterWndClass(HINSTANCE);
HWND CreateMainWnd(HINSTANCE);
void ErrorMsg(char [], char []);
void SetUpFont();
HWND CreateButton(char [], int, int, int, int, HWND, HMENU);
void LoadCmds(char []);
void WriteCmds(char []);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

// GLOBAL VARIABLES //
// M$ leaves me little choice...
CWndInfo	g_wndinfo;
HFONT		g_defont; // default font
HFONT		g_verfont; // default font
HBITMAP		g_bmpLogo = NULL;
HBRUSH		g_hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
//HINSTANCE	g_hInst;

// RegisterWndClass(): Register a window and return success/failure.
ATOM RegisterWndClass(HINSTANCE hInstance)
{
	WNDCLASSEX wc;

    wc.cbSize        = sizeof(WNDCLASSEX);				// size of WNDCLASSEX struct
    wc.style         = 0;								// class style
    wc.lpfnWndProc   = WndProc;							// pointer to windows procedure function
    wc.cbClsExtra    = 0;								// allocate extra memory (bytes) per class
    wc.cbWndExtra    = 0;								// allocate extra memory (bytes) per window
    wc.hInstance     = hInstance;						// handle to application instance
    wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));  // large icon (32x32)
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);		// cursor to use with application
    wc.hbrBackground = g_hbrBackground;					// background color of window
    wc.lpszMenuName  = NULL;							// name of menu resource
    wc.lpszClassName = g_wndinfo.get_cname();			// window classname
    wc.hIconSm       = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0);	// small icon (16x16)

	return RegisterClassEx(&wc);
}

HWND CreateMainWnd(HINSTANCE hInstance)
{
//	g_hInst = hInstance;

	return CreateWindowEx(
			 WS_EX_WINDOWEDGE,				// window style
			 g_wndinfo.get_cname(),			// window classname
			 "Launcher",				    // window title
			 WS_OVERLAPPED | WS_CAPTION |	// more window styles
			 WS_SYSMENU | WS_MINIMIZEBOX,	// more window styles
			 CW_USEDEFAULT, CW_USEDEFAULT,	// x,y coords
			 WND_WIDTH, WND_HEIGHT,			// width,height
			 NULL, NULL,					// applies to MDI stuff
			 hInstance, NULL);				// window instance
}

// ErrorMsg(): quicker interface for MessageBox().
void ErrorMsg(char msg[], char title[])
{
	 MessageBox(NULL, msg, title, MB_ICONEXCLAMATION | MB_OK);
}

// WndProc(): message handler.
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
	case WM_CREATE:
	{ // window is being created
		char s[5001];

		CWndInfo cmdLaunch("BUTTON"); // ok button
		CWndInfo cmdQuit("BUTTON"); // quit button
		CWndInfo cmdAbout("BUTTON"); // about button
		CWndInfo cmdSite("BUTTON"); // goto site button
		CWndInfo lblParams("STATIC"); // label for params box
		CWndInfo lblVersion("STATIC"); // label for version box
		CWndInfo txtParams("EDIT"); // extra params box
/*
		cmdLaunch.set_hwnd(CreateButton("Launch!", 583, 155, 80, 30, hwnd, (HMENU)IDC_MAIN_LAUNCH));
		cmdQuit.set_hwnd(CreateButton("Quit", 583, 475, 80, 30, hwnd, (HMENU)IDC_MAIN_QUIT));
		cmdSite.set_hwnd(CreateButton("Website", 583, 290, 80, 30, hwnd, (HMENU)IDC_MAIN_SITE));
		cmdAbout.set_hwnd(CreateButton("About", 583, 330, 80, 30, hwnd, (HMENU)IDC_MAIN_ABOUT));
*/
		cmdLaunch.set_hwnd(CreateButton("PLAY", 583, 155, 80, 30, hwnd, (HMENU)IDC_MAIN_LAUNCH));
		cmdSite.set_hwnd(CreateButton("COMMUNITY", 583, 205, 80, 30, hwnd, (HMENU)IDC_MAIN_SITE));
		cmdAbout.set_hwnd(CreateButton("ABOUT", 583, 255, 80, 30, hwnd, (HMENU)IDC_MAIN_ABOUT));
		cmdQuit.set_hwnd(CreateButton("EXIT", 583, 305, 80, 30, hwnd, (HMENU)IDC_MAIN_QUIT));

		lblParams.set_hwnd(CreateWindowEx(WS_EX_LEFT, "STATIC","Launch Parameters:", WS_CHILD | WS_VISIBLE,
							10, 135, 150, 20, hwnd, (HMENU)IDC_MAIN_EDITLBL, GetModuleHandle(NULL), NULL));

		txtParams.set_hwnd(CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", 
							WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN, 
							5, 155, 567, 180, hwnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL));

		lblVersion.set_hwnd(CreateWindowEx(WS_EX_LEFT, "STATIC","Version " XVersion, WS_CHILD | WS_VISIBLE,
							592, 135, 150, 20, hwnd, (HMENU)IDC_MAIN_VERLBL, GetModuleHandle(NULL), NULL));


		if (cmdLaunch.get_hwnd() == NULL || cmdQuit.get_hwnd() == NULL)
			ErrorMsg("Initialization failed in WM_CREATE!", "Error!");

		// set up fonts
		SendMessage(cmdLaunch.get_hwnd(), WM_SETFONT, (WPARAM)g_defont, MAKELPARAM(FALSE, 0));
		SendMessage(cmdQuit.get_hwnd(), WM_SETFONT, (WPARAM)g_defont, MAKELPARAM(FALSE, 0));
		SendMessage(cmdSite.get_hwnd(), WM_SETFONT, (WPARAM)g_defont, MAKELPARAM(FALSE, 0));
		SendMessage(cmdAbout.get_hwnd(), WM_SETFONT, (WPARAM)g_defont, MAKELPARAM(FALSE, 0));
		SendMessage(txtParams.get_hwnd(), WM_SETFONT, (WPARAM)g_defont, MAKELPARAM(FALSE, 0));
		SendMessage(lblParams.get_hwnd(), WM_SETFONT, (WPARAM)g_defont, MAKELPARAM(FALSE,0));
		SendMessage(lblVersion.get_hwnd(), WM_SETFONT, (WPARAM)g_verfont, MAKELPARAM(FALSE,0));

		LoadCmds(s);
		if (s[0] == '\0')
			strcpy(s, "+set game dday\r\n+set deathmatch 1");

		// set default text inside edit box
		SetDlgItemText(hwnd, IDC_MAIN_EDIT, s);

		// pbowens: dday's logo
		g_bmpLogo = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BMPLOGO));

        if(g_bmpLogo == NULL)
            MessageBox(hwnd, "Could not load IDB_BMPLOGO!", "Error", MB_OK | MB_ICONEXCLAMATION);
    
	}
	break;

	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
			case IDC_MAIN_LAUNCH:
			{ // clicked "Launch!" button
				int len = GetWindowTextLength(GetDlgItem(hwnd,IDC_MAIN_EDIT));
				long exec_rval=0;
				char *params;

				params = new char[len+3]; // space, extra "+", and null byte
				GetDlgItemText(hwnd, IDC_MAIN_EDIT, params, len+1);
				strcat(params, " +"); // shows console by default

				exec_rval=(long)ShellExecute(NULL,"open", EXECUTABLE, params,NULL, SW_SHOWNORMAL);
				if (exec_rval == ERROR_FILE_NOT_FOUND)
					ErrorMsg("Could not find " EXECUTABLE "!", "File Not Found");
				delete [] params;
			}
			break;

			case IDC_MAIN_QUIT:
				// clicked "Quit" button
				DestroyWindow(g_wndinfo.get_hwnd());
				break;

			case IDC_MAIN_SITE:
				// clicked "Website" button
				ShellExecute(NULL,"open","http://chili.planetquake.gamespy.com/forum",NULL,NULL,SW_SHOWNORMAL);
				break;

			case IDC_MAIN_ABOUT:
				// clicked "About" button
				MessageBox(g_wndinfo.get_hwnd(),"XRevelations Launcher\n"
												"Version: " XVersion "\n"
												"Written By: n321\n"
												"GUI By: n321 \n\n"
												"Written in C++ using MSVC++.\n"
												"Copyright (c) 2008 NCG Productions",
												"About", MB_OK | MB_ICONQUESTION );
				break;
		}
		break;

	case WM_PAINT:
    {
        BITMAP bm;
        PAINTSTRUCT ps;

        HDC hdc = BeginPaint(hwnd, &ps);

        HDC hdcMem = CreateCompatibleDC(hdc);

// pbowens: SelectObject apparently doesnt like HBITMAP
//        HBITMAP hbmOld = SelectObject(hdcMem, g_bmpLogo);
		HGDIOBJ hbmOld = SelectObject(hdcMem, g_bmpLogo);

        GetObject(g_bmpLogo, sizeof(bm), &bm);

        BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

        SelectObject(hdcMem, hbmOld);
        DeleteDC(hdcMem);

        EndPaint(hwnd, &ps);

		hwnd.nWidth = WND_WIDTH;
		hwnd.nHeight = WND_HEIGHT;
    }
    break;

    case WM_CTLCOLORDLG:
        return (LONG)g_hbrBackground;

    case WM_CTLCOLORSTATIC:
    {
        HDC hdcStatic = (HDC)wParam;
        SetTextColor(hdcStatic, RGB(255, 255, 255));
        SetBkMode(hdcStatic, TRANSPARENT);
        return (LONG)g_hbrBackground;
    }
    break;


    case WM_CLOSE:
		// user closed the window
        DestroyWindow(hwnd);
        break;

    case WM_DESTROY:
	{ // program is exiting
		int len = GetWindowTextLength(GetDlgItem(hwnd,IDC_MAIN_EDIT));
		char *params;

		params = new char[len+2]; // null byte
		GetDlgItemText(hwnd, IDC_MAIN_EDIT, params, len+1);
		WriteCmds(params);
		delete [] params;

        DeleteObject(g_bmpLogo);

        PostQuitMessage(0);
	}
        break;

    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

// SetUpFont(): Set the default app font
void SetUpFont()
{
	HFONT hf;
	HFONT hf_ver;
	HDC hdc;
	long lfHeight;

	hdc = GetDC(NULL);
	lfHeight = -MulDiv(10, GetDeviceCaps(hdc, LOGPIXELSY), 72);
	ReleaseDC(NULL, hdc);

    hf = CreateFont(lfHeight, 0, 0, 0, FW_BOLD, FALSE, 0, 0, 0, 0, 0, 0, 0, "Verdana");

    if(hf)
    {
        DeleteObject(g_defont);
        g_defont = hf;
    }
    else
    {
        ErrorMsg("Font creation failed!", "Error");
	}

	
	hdc = GetDC(NULL);
	lfHeight = -MulDiv(10, GetDeviceCaps(hdc, LOGPIXELSY), 96);
	ReleaseDC(NULL, hdc);

    hf_ver = CreateFont(lfHeight, 0, 0, 0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, "Verdana");

    if(hf_ver)
    {
        DeleteObject(g_verfont);
        g_verfont = hf_ver;
    }
    else
    {
        ErrorMsg("Font creation failed!", "Error");
    }

}

// CreateButton(): Reduce code redundancy by placing the
//				   code to create a button in one func.
HWND CreateButton(char s[], int x, int y, int width, int height, HWND hwnd, HMENU idc)
{
	return CreateWindowEx(WS_EX_WINDOWEDGE, "BUTTON", s,
						WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_FLAT, x, y, width, height, hwnd, idc,
						GetModuleHandle(NULL), NULL);
}

// LoadCmds(): Load extra paramaters from a file
void LoadCmds(char s[])
{
	FILE *fp=NULL;
	int i=0;

	fp = fopen("q2dday.dat", "r");

	if (fp)
	{
		while (feof(fp) == 0)
			s[i++] = fgetc(fp);
		s[i-1] = '\0';
		fclose(fp);
	}
	else
		s[0] = '\0';
}

// WriteCmds(): Save extra parameters to a file
void WriteCmds(char s[])
{
	FILE *fp=NULL;
	int i=0;

	fp = fopen("q2dday.dat", "w");

	if (fp)
	{
		while (s[i] != '\0')
			fputc(s[i++],fp);
		fclose(fp);
	}
	else
		ErrorMsg("Could not write to file!", "Error!");
}

// WinMain(): application entry point.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;

	// set up the default app font
	SetUpFont();

	// register a window class
    if(!RegisterWndClass(hInstance))
    {
        ErrorMsg("Window Registration Failed!", "Error!");
        return 0;
    }

	// attempt to create the window
    if(!(g_wndinfo.set_hwnd(CreateMainWnd(hInstance))))
    {
        ErrorMsg("Window Creation Failed!", "Error!");
        return 0;
    }

	// refresh the window
    ShowWindow(g_wndinfo.get_hwnd(), nCmdShow);
    UpdateWindow(g_wndinfo.get_hwnd());

    // message loop
    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

Recource.h

#define IDI_ICON1                       1
#define IDC_MAIN_LAUNCH                 101
#define IDC_MAIN_QUIT                   102
#define IDC_MAIN_ABOUT                  103
#define IDC_MAIN_EDIT                   104
#define IDC_MAIN_SITE                   105
#define IDC_MAIN_EDITLBL                106
#define IDC_MAIN_VERLBL                 108
#define IDB_BMPLOGO                     111

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        112
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif

Ok the error is on these lines #216 and #217 in main.cpp and reads as follows

hwnd.nWidth = WND_WIDTH;
		hwnd.nHeight = WND_HEIGHT;

Output reads


1>------ Build started: Project: Launcher, Configuration: Release Win32 ------
1>Compiling...
1>main.cpp
1>c:\documents and settings\nick\desktop\launcher-src\cwndinfo.h(21) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> C:\Program Files\Microsoft Visual Studio 9.0\VC\include\string.h(74) : see declaration of 'strcpy'
1>c:\documents and settings\nick\desktop\launcher-src\cwndinfo.h(22) : warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> C:\Program Files\Microsoft Visual Studio 9.0\VC\include\string.h(157) : see declaration of 'strncpy'
1>..\..\main.cpp(137) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> C:\Program Files\Microsoft Visual Studio 9.0\VC\include\string.h(74) : see declaration of 'strcpy'
1>..\..\main.cpp(162) : warning C4996: 'strcat': This function or variable may be unsafe. Consider using strcat_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> C:\Program Files\Microsoft Visual Studio 9.0\VC\include\string.h(79) : see declaration of 'strcat'
1>..\..\main.cpp(216) : error C2228: left of '.nWidth' must have class/struct/union
1> type is 'HWND'
1> did you intend to use '->' instead?
1>..\..\main.cpp(217) : error C2228: left of '.nHeight' must have class/struct/union
1> type is 'HWND'
1> did you intend to use '->' instead?
1>Build log was saved at "file://c:\Documents and Settings\Nick\Desktop\launcher-src\Launcher\Launcher\Release\BuildLog.htm"
1>Launcher - 2 error(s), 4 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

warning c4996 -- Microsoft has declared many of the standard C functions from stdstring.h decpreciated (obsolete). The c and c++ standards say otherwise. So you have a choice: 1) ignore the warnings, they can be disabled with this pragma: #pragma warning(disable: 4996) , or 2) fix the problems by using Microsofts safe, but non-standard, replacements that are suggested in the warning. I just ignore and disable them.


The error on line 217: This is a true error. HWND is not a structure but a pointer.

Yea Im just ignoring the warnings. So in my code how would I go about fixing the c2228 error in 217? I know the code should work as I have compiled it before on an older version so it has to be something that has changed in the new version of MSVC++ Express or the new windows SDK. ( I was using the 2003 SDK and now Im using the 2008)

I don't know how to do it because I have never seen HWND be a pointer to a structure with those items. I just tried it with VC++ 6.0 and it has the same problem. So I guess what you compiled before was wrong too. Check your work carefully -- my guess is that hwnd should not have been on those two lines.

well I tried to just remove the 2 lines and it built successfuly but the exe would not load IDP_BMPLOGO and when I close the error message the launcher opens with no title logo. Do you know of a way I could get this to work differently with out the HWND?

This article has been dead for over six months. Start a new discussion instead.