Posted on 2004-10-05
Last Modified: 2013-12-26

Hey.  I'm using a big bitmap in my VB app, for various reasons I have used VB resource editor to load it into a RES file which is included in the project.  The bitmap called itself image number 101.

Now how do I use it?  It looks like LoadImage requires use of the MAKEINTRESOURCE macro to turn the number 101 into the proper resource identifier.  But VB won't recognize this macro.  How can I declare it?  Or how can I use LoadImage w/o it?

Question by:riceman0
  • 6
  • 3
LVL 10

Expert Comment

ID: 12226339
LoadResPicture(101, vbResBitmap) returns a reference to your bitmap.
LVL 10

Expert Comment

ID: 12226529
Sorry - I should have said
LoadResPicture(101, vbResBitmap) returns a reference to your bitmap as a stdPicture object

Therefore you should be able to work with this...
    hBMP = LoadResPicture(101, vbResBitmap).handle

Author Comment

ID: 12226869

Looks great, but doesn't seem to work.  The old way:

Dim hbmpBack as long
hdcBack = CreateCompatibleDC(hdcCompat)
Call SelectObject(hdcBack, hbmpBack)

works when I try to BitBlt from hdcBack to a picturebox later.  But the new way (using a resource instead of a file)

Dim hbmpBack as long
hbmpBack = LoadResPicture(101, vbResBitmap)
hdcBack = CreateCompatibleDC(hdcCompat)
Call SelectObject(hdcBack, hbmpBack)

seems to result in a black field for BitBlt-ing.  However the LoadResPicture call seems to work, hbmpBack returns a value in both cases.  The picture should be there, compiled into a RES file and appears in the project explorer under "Related documents."  Any ideas?
LVL 10

Accepted Solution

fds_fatboy earned 125 total points
ID: 12227244
Hmm... That's a surprise. It works a treat for me. Here's the exact code I use if you want to compare and contrast because unfortunately I can't spare the time that this problem requires until I get out of work tonight.

Public Sub DayGraphic(X As Long, Y As Long, Graphic As HighlightGraphic, Color As OLE_COLOR)
    Dim pic As StdPicture
    Dim hBmp As Long
    Dim bmp As BITMAP
    Dim SrcDC As Long
    Dim HoldingDC As Long
    Dim HoldingBmp As Long
    Dim PrevHoldingBmp As Long
    Dim RGBColor As Long
    Dim rcPaint As RECT
    Dim LlnghBrush As Long

    Const LstrPROCEDURE As String = MstrMODULE & ".DayGraphic" ' The procedure name.
    On Error GoTo ErrorHandler

    Select Case Graphic
    Case [Crossed out date]
        If MlnghCrossDC = 0 Then
            MlnghCrossDC = CreateCompatibleDC(picDates.hdc)
            Set pic = LoadResPicture("CrossedOut", vbResBitmap)

            MlnghCrossBmp = pic.Handle
            MlnghPrevCrossBmp = SelectObject(MlnghCrossDC, MlnghCrossBmp)
        End If

        hBmp = MlnghCrossBmp
        SrcDC = MlnghCrossDC
    Case [Ringed date]
        If MlnghRingDC = 0 Then
            MlnghRingDC = CreateCompatibleDC(picDates.hdc)
            Set pic = LoadResPicture("ringedDate", vbResBitmap)

            MlnghRingBmp = pic.Handle
            MlnghPrevRingBmp = SelectObject(MlnghRingDC, MlnghRingBmp)

        End If

        hBmp = MlnghRingBmp
        SrcDC = MlnghRingDC
    End Select

    GetObject hBmp, Len(bmp), bmp

    rcPaint.Left = 0
    rcPaint.Top = 0
    rcPaint.Right = bmp.bmWidth
    rcPaint.Bottom = bmp.bmHeight

    HoldingDC = CreateCompatibleDC(MlnghBufferDC)
    HoldingBmp = CreateCompatibleBitmap(MlnghBufferDC, rcPaint.Right, rcPaint.Bottom)
    PrevHoldingBmp = SelectObject(HoldingDC, HoldingBmp)

    RGBColor = TranslateOLEColor(Color)

    If RGBColor <> vbWhite Then
        LlnghBrush = CreateSolidBrush(RGBColor)
        FillRect HoldingDC, rcPaint, LlnghBrush
        DeleteObject LlnghBrush
        BitBlt HoldingDC, 0, 0, rcPaint.Right, rcPaint.Bottom, SrcDC, 0, 0, vbSrcPaint
        ReleaseDC HoldingBmp, SrcDC
        TransparentBlt MlnghBufferDC, X, Y, rcPaint.Right, rcPaint.Bottom, HoldingDC, 0, 0, rcPaint.Right, rcPaint.Bottom, vbWhite
        ReleaseDC MlnghBufferBmp, HoldingDC
        BitBlt HoldingDC, 0, 0, rcPaint.Right, rcPaint.Bottom, SrcDC, 0, 0, vbNotSrcCopy
        ReleaseDC HoldingBmp, SrcDC
        TransparentBlt MlnghBufferDC, X, Y, rcPaint.Right, rcPaint.Bottom, HoldingDC, 0, 0, rcPaint.Right, rcPaint.Bottom, vbBlack
        ReleaseDC MlnghBufferBmp, HoldingDC
    End If

    SelectObject HoldingDC, PrevHoldingBmp
    DeleteObject HoldingBmp
    DeleteDC HoldingDC

    Exit Sub
'Error handler code [Generated 18/05/04 Using LCPEditToolbox Ver 1.2 build 90]
'This code block must be the last code in the procedure.
    'Clean up
    Set pic = Nothing

    With Err
        If .Source = App.Title Then
            .Source = App.Title & "::" & LstrPROCEDURE
        End If

        .Raise .Number, .Source, .Description, .HelpFile, .HelpContext
    End With

End Sub
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!


Author Comment

ID: 12228485

Perfect.  Borrowing from your code, this fixed it:

        Dim pic As StdPicture
        Set pic = LoadResPicture(101, vbResBitmap)
        hbmpBack = pic.handle

Thanks a lot!
LVL 10

Expert Comment

ID: 12231904
Ahh -  .handle - I didn't spot that earlier - but as I said , I was a bit busy.
Glad it helped.

I also noticed in my code, I forgot to set the pic to nothing so it's probably leaking away - that code's been running for a year or so as well.

Author Comment

ID: 12232633
I'm suffering from leaks too.  When exactly do you need to set things to nothing?  Is the rule that you need one Nothing for every Set?
LVL 10

Expert Comment

ID: 12236192
>>Is the rule that you need one Nothing for every Set?

Yes - before it goes out of scope.

Some people will tell you that VB is meant to handle it but I have found it doesn't necessarily. Another nasty is when you have parent and child objects and the child has a reference to its parent. Standard practice is to set module level object references to nothing in the terminate event (Unload event in the case of a form) but in this case, neither object will ever terminate because of the reference held by the other. In this case the the parent must tell the child to remove the reference to itself before it attempts to terminate. Knowing when to to this can be tricky. A way round this is to use store objPtr to the parent as a Long and use it create a temporary local reference to the parent when you need it - removing it as soon as you have finished with it. But that is getting way off topic on this question.
LVL 10

Expert Comment

ID: 12236222
Also to avoid leaks, I should have said every SelectObject should be put back the way it was. Every object created with an API call should have a DeleteObject/DeleteDC, every blt should have a releaseDC etc.

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
using Access 8 52
VBA filters 2 39
Copy a row 12 53
Protecting vb6 & .Net code Obfuscation 18 51
Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now