Please download the included file attachment and you'll see what I mean. Can I BitBlt over top of a frame or within a frame?
Printable View
Please download the included file attachment and you'll see what I mean. Can I BitBlt over top of a frame or within a frame?
You can but you need to get the Device Context of the Frame first. That property is not exposed by VB but you can get it with an API call.
Private Declare Function GetWindowDC Lib "user32" (ByVal hWnd As Long) As Long
Dim hWinDC As Long
hWinDC = GetWindowDC(Frame1.hWnd)
BitBlt hWinDC, 150, 50, pic.Width, pic.Height, pic.hDC, 0, 0, vbSrcCopy
Greg
You're a genius! I'd never heard of that API before. Thanks SO much -- you just saved me a buttload of work!
Saving buttloads of work is what I do best!
Greg:)
Then maybe you can save me a little more time! :) Both Forms and Pictureboxes have a Cls method to clear them of BitBlt's. Since Frames don't have a Cls method, is there an API I can use to somehow perform an equivalent Cls-like method on a frame?
There is no Cls method but what you can do is draw a rectangle of the same color as the background over the spot were the image was BitBlted.
Private Const Color_btnFAce = 15
Private Const PS_SOLID = 0
Private Declare Function Rectangle Lib "GDI32" (ByVal hDC As Long, ByVal x1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function CreateSolidBrush Lib "GDI32" (ByVal crColor As Long) As Long
Private Declare Function CreatePen Lib "GDI32" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
Private Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
Private Declare Function DeleteObject Lib "GDI32" (ByVal hObject As Long) As Long
Private Declare Function SelectObject Lib "GDI32" (ByVal hDC As Long, ByVal hObject As Long) As Long
Dim lRet As Long
Dim hPen As Long
Dim hOldPen As Long
Dim hBrush As Long
Dim hOldBrush As Long
' Create a Pen and Brush the same color as the frame
hPen = CreatePen(PS_SOLID, 1, GetSysColor(Color_btnFAce))
hOldPen = SelectObject(hWinDC, hPen)
hBrush = CreateSolidBrush(GetSysColor(Color_btnFAce))
hOldBrush = SelectObject(hWinDC, hBrush)
'Draw the rect
'Replace the lLeft, lTop, lRight, lBottom
'with the proper values to cover the area of your image
'It will expect pixels so if you have the form.scalmode set to
'Twips you may need to convert
lRet = Rectangle(hWinDC, lLeft, lTop, lRight, lBottom)
' Get rid of the pen and brush
hOldPen = SelectObject(hWinDC, hOldPen)
lRet = DeleteObject(hPen)
hOldBrush = SelectObject(hWinDC, hOldBrush)
lRet = DeleteObject(hBrush)
Greg
Very cool! So which portion of your code is actually retrieving the Color of the background? For instance, if I want to fill a picturebox (scalemode pixels) with Frame1's background color to BitBlt copy later, how would I do that since the below code's Frame1's BackColor is some funky negative number and doesn't work?...
For x = 0 To picBlank.Width - 1
For y = 0 To picBlank.Height - 1
SetPixel picBlank.hdc, x, y, Frame1.BackColor
Next y
Next x
When you create the Pen and Brush (The Pen defines the border of the rect and the brush is the color it will be filled with) the last parameter in CreatePen determines the color, and the only parameter in CreateSolidBrush determines the color of the brush. The values for those parameters can be any long integer that evaluates to a color. So you could use VB's RGB() or QBColor() functions for the color.
The GetSysColor() API call returns a color value based on the user's current color scheme. I use the Color_btnFAce value which is the color of the Button Face (duh!). This is almost always, if not always, the same color as the frame.
hPen = CreatePen(PS_SOLID, 1, GetSysColor(Color_btnFAce))
hBrush = CreateSolidBrush(GetSysColor(Color_btnFAce))
This would also work
lLongClrVal = GetPixel(...)
hPen = CreatePen(PS_SOLID, 1, lLongClrVal)
hBrush = CreateSolidBrush(lLongClrVal)
Below I've inculded some other constant color values that can be used with the GetSysColor() API.
Global Const COLOR_SCROLLBAR = 0
Global Const COLOR_BACKGROUND = 1
Global Const COLOR_ACTIVECAPTION = 2
Global Const COLOR_INACTIVECAPTION = 3
Global Const COLOR_MENU = 4
Global Const Color_Window = 5
Global Const Color_WindowFrame = 6
Global Const COLOR_MENUTEXT = 7
Global Const Color_WindowText = 8
Global Const COLOR_CAPTIONTEXT = 9
Global Const COLOR_ACTIVEBORDER = 10
Global Const COLOR_INACTIVEBORDER = 11
Global Const COLOR_APPWORKSPACE = 12
Global Const COLOR_HIGHLIGHT = 13
Global Const COLOR_HIGHLIGHTTEXT = 14
Global Const Color_btnFAce = 15
Global Const Color_btnShadow = 16
Global Const COLOR_GRAYTEXT = 17
Global Const COLOR_BTNTEXT = 18
'Only for > win 3.1
Global Const COLOR_INACTIVECAPTIONTEXT = 19
Global Const Color_btnHighlight = 20
Greg
PS: When working with GDI Pens and Brushs always, always clean up after yourself with the SelectObject and DeleteObject calls. If you don't you can quickly gobble up GDI resources and your PC will become a slug in no time.
' Get rid of the pen and brush
hOldPen = SelectObject(hWinDC, hOldPen)
lRet = DeleteObject(hPen)
hOldBrush = SelectObject(hWinDC, hOldBrush)
lRet = DeleteObject(hBrush)
After I write code with GDI calls for a little bit I run the program and check the resource consumption with the Resource Meter that ships with Windows.
Start/Accessories/Systems Tools/Resource Meter
If you see resources drop and drop and never go back up then you are not deleting all of the objects you've created.
Greg
Thanks so much! I'm learning more and more! And I was just thinking and wondering if for clearing my BitBlted object on the frame, if I could just BitBlt a picturebox of the same size as the picture I'm BitBlting if I set up the picturebox with...
picBlank.BackColor = Frame1.BackColor
Would there be a disadvantage to that?
That would work fine. The only disadvatage is that you have that extra control taking up resources. Probably not a big deal uless the app gets really big and confusing.
Greg
Thanks again for all your help! Saved me a LOT of work!!
My pleasure.
Greg