Thread: Access violation on class members

  1. #1
    Registered User filler_bunny's Avatar
    Join Date
    Feb 2003
    Posts
    87

    Access violation on class members

    This is just some test code to demonstrate the problem so there are many missing tests etc.

    Could anyone explain to me why this code fails (there is an access violation when trying to store the results from LoadBitmap, or in face use any member variable). I can solve this by making the member hBitmap a static variable or making the variable local to the code block where Loadbitmap is called... This just seems a bit odd to me, because I have been using code like this with dialogs for some time..

    Also - all non static member functions can be called, so the static message router seems to be working OK...

    Can someone enlighten me as to the cause?
    Code:
    #include <windows.h>
    #include "resource.h"
    
    class CApp
    {
    private:
    	HBITMAP hBitmap;
    
    public:
    	CApp();
    	int Run();
    	LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
    	static LRESULT CALLBACK StaticWndProc(HWND, UINT, WPARAM, LPARAM);
    };
    
    CApp::CApp()
    {
    	WNDCLASSEX wcx;
    	HINSTANCE hInstance  = (HINSTANCE)GetModuleHandle(NULL);
    
    	wcx.cbClsExtra		= 0;
    	wcx.cbSize			= sizeof(WNDCLASSEX);
    	wcx.cbWndExtra		= 0;
    	wcx.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wcx.hCursor			= LoadCursor(NULL, IDC_ARROW);
    	wcx.hIcon			= LoadIcon(NULL, IDI_WINLOGO);
    	wcx.hIconSm			= NULL;
    	wcx.hInstance		= hInstance;
    	wcx.lpfnWndProc		= (WNDPROC)StaticWndProc;
    	wcx.lpszClassName	= TEXT("Test");
    	wcx.lpszMenuName	= NULL;
    	wcx.style			= CS_HREDRAW | CS_VREDRAW;
    
    	RegisterClassEx(&wcx);
    
    	HWND hwnd = CreateWindowEx(0, TEXT("Test"), TEXT("Window"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
    							   CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, this);
    
    	ShowWindow(hwnd, SW_SHOW);
    	UpdateWindow(hwnd);
    }
    
    int CApp::Run()
    {
    	MSG msg;
    
    	while (GetMessage(&msg, NULL, 0, 0) > 0)
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	return msg.wParam;
    }
    
    LRESULT CALLBACK CApp::MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	switch(msg)
    	{
    	case WM_CREATE:
    		{
    			HINSTANCE hInstance = (HINSTANCE) GetModuleHandle(NULL);
    			hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
    			if (!hBitmap)
    				OutputDebugString(TEXT("Error: Unable to load bitmap\n\n"));
    		}
    		return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    
    	default:
    		return DefWindowProc(hwnd, msg, wParam, lParam);
    	}
    }
    
    LRESULT CALLBACK CApp::StaticWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	CApp *ca = (CApp *) GetWindowLongPtr(hwnd, GWL_USERDATA);
    
    	if (!ca)
    	{
    		CREATESTRUCT *cs = (CREATESTRUCT *) lParam;
    		ca = (CApp *) cs->lpCreateParams;
    		SetWindowLongPtr(hwnd, GWL_USERDATA, (LONG_PTR)ca);
    	}
    
    	if (!ca)
    		return DefWindowProc(hwnd, msg, wParam, lParam);
    	else
    		return ca->MainWndProc(hwnd, msg, wParam, lParam);
    }
    
    CApp App;
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int nCmdShow)
    {
    	App.Run();
    
    	return 0;
    }
    EDIT

    Crap - I think I solved it.. but I am not sure. I stupidly didn't make sure I had recieved a WM_NCCREATE message before getting the CREATESTRUCT data, but can anyone tell me why I am still able to call non-static methods, but I am not able to use non-static variables?

    Cheers,

    FB
    Last edited by filler_bunny; 05-02-2004 at 12:05 AM.
    Visual C++ .net
    Windows XP profesional

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Class member functions are simply C functions that have the this pointer passed implicitly.
    When you try to access member variables, you are essentially dereferencing a bad this pointer.

    gg
    Last edited by Codeplug; 05-03-2004 at 08:03 AM.

  3. #3
    Registered User filler_bunny's Avatar
    Join Date
    Feb 2003
    Posts
    87
    Thanks, your absolutely right. Let me explain why I was getting confused.

    I was writing an application that contained a class (lets call it CApp), that represents the main application and its main window. In the past I had always used the main windows handle as passed by the windows procedure, but I found myself needing it in methods of CApp, and I felt it was wastefull to not just store the HWND and use it as a member variable.

    Now - I obtained the HWND from CreateWindowEx(), stored it as a member variable of CApp, and then used it in the WM_CREATE message and I couldn't work out why it was always failing (This was really late at night ok..). Of course you don't get the hwnd from CreateWindowEx until after WM_CREATE is processed, and until then it was going to be NULL as I set it in the contstructor!

    Thanks for your help. I really just needed to think this through somewhat.
    Visual C++ .net
    Windows XP profesional

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Message class ** Need help befor 12am tonight**
    By TransformedBG in forum C++ Programming
    Replies: 1
    Last Post: 11-29-2006, 11:03 PM
  2. My Window Class
    By Epo in forum Game Programming
    Replies: 2
    Last Post: 07-10-2005, 02:33 PM
  3. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM
  4. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM