Link to home
Start Free TrialLog in
Avatar of brownsoft
brownsoft

asked on

LoadBitmap for custom brush?

Hi, I'm trying to create a custom brush to use with win32 application and i get errors.  Am I using the wrong type of handle?  See the two snippets of code below and the associated error with each.  What must I do to get the brush set up.  (Using vc++6)  

Thanks.

Snippet 1.

HINSTANCE hbitmap;

LoadBitmap(hbitmap,"IDB_BITMAP1");
HBRUSH bitmap_brush = CreatePatternBrush(hbitmap);

ERROR = CreatePatternBrush' : cannot convert parameter 1 from 'struct HINSTANCE__ *' to 'struct HBITMAP__ *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


Snippet 2.

HBITMAP hbitmap;

LoadBitmap(hbitmap,"IDB_BITMAP1");
HBRUSH bitmap_brush = CreatePatternBrush(hbitmap);

ERROR = LoadBitmapA' : cannot convert parameter 1 from 'struct HBITMAP__ *' to 'struct HINSTANCE__ *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nietod
nietod

So you code muyst save the value RETURNED by LoadBitmap(), but it also must pass a value in the 1st parameter of LoadBitmap().  This value that is passed is the instance handle of the module (EXE or DLL) that contains the bitmap in its resources.   This "tells" LoadBitmap() where to find the resource for the bitmap.  The instance handle will be passed to the EXE's WinMain() procedure, or to the DLL's DllMain() procedure.  You should be using one of these values.

Let me know if you have any questions.
Avatar of brownsoft

ASKER

Okay, so as my window handle is called hwnd, this is how I should use the LoadBitmap()

~~~~~~~LoadBitmap(hwnd,"IDB_BITMAP1");

So how do I store the returned value and create the brush?
NO!!

Reread what I said.  The 1st parameter is not a window handle.  it is an instance handle.  A handle to the DLL or EXE that has the bitmap in its resources.

Where is the bitmap?  In an EXE or in a DLL?
Sorry, i am stupid but getting smarter..

This is what I have and it is more successful now but not completely as when I draw a rectangle with the brush, it uses the previous selected brush as if my brush failed to be created?

HBITMAP hbitmap;


hbitmap=LoadBitmap hinstance,"IDB_BITMAP1");


HBRUSH bitmap_brush = CreatePatternBrush(hbitmap);
Rectangle(.......

I'm not sure about whether the bitmap is an exe or dll,  I created an 8x8 bitmap and added it to my project via the resource editor.  My best guess is that it is an exe.
>> added it to my project via the resource editor
Is it a project for an EXE--a program?  If so it is in the EXE, so use the instance handle passed to WinMain().

If the project is for a DLL, then use the instance handle passed to DllMain().

>> it uses the previous selected brush as if my brush
>> failed to be created?
Its easy to tell if the brush was not created.  CreatePaterBrush will return NULL.  Does it?

If not, do you select the new brush into the DC?  You have to do so or the DC continues to use the old brush.

If that doesn't help, can you the code?

I'm leaving town in about 8 hours and will be gone--and unavailable--for 4 days.
Heres the code minus all my irrelevant timer events and so forth.  Sorry it's so big.

#define WIN32_LEAN_AND_MEAN//You always have to put this in
#include <windows.h> //includes the windows libraries
#include <windowsx.h>//as above
#include <stdio.h>//standard input/output functions
#include <math.h>//you know for maths and stuff
#include <mmsystem.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <time.h>

#define WINDOW_CLASS_NAME "WINCLASS1"  
#define TIMER_ID1_SEC  3
#define TIMER_ID3_SEC  4
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)


int drawmap(void);
static int counter=0;
char buffer[80];

