'=' : cannot convert from 'void *' to 'struct HBRUSH__ *'

This is a discussion on '=' : cannot convert from 'void *' to 'struct HBRUSH__ *' within the Windows Programming forums, part of the Platform Specific Boards category; I am having problems with this rather simple program from one of my books. I would appreciate some help on ...

  1. #1
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396

    Angry '=' : cannot convert from 'void *' to 'struct HBRUSH__ *'

    I am having problems with this rather simple program from one of my books. I would appreciate some help on what these errors mean and how to correct them. Thanks in advance.

    Here are my errors:

    cpp(61) : error C2440: '=' : cannot convert from 'void *' to 'struct HBRUSH__ *'
    Conversion from 'void*' to pointer to non-'void' requires an explicit cast

    cpp(68) : error C2065: 'rect' : undeclared identifier
    Error executing cl.exe.




    Here is my source code: (Copied from my Nitty Gritty book)
    Code:
    #include <windows.h>
    
    
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
    
    
    int APIENTRY WinMain(HINSTANCE hInstance,
    		HINSTANCE hPrevInstance,
    		LPSTR lpCmdLine,
    		int nCmdShow)
    
    {
    	WNDCLASS WndClass;
    	WndClass.style = 0;
    	WndClass.cbClsExtra = 0;
    	WndClass.cbWndExtra = 0;
    	WndClass.lpfnWndProc = WndProc;
    	WndClass.hInstance = hInstance;
    	WndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
    	WndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
    	WndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    	WndClass.lpszMenuName = 0;
    	WndClass.lpszClassName = "WinProg";
    
    	RegisterClass(&WndClass);
    
    	HWND hWindow;
    	hWindow = CreateWindow("WinProg","GDI App",
    		WS_OVERLAPPEDWINDOW,
    		0,0,600,460,NULL,NULL,
    		hInstance, NULL);
    
    	ShowWindow (hWindow, nCmdShow);
    
    	UpdateWindow (hWindow);
    
    	MSG Message;
    	while (GetMessage(&Message, NULL, 0, 0))
    	{
    		DispatchMessage(&Message);
    	}
    	return (Message.wParam);
    }
    
    
    
    LRESULT CALLBACK WndProc (HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
    {
    	switch(uiMessage)
    	{
    	case WM_PAINT:
    		HPEN hPen;
    		HPEN hPenalt;
    		HBRUSH hBrush;
    		HBRUSH hBrushalt;
    		hBrush = CreateSolidBrush (RGB(255,100,0));
    		hPen = CreatePen (PS_SOLID,2,RGB(0,255,255));
    		HDC hdc;
    		PAINTSTRUCT ps;
    		hdc = BeginPaint (hWnd, &ps);
    		hBrushalt = SelectObject (hdc, hBrush);
    		MoveToEx (hdc, 20,20, NULL);
    		LineTo (hdc, 100, 100);
    		Rectangle (hdc, 120, 20, 240, 140);
    		RoundRect (hdc, 260,20, 420, 140, 20, 20);
    		
    		RECT Rect;
    		SetRect (&rect, 20, 260, 240, 420);
    		FrameRect (hdc, &rect, hBrush);
    		SetRect (&rect, 260, 260, 420, 420);
    		FillRect (hdc, &rect, hBrush);
    		Ellipse (hdc, 440, 260, 480, 420);
    		SelectObject (hdc, hBrushalt);
    		SelectObject (hdc, hPenalt);
    		DeleteObject (hPen);
    		DeleteObject (hBrush);
    		EndPaint (hWnd, &ps);
    		return 0;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	default:
    		return DefWindowProc (hWnd, uiMessage, wParam, lParam);
    	}
    }
    Last edited by Bajanine; 10-08-2002 at 09:17 PM.

  2. #2
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396

    Question ? What happened to my indentation?

    What happened to my indentation?

    I guess I forgot to add my tags. Sorry!
    Last edited by Bajanine; 10-08-2002 at 09:16 PM.

  3. #3
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Code:
      RECT Rect;
      SetRect (&rect, 20, 260, 240, 420);
      FrameRect (hdc, &rect, hBrush); 
      SetRect (&rect, 260, 260, 420, 420);
      FillRect (hdc, &rect, hBrush);
    You're declaring Rect but using rect everywhere. Change it and magical eliminate an error.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  4. #4
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396

    Boy do I feel stupid!

    Thank you for your time Mr. Wizard.

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Solution #2:

    SelectObject returns a void*. You must cast it, ie:

    hBrushalt = (HBRUSH)SelectObject (hdc, hBrush);
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396

    Talking Many thanks everyone.

    Sabastiani, thanks for your help. It sure is a drag when these programming books include errors like that.

    Thanks again everyone.


    I now get this warning:

    cpp(74) : warning C4700: local variable 'hPenalt' used without having been initialized

    Why do I get a warning on hPenalt and not on hBrushalt aren't they used in the same way?

    For now I just rem. the references to hPenalt out and it gives no errors or warnings, but I still don't see why I don't also get a warning about hBrushalt.
    Last edited by Bajanine; 10-08-2002 at 10:35 PM.

  7. #7
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    You *should* get a warning on both but not garaunteed. You should not be selecting unintialized objects into any DC. I'm not sure what you are trying to do but don't do that!

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    No, you initialized hbrushalt in the code I posted above. Let me explain to you what the SelectObject function does. Every HDC has a complete set of GDI objects within it (HPEN, HBRUSH, HBITMAP, etc). These GDI objects could have been set by a previous application (unless CS_OWNDC was specified for one of the window class attributes) or even a previous operation. So initially, when you start an app, the HDC already has initialized GDI objects. When you call SelectObject() it does 2 things. First, it looks at your second parameter and determines what type of object it is( lets say it's an HPEN ). Using a table of sorts, it looks up that HDC, and then looks up the current HPEN object for that HDC, and replaces it with the new one. Second, it returns a void* to the previous HPEN. This is why the cast is necessary. Windows was developed before C++ gained popularity, and it abundant in weird hacks such as these. Now then. Remember I said that the initial GDI objects may have been set by an old or even currently running application. So it would be impolite to place your GDI object in that HDC without replacing the old one after your done, as you may cause another app's screen to go blank, etc. This is extremely important to remember and highlights the golden rule of GDI:

    "Save the old objects, and reinsert them after you're done with a single operation!!!"

    It may seem odd(it is), but is an unfortunate reality of the GDI you have to be mindful of at all times. The second golden rule, by the way, is:

    "ALWAYS delete a GDI object when you no longer need it!!"

    Windows just isn't smart enough to do this on it's own, and so careless programming will result in memory leaks and exausted memory (read: "there is not enough memory to complete this operation..." type of user messages.).

    Finally, never place an uninitialized object into SelectObject(). This is eqivalent to handing a fireman a water hose that is not connected to a hydrant! He would have nothing to work with, and the house will burn down, too! So let's look at some proper GDI with SelectObject:

    Code:
    HDC winDC, cDc;
    HBITMAP oldBm, newBm;
    RECT rect;
    int width, height;
    
    //...fill the rect with window coords...
    GetClientRect(hwnd, &rect);
    
    width = rect.right - rect,left;
    height = rect.bottom - rect.top;
    
    //...get a handle to the HDC to the window "hwnd"...
    winDc = GetDC(hwnd); 
    
    //...initialization...
    cDC = CreateCompatibleDC(winDC); 
    
    //...initialization...
    newBm = CreateCompatibleBitmap(winDc, width, height); 
    
    //...save old and select new...
    oldBm = (HBITMAP)SelectObject(cDc, newBm); 
    
    //..now paint the bits onto the window...
    BitBlt(winDc, rect.left, rect.top, width, height, cDc, rect.left, rect.top, SRCCOPY);
    
    //...clean up...
    
    //...give back winDc...
    ReleaseDC(hwnd, winDC); 
    
    //...delete newBm and reselect oldBm...no cast necessary.
    DeleteObject(SelectObject(cDc, oldBm)); 
    
    DeleteDC(cDc);
    
    //...send a paint message to the window to ensure the update...
    InvalidateRect(hwnd, &rect, 1);

    You have sucessfully painted a window with it's own bits! Well I hope that proves to be helpful to you. Good luck!
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  9. #9
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,859
    If you are writting in pure C (not using MFC or C++) then use the source file extension .c (not the .cpp) and this type of casting error will go away.

    To add to Sebastiani's golden rules

    "You can't delete a GDI object that is seleted in a DC."
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  10. #10
    Registered User Bajanine's Avatar
    Join Date
    Dec 2001
    Location
    The most peaks over 10,000 feet!
    Posts
    396

    Question Thanks

    Thank you all for input. I think I will have to digest this for a while!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 04:06 PM
  2. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 02:01 AM
  3. LNK2001 ERROR!!! need help
    By lifeafterdeath in forum C++ Programming
    Replies: 7
    Last Post: 05-27-2008, 06:05 PM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 04:00 PM
  5. Quack! It doesn't work! >.<
    By *Michelle* in forum C++ Programming
    Replies: 8
    Last Post: 03-02-2003, 12:26 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21