From: Nobody on 17 Nov 2009 05:54 "Bee" <Bee(a)discussions.microsoft.com> wrote in message news:B2CBE975-4A53-46B7-AC1A-557C2876893F(a)microsoft.com... > I need to be able to copy the selected area to the clipboard and then > paste > the selected area only on to a picturebox pixture with a moveable paste > image. Check out MaskBlt().
From: Nobody on 17 Nov 2009 06:03 "Nobody" <nobody(a)nobody.com> wrote in message news:uMwV0R3ZKHA.5300(a)TK2MSFTNGP02.phx.gbl... > "Bee" <Bee(a)discussions.microsoft.com> wrote in message > news:B2CBE975-4A53-46B7-AC1A-557C2876893F(a)microsoft.com... >> I need to be able to copy the selected area to the clipboard and then >> paste >> the selected area only on to a picturebox pixture with a moveable paste >> image. > > Check out MaskBlt(). > On the other hand, that function may not be suitable for what you are trying to do, I have not tried it.
From: Nobody on 17 Nov 2009 06:20 Search the newsgroups for "vb TransparentBlt".
From: Mike Williams on 17 Nov 2009 07:49 "Bee" <Bee(a)discussions.microsoft.com> wrote in message news:B2CBE975-4A53-46B7-AC1A-557C2876893F(a)microsoft.com... > Thank you both for some good insights. > Unfortuantely I am not that gifted to take it further. The thing is that most people here don't have the time to write full working examples for you, and even if they do have the time they often do not have the inclination, because it is always a better idea in the long run (for yourself I mean) for people to post responses containing just get some sample starter code or some information and for you to take it to the next step yourself. > Perhaps there is sample code or books that might > take me to the next step. Suggestions? A lot depends on which things you already know and which you don't. To get you a bit further along the road to your goal here is a modification of my previous example which takes the process one step further in that it now creates a sprite image and the associated mask image for you. The sprite image is your selection on a white background and the mask image is a black on white image where the white pixels represent the transparent pixels of the sprite (see code at end of this response). These two images are what you need to draw a "transparent sprite" onto any part of your main PictureBox (or anywhere else) and you need to combine them (commonly in a multiple blit operation, although there are other different methods) using a standard "sprite drawing" technique. Alternatively, you could simply use a single call to the TransparentBlt API using only the sprite image and specifying white as the transparent colour. The problem with the TransparentBlt API though is that it does not use a supplied mask (it creates its own on the fly) and so any parts of the image that you do not want to be transparent and that just happen to be the same colour as the selected transparent colour will also be drawn transparently, which is not what you want. Most real sprite drawing methods do not have that limitation, because they commonly use both a sprite image and a mask, and so I would suggest that's what you do. Transparently drawing the sprite on the PictureBox is only part of your solution of course, because according to your latest post you also want to be able to drag the transparently drawn sprite around the man pictureBox in real time, which requires a little more code. Anyway, here's the example code (below) which allows you to use the mouse to freehand draw your selection and which then creates the appropriate sprite and mask images. Once you've tried it you'll be able to add the extra code yourself to actually transparently draw and move the sprite around the main PictureBox with the mouse, using the sprite and mask images that my code already provides for your sprite drawings. Drawing and moving sprites is a fairly standard operation for which you'll find lots of example code dotted around the web. I would advise you to search Google and see what you can come up with in the way of sample code and tutorials for sprite drawing and sprite movement or animation in VB6, and then write the required code yourself. If you really do get stuck though after reading teavailable tutorials then feel free to post again. Start a new VB project and place three PictureBoxes and three Command Buttons on the Form. Name the three PictureBoxes picMain, picSprite and picMask respectively. Then paste in the following code. Mike Option Explicit Private Declare Function Polygon Lib "gdi32" _ (ByVal hdc As Long, lpPoint As POINTAPI, _ ByVal nCount As Long) As Long Private Declare Function CreatePolygonRgn Lib "gdi32" _ (lpPoint As POINTAPI, ByVal nCount As Long, _ ByVal nPolyFillMode As Long) As Long Private Declare Function PaintRgn Lib "gdi32" _ (ByVal hdc As Long, ByVal hRgn As Long) As Long Private Declare Function GetRgnBox Lib "gdi32" _ (ByVal hRgn As Long, lpRect As RECT) As Long Private Declare Function OffsetRgn Lib "gdi32" _ (ByVal hRgn As Long, ByVal x As Long, _ ByVal y As Long) As Long Private Declare Function SelectClipRgn Lib "gdi32" _ (ByVal hdc As Long, ByVal hRgn As Long) As Long Private Declare Function DeleteObject Lib "gdi32" _ (ByVal hObject As Long) As Long Private Declare Function BitBlt Lib "gdi32" _ (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, _ ByVal nWidth As Long, ByVal nHeight As Long, _ ByVal hSrcDC As Long, ByVal xSrc As Long, _ ByVal ySrc As Long, ByVal dwRop As Long) As Long Private Const ALTERNATE As Long = 1 Private Const WINDING As Long = 2 Private Const NULLREGION As Long = 1 Private Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Private Type POINTAPI x As Long y As Long End Type Private d1() As POINTAPI Private lastCoord As Long, SelectionValid As Boolean Private Rgn1 As Long, Rgn2 As Long, Rect1 As RECT Private Drawing As Boolean, SpriteVisible As Boolean Private Sub Form_Load() Dim s1 As String Me.WindowState = vbMaximized Me.Show s1 = "c:\temp\jessica1.jpg" picMain.AutoRedraw = True picMain.Move 0, 0, Me.ScaleWidth, Me.ScaleHeight - Command1.Height picMain.ScaleMode = vbPixels picMain.PaintPicture LoadPicture(s1), 0, 0, _ picMain.ScaleWidth, picMain.ScaleHeight picSprite.ScaleMode = vbPixels picSprite.BorderStyle = vbBSNone picSprite.BackColor = vbWhite picSprite.AutoRedraw = True picSprite.ZOrder 1 picMask.ScaleMode = vbPixels picMask.BorderStyle = vbBSNone picMask.BackColor = vbWhite picMask.FillColor = vbBlack picMask.FillStyle = vbFSSolid picMask.AutoRedraw = True picMask.ZOrder 1 Command1.Move picMain.Width * 0.3, picMain.Height Command2.Move Command1.Width * 1.2 + Command1.Left, picMain.Height Command3.Move Command2.Width * 1.2 + Command2.Left, picMain.Height, _ Command2.Width * 1.5, Command2.Height Command1.Caption = "Cut Selection" Command2.Caption = "Copy Selection" Command3.Caption = "Show / Hide Sprite and Mask" Command1.Enabled = False: Command2.Enabled = False End Sub Private Sub Form_Unload(Cancel As Integer) DeleteObject Rgn1 DeleteObject Rgn2 End Sub Private Sub picmain_MouseDown(Button As Integer, _ Shift As Integer, x As Single, y As Single) Dim retVal As Long Select Case Button Case vbLeftButton If SelectionValid = True Then picMain.DrawMode = vbXorPen picMain.FillStyle = vbFSTransparent Polygon picMain.hdc, d1(0), lastCoord + 1 End If SelectionValid = False Command1.Enabled = False Command2.Enabled = False Drawing = True picMain.ForeColor = vbWhite picMain.DrawMode = vbNop picMain.PSet (x, y) picMain.DrawMode = vbXorPen ReDim d1(0 To 100) lastCoord = 0 d1(lastCoord).x = x d1(lastCoord).y = y Case vbRightButton ' not yet used End Select End Sub Private Sub picmain_MouseMove(Button As Integer, _ Shift As Integer, x As Single, y As Single) If Not Drawing Then Exit Sub picMain.Line -(x, y) lastCoord = lastCoord + 1 If lastCoord > UBound(d1) Then ReDim Preserve d1(0 To lastCoord + 100) End If d1(lastCoord).x = x d1(lastCoord).y = y End Sub Private Sub picmain_MouseUp(Button As Integer, _ Shift As Integer, x As Single, y As Single) Drawing = False If Button = vbLeftButton Then picMain.Line -(d1(0).x, d1(0).y) If lastCoord > 0 Then SelectionValid = True Command1.Enabled = True Command2.Enabled = True End If End If End Sub Private Sub MakeSpriteAndMask() picSprite.Width = Me.ScaleX(Rect1.Right - Rect1.Left, _ vbPixels, Me.ScaleMode) picSprite.Height = Me.ScaleY(Rect1.Bottom - Rect1.Top, _ vbPixels, Me.ScaleMode) picSprite.Cls ' clear to white ' move Rgn2 to location (0, 0) and select into picSprite OffsetRgn Rgn2, -Rect1.Left, -Rect1.Top SelectClipRgn picSprite.hdc, Rgn2 ' blit the rectangle containing the region into ' from picMain into picSprite BitBlt picSprite.hdc, 0, 0, picSprite.ScaleWidth, _ picSprite.ScaleHeight, picMain.hdc, _ Rect1.Left, Rect1.Top, vbSrcCopy picSprite.Refresh ' just for display while testing ' set up picMask accordingly picMask.Width = picSprite.Width picMask.Height = picSprite.Height picMask.Cls PaintRgn picMask.hdc, Rgn2 picMask.Refresh ' just for display while testing End Sub Private Sub Command1_Click() ' Cut selected area to sprite and mask buffers Dim retVal As Long If SelectionValid = True Then ' erase vbXorPen drawn polygon by redrawing Polygon picMain.hdc, d1(0), lastCoord + 1 ' create two regions using the polygon data DeleteObject Rgn1: DeleteObject Rgn2 Rgn1 = CreatePolygonRgn(d1(0), lastCoord + 1, WINDING) Rgn2 = CreatePolygonRgn(d1(0), lastCoord + 1, WINDING) ' paint the region white retVal = GetRgnBox(Rgn1, Rect1) If retVal <> 0 And retVal <> NULLREGION Then MakeSpriteAndMask ' cut the selected area to white picMain.FillColor = vbWhite picMain.FillStyle = vbFSSolid picMain.DrawMode = vbCopyPen PaintRgn picMain.hdc, Rgn1 picMain.FillStyle = vbFSTransparent picMain.Refresh End If End If SelectionValid = False Command1.Enabled = False Command2.Enabled = False End Sub Private Sub Command2_Click() ' Copy selected area to sprite and mask buffers Dim retVal As Long If SelectionValid = True Then ' erase vbXorPen drawn polygon by redrawing Polygon picMain.hdc, d1(0), lastCoord + 1 ' create two regions using the polygon data DeleteObject Rgn1: DeleteObject Rgn2 Rgn1 = CreatePolygonRgn(d1(0), lastCoord + 1, WINDING) Rgn2 = CreatePolygonRgn(d1(0), lastCoord + 1, WINDING) ' paint the region white retVal = GetRgnBox(Rgn1, Rect1) If retVal <> 0 And retVal <> NULLREGION Then MakeSpriteAndMask picMain.Refresh End If End If SelectionValid = False Command1.Enabled = False Command2.Enabled = False If picSprite.Visible Then picSprite.Move 0, 0 picMask.Move Me.ScaleWidth - picMask.Width, 0 End If End Sub Private Sub Command3_Click() ' show / hide the sprite and mask PictureBoxes ' (This is just for test purposes and the ' sprite and mask images will overlap on the ' Form they are large If SpriteVisible Then picSprite.ZOrder 1: picMask.ZOrder 1 SpriteVisible = False Else picSprite.Move 0, 0 picMask.Move Me.ScaleWidth - picMask.Width, 0 picMask.ZOrder 0: picSprite.ZOrder 0 SpriteVisible = True End If End Sub
From: Bee on 17 Nov 2009 18:20 Thanks again Mike. I used the clipboard because it seemed easier for me to deal with it all when I was doing the limited box lasso. It works and has the side benefit that the copy or cut image is available on the clipboard if needed. I am always torn as in when to use a picturebox component or a Dim pic As Picturebox or Dim pic As StdPicture. I will take a long look at this latest effort on your part. Maybe you should write a book on all of this graphics API call stuff. I would buy it. I'll bet others would too because as far as I know, stuff like this is not built into that other language or C++. Many would get a good education. You are very well informed. Still would like to find a book or website dealing with all of this.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: How to get disk size in VB6 Next: ODBC driver error with Visual Foxpro Version 9 |