int map[10][15]={{      1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{                              1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{                              1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{                              1,0,0,0,0,0,0,0,0,0,1,1,0,0,1},
{                              1,0,0,1,1,1,0,0,0,0,1,1,0,0,1},
{                              1,0,0,1,1,1,0,0,1,1,1,1,0,0,1},
{                              1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{                              1,0,0,1,0,0,1,1,0,0,0,0,0,0,1},
{                              1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{                              1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
HPEN green_pen = CreatePen(PS_SOLID, 0, RGB(0,255,0));
HPEN red_pen = CreatePen(PS_SOLID, 0, RGB(255,0,0));
HPEN black_pen = CreatePen(PS_SOLID, 0, RGB(0,0,0));
HPEN purple_pen = CreatePen(PS_SOLID, 0, RGB(0,255,255));
HBRUSH blue_brush = CreateSolidBrush(RGB(0,0,255));
HBRUSH black_brush = CreateSolidBrush(RGB(0,0,0));
HBRUSH red_brush = CreateSolidBrush(RGB(255,0,0));
HBRUSH green_brush = CreateSolidBrush(RGB(0,255,0));
HBRUSH purple_brush = CreateSolidBrush(RGB(0,255,255));
HBRUSH bitmap_brush;
//HBRUSH bitmap_brush=CreatePatternBrush(hbitmap);
HWND main_window_handle = NULL; //save the window handle??
HBITMAP hbitmap;
HDC      hdc;
LRESULT CALLBACK WindowProc(HWND hwnd,//Function pointer to event handler
                                          UINT msg, WPARAM wparam, LPARAM lparam)
{
      PAINTSTRUCT ps;//used in WM_PAINT
      switch(msg)//If an event occurs, it is sent to here
      {
      case WM_CREATE:
            {
            return(0);
            }break;
      case WM_PAINT:
            {
            
            hdc=GetDC(hwnd);//gets the device context for the window
            ReleaseDC(hwnd,hdc);//releases the device context
            ValidateRect(hwnd, NULL);//validates the window
            return(0);
            }break;
      case WM_DESTROY:
            {
            PostQuitMessage(0);//Ends the application
            return(0);
            }break;

      return (DefWindowProc(hwnd, msg, wparam, lparam));//Deal with any
      //other messages not dealt with via case statements.
}

int WINAPI WinMain(HINSTANCE hinstance,
                           HINSTANCE hprevinstance,
                           LPSTR lpcmdline,
                           int ncmdshow)//standard stuff to set up a window
{
      WNDCLASS winclass;  //Create a new class called winclass
      HWND      hwnd;            //create a handle
      MSG msg; //create a variable to hold the messages                  
      winclass.style=      CS_DBLCLKS | CS_OWNDC |
                              CS_HREDRAW | CS_VREDRAW;//Sets window type
      winclass.lpfnWndProc      =WindowProc;//Fills in more class details.
      winclass.cbClsExtra            =0;
      winclass.cbWndExtra            =0;
      winclass.hInstance            =hinstance;
      winclass.hIcon                  =LoadIcon(NULL,IDI_APPLICATION);
      winclass.hCursor            =LoadCursor(NULL, IDC_ARROW);
      winclass.hbrBackground      =(HBRUSH)GetStockObject(BLACK_BRUSH);
      winclass.lpszMenuName      =NULL;
      winclass.lpszClassName      =WINDOW_CLASS_NAME;

      if(!RegisterClass(&winclass))//registers the window class
            return(0);
      if (!(hwnd=CreateWindow(WINDOW_CLASS_NAME,//create the window
            "Tanks very much!!",//with the below values
            WS_OVERLAPPEDWINDOW | WS_VISIBLE,
            0,0,//location
            604,444,//size
            NULL,//parent
            LoadMenu(hinstance, "mymenu"),//menu
            hinstance,//instance
            NULL)))//creation parameters??
            
            
      return(0);
      main_window_handle=hwnd;//save window handle as global
      hbitmap=LoadBitmap(hinstance,"IDB_BITMAP1");
      HBRUSH bitmap_brush = CreatePatternBrush(hbitmap);
      hdc=GetDC(hwnd);
      drawmap();

      ReleaseDC(hwnd, hdc);
      while(1)
      {
            
            if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))//is there message?
            {
                  if(msg.message==WM_QUIT)break;
                  TranslateMessage(&msg);//translates message
                  DispatchMessage(&msg);//sends message(msg) to event handler
            }
            
            COLORREF      old_text_color,
                              old_back_color;
            hdc=GetDC(hwnd);
            SetBkMode(hdc,TRANSPARENT);
            old_text_color = SetTextColor(hdc,RGB(255,0,0));
            old_back_color = SetBkColor(hdc,RGB(0,0,0));
            SetBkMode(hdc,OPAQUE);
            SetTextColor(hdc,RGB(0,0,255));
            SetTextColor(hdc,old_text_color);
            SetBkColor(hdc,old_back_color);
            

            ReleaseDC(hwnd, hdc);


      }
return(msg.wParam);
}



drawmap(void)
{      
      int xpos=0,ypos=0,x=0,y=0,x2=0,y2=0;
            SelectObject(hdc, green_brush);

      SelectObject(hdc, red_pen);
      SelectObject(hdc, bitmap_brush);
      for(ypos=0;ypos<10;ypos++)
            {for(xpos=0;xpos<15;xpos++)
                  {      x2=x+40;
                        y2=y+40;
                        if (map[ypos][xpos]==1)
                        {
                        Rectangle(hdc,x,y,x2,y2);}
                        x=x+40;
                        
                        if (x>=600){      x=0;
                                                }

            }
      y=y+40;
      }
return(0);}



I can't follow that.  its to hard to read.

There are lots of potential problems.  There are global and local variables that have the same name, like bitmap_brush and hbitmap.  That can cause problems because when the local is in scope, you will be working with it, but when the local is not in scope you will be working with the global.  so you might initialize the local, then try to use the value int he global.  That is likely to be a problem

Also I don't see any attempts to clean up.  When you load and create  things, you need to delete them too.  That's very important.

Also I don't see error checks.  you should test to see if the bitmap gets loaded and test to see if a brush gets created.  At least use an assert for this.

If that doesn't help, e-mail me a copy.  nietod@theshop.net
Thanks for your help Nietod.  I am a beginner to Windows programming and am stumbling along.  I know I'm supposed to delete things after I'm finished with them but I'm not yet up to the point where Iknow what to delete.  Thanks for having a look.  WHat I might do is make a smal program just to try and draw a rectangle with a textured brush and I'll get back to you.

THanks again.