BitBlt scroll left AND right
BitBlt scroll left AND right
BitBlt scroll left AND right
BitBlt scroll left AND right
BitBlt scroll left AND right
BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right
BitBlt scroll left AND right BitBlt scroll left AND right
BitBlt scroll left AND right
Go Back  Xtreme Visual Basic Talk > > > BitBlt scroll left AND right


Reply
 
Thread Tools Display Modes
  #1  
Old 03-01-2010, 06:25 PM
GlynD GlynD is offline
Newcomer
 
Join Date: Mar 2010
Location: Telford, UK
Posts: 6
Default BitBlt scroll left AND right


Hiya folks

I am building a dial for a flight-sim and I am having some problems. I have figured out how to scroll the image one way but not back the other - and I have searched high and low for an example... Here's what I got at the moment:
Code:
Option Explicit
Private Declare Function BitBlt Lib "gdi32" (etc... etc...)

Const BackLength As Long = 720 'Back ground dimensions - width of compass gauge...

Const WindowWidth As Long = 201 'The size of the view window
Const WindowHeight As Long = 92

Dim lngScroll As Long 'Compass gauge position
Dim intCompassBearing As Integer
And then a timer which will check for data coming in from the sim and move the compass to the correct position...

Code:
Private Sub tmrScroll_Timer()

Dim GlueWidth As Long, EndScroll As Long

If cboDirection.ListIndex = 0 Then
    lngScroll = (lngScroll Mod BackLength) + 2
    intCompassBearing = (intCompassBearing Mod 360) + 1
Else
    lngScroll = (lngScroll Mod BackLength) - 2
    intCompassBearing = (intCompassBearing Mod 360) - 1
End If

If lngScroll + WindowWidth > BackLength Then
    
    GlueWidth = lngScroll + WindowWidth - BackLength
    EndScroll = WindowWidth - GlueWidth
    
    'Blit the first part
    BitBlt picWindow.hDC, 0, 0, EndScroll, WindowHeight, picDial.hDC, lngScroll, 0, vbSrcCopy
    'Now draw from the beginning again
    BitBlt picWindow.hDC, EndScroll, 0, GlueWidth, WindowHeight, picDial.hDC, 0, 0, vbSrcCopy
    
Else
    
    BitBlt picWindow.hDC, 0, 0, WindowWidth, WindowHeight, picDial.hDC, lngScroll, 0, vbSrcCopy
    
End If

picWindow.Refresh

If intCompassBearing < 0 Then
    intCompassBearing = intCompassBearing + 360
    lblScrollPos.Caption = intCompassBearing
Else
    lblScrollPos.Caption = intCompassBearing
End If

End Sub
At the moment the cboDirection box just controls the direction of the dial picture (attached and also pic of gauge form) scroll at the moment - that will be replaced with the program querying the sim for the compass bearing...

scale.jpg

Cheers in advance
Attached Images
File Type: bmp scale.bmp (194.1 KB, 16 views)
File Type: jpg wet_compass.jpg (83.0 KB, 25 views)
Reply With Quote
  #2  
Old 03-02-2010, 04:13 AM
Andorsay Andorsay is offline
Privileges Suspended
 
Join Date: Feb 2010
Location: Canada
Posts: 101
Cool BitBlt from Picture to another Picture and Scroll

Looks Kewl!!

Take a look at my Code and see what I have done to accomplish this.

I am BitBlitting from Picture1 (Picture1.hDC) to Picture2 (Picture2.hDC).

Remember to set the Form and Pictures ScaleMode to Pixel.

Enjoy!

- Andorsay

In a Module:

Code:
Option Explicit

' Raster Operation
Public Const SrcCopy = &HCC0020

' BitBlt Function
Public 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

' Sleep Sub
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
In a Form:

Create 2 Pictures named Picture1 and Picture2 and 2 Labels named Label1 and Label2.

Picture1 contains your Full Picture. Width = 720, Height = 92.
Picture2 is currently empty. Width = 201, Height = 92.
Label 1 will be the X value of the Scroll.
Label 2 will read "Left Arrow Decreases, Right Arrow Increases".

Set the Form's ScaleMode to 3 - Pixel.
Set Picture1's ScaleMode to 3 - Pixel.
Set Picture2's ScaleMode to 3 - Pixel.

Set the Form's KeyPreview to True.

Code:
Option Explicit

Dim WhatX As Integer
Dim Retval As Long


Public Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

    If KeyCode = 37 Then
        WhatX = WhatX - 1
        If WhatX < 0 Then
            WhatX = 0
            Exit Sub
        End If
        Label1.Caption = WhatX
        Retval = BitBlt(Picture2.hDC, 0, 0, 201, 92, Picture1.hDC, WhatX, 0, SrcCopy)
        Exit Sub
    End If
    
    If KeyCode = 39 Then
        WhatX = WhatX + 1
        If WhatX > 519 Then ' (Width of Picture(720) - Width of Portal Window(201))
            WhatX = 519
            Exit Sub
        End If
        Label1.Caption = WhatX
        Retval = BitBlt(Picture2.hDC, 0, 0, 201, 92, Picture1.hDC, WhatX, 0, SrcCopy)
    End If

End Sub

Public Sub Initialize()

    WhatX = 0
    Label1.Caption = WhatX
    
    Sleep 200 ' Sleep for 200 Milliseconds
    
    ' BitBlt Destination, DestX, DestY, SourceDestWidth, SourceDestHeight, Source, SourceX, SourceY, RasterOp
    Retval = BitBlt(Picture2.hDC, 0, 0, 201, 92, Picture1.hDC, WhatX, 0, SrcCopy)

End Sub

Public Sub Form_Load()

    Me.Show
    Me.Refresh
    Call Initialize

End Sub
Attached Files
File Type: zip BitBlittingPictures.zip (11.7 KB, 25 views)

Last edited by passel; 03-02-2010 at 10:09 AM.
Reply With Quote
  #3  
Old 03-02-2010, 07:55 AM
GlynD GlynD is offline
Newcomer
 
Join Date: Mar 2010
Location: Telford, UK
Posts: 6
Default

Thanks very much Andorsay

However it is not quite what is needed, as the gauge only scrolls to the limit of the picture. It needs to scroll both ways continuously...

I have found some code to allow it to scroll continuously in one direction - but not the other. I have attached the project to this thread.

Cheers
Attached Files
File Type: zip wet_compass.zip (20.9 KB, 15 views)
Reply With Quote
  #4  
Old 03-02-2010, 09:12 AM
passel's Avatar
passelBitBlt scroll left AND right passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Simplest, rather than have to do two bitblts, is make the source image wider, to accomodate the size of your display window.
In your case, it looks like your display window is 100 degrees wide, so rather than have 360 degrees in your source, make it 460 degrees (I would make it run from 310 degrees, 0 degrees in the middle of the window, to 50 degrees, 0 degrees still in the middle).
Then it is a simple matter of taking the degree value in, which you want in the middle of your window, and use it to select the source X value.
If you created your source image so that 0 degree position is 1/2 your output window width from the left edge of your source, then it is a simple matter to use the value directly (eg. 0 degree input angle means you bitblt from from source X of 0. For 10 degrees, you bitblt from source X of 10 degrees worth of pixels).

Below is a quick example, sort of based on the images from your first post.
Just open a new project and add two pictureboxes to the form, and paste in the code below.

When you run the code it will resize the pictureboxes and create a source image running from 310 to 50 degrees (460 degrees of scale)

If you drag with the left mouse on the smaller picturebox, it will change an angle value and "bitblt" (using paintpicture) from the source to the destination,
using the ang value directly to select the source X position.
Just in case the smaller window is not where you want it in the IDE, I also added a little code to allow dragging the picturebox using the right mouse button.
Code:
Option Explicit Private Sub Form_Load() ScaleMode = vbPixels Picture1.BackColor = vbBlack Picture1.BorderStyle = vbBSNone Picture1.ScaleMode = vbPixels Picture1.AutoRedraw = True Picture1.Height = 50 Picture1.Width = 460 Picture1.ForeColor = vbWhite Picture2.BackColor = vbBlack Picture2.ScaleMode = vbPixels Picture2.Height = 50 Picture2.Width = 100 Picture2.AutoRedraw = True Dim i As Integer, X As Integer, s As String 'Draw the Compass tape For i = 0 To 460 Step 5 X = (360 + (i - 50)) Mod 360 'keep x in the range 0 to 359 If X Mod 90 = 0 Then Picture1.Line (i, 50)-Step(0, -20), vbWhite Select Case X Case 0: s = "N" Case 90: s = "E" Case 180: s = "S" Case 270: s = "W" End Select Picture1.CurrentX = Picture1.CurrentX - (Picture1.TextWidth(s) / 2) Picture1.CurrentY = Picture1.CurrentY - (Picture1.TextHeight(s) + 2) Picture1.Print s ElseIf X Mod 10 = 0 Then Picture1.Line (i, 50)-Step(0, -13), vbWhite If X Mod 30 = 0 Then s = Trim$(CStr(X)) Picture1.CurrentX = Picture1.CurrentX - (Picture1.TextWidth(s) / 2) Picture1.CurrentY = Picture1.CurrentY - (Picture1.TextHeight(s) + 4) Picture1.Print s End If Else Picture1.Line (i, 50)-Step(0, -10), vbWhite End If Next End Sub Private Sub Picture2_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Static ang As Integer Static lx As Single, ly As Single If Button = vbLeftButton Then ang = (ang + (lx - X)) Mod 360 'keep in range -359 to 359 If ang < 0 Then ang = ang + 360 'keep in range 0 to 359 'You would bitblt rather than PaintPicture at this point, but I didn't care to 'look up the declaration, so used the built-in PaintPicture. Picture2.PaintPicture Picture1.Image, 0, 0, 100, 50, ang, 0, 100, 50 lx = X: ly = Y ElseIf Button = vbRightButton Then 'Added to allow moving the window, in case it is not where you want it in the IDE 'Don't save X, Y when moving the window Picture2.Top = Picture2.Top + (Y - ly) Picture2.Left = Picture2.Left + (X - lx) Else lx = X: ly = Y End If End Sub
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 03-02-2010 at 10:35 AM. Reason: Added a quick example of what I described.
Reply With Quote
  #5  
Old 03-03-2010, 02:34 AM
GlynD GlynD is offline
Newcomer
 
Join Date: Mar 2010
Location: Telford, UK
Posts: 6
Default

Thanks very much Passel, I will give that code a try later on and see if it does the trick - certainly looks like it will

Cheers
Reply With Quote
  #6  
Old 03-04-2010, 09:14 AM
passel's Avatar
passelBitBlt scroll left AND right passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

While the method I used simplifies the bitblt, it does have the drawback of not being reusable without modification.
Also, if the output window size is changed or the source bitmap changed, the code has to be modified to accomodate the changes.

So, I do see the benefit of having a source image which is strickly the size of one "rotation" of some range, whether it be for a compass tape, or a pitch ladder, etc.
and having a general routine that given a point in the source bitmap will copy, wrapping if necessary, a portion of the source bitmap to a given sized output window.
The general routine should know nothing about the scale or units of the graphic in the bitmap, it would just copy pixels to fill the given output window.
It would be up to the calling program to convert the Scale Unit to the Center reference pixel coordinate.

I don't know if that statement is clear, so an example is probably best.

Using your code, we'll add a WrapWindow Sub and have your timer code call it.
The timer code will computer the Compass Bearing, as it does, and then convert Compass Bearing into the X coordinate of the pixel in the source bitmap that we want centered in the output window, and pass that to the WrapWindow Sub.
Since your source bitmap has 2 pixels per degree, and the 0 degree pixel is 10 degrees from the left edge, we can convert
degree to pixel coordinate using (degree + 10) * 2.

Code:
Private Sub tmrScroll_Timer() If cboDirection.ListIndex = 0 Then intCompassBearing = (intCompassBearing Mod 360) + 1 Else intCompassBearing = (intCompassBearing Mod 360) - 1 End If If intCompassBearing < 0 Then intCompassBearing = intCompassBearing + 360 lblScrollPos.Caption = intCompassBearing Else lblScrollPos.Caption = intCompassBearing End If WrapWindow picWindow, picDial, (intCompassBearing + 10) * 2 picWindow.Refresh End Sub Private Sub WrapWindow(ToPic As PictureBox, FromPic As PictureBox, FromCenterX As Long) 'For simplicity, this Sub expects PictureBoxes scalemode to be pixels. 'And the height of the ToPic to be the height we want copied. 'Also, the ToPic width can't be greater than the FromPic width, or the logic will fail 'If ToPic's ScaleWidth is not an odd number of pixels (a "center" pixel with an even 'number of pixels on each side), there can be an "off by one" alignment issue. Dim FromLeft As Long, FromRight As Long, FirstWidth As Long Dim ToCenter As Long, WindowHeight As Long WindowHeight = ToPic.ScaleHeight ToCenter = ToPic.ScaleWidth / 2 FromLeft = FromCenterX - ToCenter FromRight = FromCenterX + ToCenter If FromLeft < 0 Or FromRight >= FromPic.ScaleWidth Then If FromLeft < 0 Then FirstWidth = -FromLeft FromLeft = FromPic.ScaleWidth - FirstWidth Else 'FromRight exceeds the width of the source window FirstWidth = FromPic.ScaleWidth - FromLeft FromRight = FromRight - FromPic.ScaleWidth End If BitBlt ToPic.hDC, 0, 0, FirstWidth, WindowHeight, FromPic.hDC, FromLeft, 0, vbSrcCopy BitBlt ToPic.hDC, FirstWidth, 0, FromRight, WindowHeight, FromPic.hDC, 0, 0, vbSrcCopy Else 'the portion to be copied falls completely within the source bitmap BitBlt ToPic.hDC, 0, 0, ToPic.ScaleWidth, WindowHeight, FromPic.hDC, FromLeft, 0, vbSrcCopy 'do a single bitblt End If End Sub

Now the output window can be resized (should maintain an odd number of pixels in the ScaleWidth for proper centering) and you don't need to make any code modifications.

By the way, you're missing the left third of your 350 degree bearing line in your bitmap.
You should bring up paint, and copy one of the other 10 degree bearing lines to the right edge of your bitmap, just leaving the left 1 pixel wide portion of the line visible at the right edge, so the wrap is undetectable.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 03-04-2010 at 09:27 AM. Reason: Remove old comment from code
Reply With Quote
  #7  
Old 03-05-2010, 02:43 AM
GlynD GlynD is offline
Newcomer
 
Join Date: Mar 2010
Location: Telford, UK
Posts: 6
Default

Thanks Passel I will give that code a try tonight and report back. Ref the dial - it is 720 pixels wide and has markings at every 10 pixels (5 degree marks), so as far as I was aware that there are no missing portions?

Cheers
Reply With Quote
  #8  
Old 03-05-2010, 09:56 AM
Andorsay Andorsay is offline
Privileges Suspended
 
Join Date: Feb 2010
Location: Canada
Posts: 101
Cool BitBlitting a Compass with Degrees

I took a look at the code, made some necessary modifications, and simplified it.

The compass now scrolls in both directions while displaying the Degrees.

I have created the DrawCompass routine as a Function.
So all you have to do is pass it the Degrees.

Example:
Code:
Degrees = 180
Call DrawCompass(Degrees)
I have added enough comments in the Code for you to understand what
is going on.

Enjoy!

- Andorsay


Module Code:
Code:
Option Explicit

' Raster Operation
Public Const SrcCopy = &HCC0020

' BitBlt Function
Public 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

Form Code:
Code:
Option Explicit

' **********************************************************************
' *                                                                    *
' *  Project Title: BitBlitting a Compass with Degrees                 *
' *                                                                    *
' *  Copyright © 2010 Andorsay.                                        *
' *                                                                    *
' **********************************************************************

Dim WhatX As Integer
Dim WhatX2 As Integer
Dim WhatX3 As Integer
Dim Degrees As Integer

Dim Retval As Long

Dim IsItOutOfBounds As Boolean


Public Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

    If KeyCode = 37 Then ' Left Arrow Key

        ' Degrees
        Degrees = Degrees - 1
        If Degrees < 0 Then Degrees = 359
        Label1.Caption = Degrees

        ' Indicator Position
        imgIndicator.Left = imgIndicator.Left - 2
        If imgIndicator.Left < 13 Then imgIndicator.Left = 731

        ' Draw Compass with the Degrees Centered
        Call DrawCompass(Degrees)

        Exit Sub

    End If

    If KeyCode = 39 Then ' Right Arrow Key

        ' Degrees
        Degrees = Degrees + 1
        If Degrees > 359 Then Degrees = 0
        Label1.Caption = Degrees

        ' Indicator Position
        imgIndicator.Left = imgIndicator.Left + 2
        If imgIndicator.Left > 731 Then imgIndicator.Left = 13

        ' Draw Compass with the Degrees Centered
        Call DrawCompass(Degrees)

    End If

End Sub

Public Function DrawCompass(myDegrees As Integer) As Long

    ' Convert Degrees to Picture1 X Location
    WhatX = (Degrees * 2) + 20

    Call CheckForOutOfBounds

    If IsItOutOfBounds = False Then

        Retval = BitBlt(Picture2.hDC, 0, 0, 201, 92, Picture1.hDC, (WhatX - 100), 0, SrcCopy)

    End If

    IsItOutOfBounds = False

End Function

Public Sub CheckForOutOfBounds()
' We have 100 pixels on either side of the Centered Degree.
' Thus the Picture2.Width of 201 Pixels.

    ' Check if (WhatX - 100) is out of bounds
    If (WhatX - 100) < 0 Then

        IsItOutOfBounds = True
        WhatX2 = (100 - WhatX)
        ' Ex: Degrees = 30
        ' WhatX = (30 * 2) + 20 = 80
        ' WhatX2 = (100 - 80) = 20
        ' So we have 20 pixels to grab from the end of Picture1.
        ' Which leaves us with a remainder of (Picture2.Width - 20) pixels to grab from the beginning of Picture1.

        Retval = BitBlt(Picture2.hDC, 0, 0, WhatX2, 92, Picture1.hDC, (Picture1.Width - WhatX2), 0, SrcCopy)
        Retval = BitBlt(Picture2.hDC, WhatX2, 0, (Picture2.Width - WhatX2), 92, Picture1.hDC, 0, 0, SrcCopy)
        Exit Sub

    End If

    ' Check if (WhatX + 100) is out of bounds
    If (WhatX + 100) > Picture1.Width Then

        IsItOutOfBounds = True
        WhatX3 = (WhatX - 100)
        ' Ex: Degrees = 301
        ' WhatX = (301 * 2) + 20 = 622
        ' WhatX3 = (622 - 100) = 522

        Retval = BitBlt(Picture2.hDC, 0, 0, (Picture1.Width - WhatX3), 92, Picture1.hDC, WhatX3, 0, SrcCopy)
        Retval = BitBlt(Picture2.hDC, (Picture1.Width - WhatX3), 0, (Picture2.Width - (Picture1.Width - WhatX3)), 92, Picture1.hDC, 0, 0, SrcCopy)
        Exit Sub

    End If

End Sub

Public Sub Initialize()

    Degrees = 0
    WhatX = 0
    IsItOutOfBounds = False

    Label1.Caption = Degrees

    Call DrawCompass(Degrees)

End Sub

Public Sub Form_Load()

    Me.Show
    Me.Refresh
    Call Initialize

End Sub
Attached Files
File Type: zip BitBlittingaCompass.zip (12.3 KB, 81 views)

Last edited by Andorsay; 03-06-2010 at 01:49 AM. Reason: Changed 732 to be 731 for proper Indicator Positioning.
Reply With Quote
  #9  
Old 03-05-2010, 03:18 PM
passel's Avatar
passelBitBlt scroll left AND right passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Quote:
Originally Posted by GlynD View Post
... Ref the dial - it is 720 pixels wide and has markings at every 10 pixels (5 degree marks), so as far as I was aware that there are no missing portions?
Cheers
Yes it is 720 pixels wide which is appropriate (2 pixels per degree * 360 degrees).

If you open the bitmap in Paint and zoom in, you will notices that the image is anti-aliased to look smoother.
Each vertical line is actually 3 pixels wide, the Center Line pixels are full white and this center line of pixels is what your lubber line should line up with when the degree value is exactly the value indicated by the line.

The pixels on each side of the full white pixels are gray to give the line a smooth appearance.

The full white line of pixels (the "center line") for the 350 degree mark on your scale is at the left edge of your bitmap (X coordinate = 0).

So you only have two of the pixel columns of your three pixel column wide line represented for the 350 degree line.

The left column of gray pixels that make up the 350 degree line should be
all the way over at the right edge of your bitmap (in the last pixel column, X coordinate = 719).
Your last column of pixels is black, so the gray anti-aliasing pixels for the 350 degree line are missing.

If you scroll the picture with your bitmap you should notice that the 350 degree line looks a little thinner than the other lines of the compass tape.

I'll attach a Jpg of what the bitmap should look like. You should see the gray column of pixels added to the right edge of the bitmap to complete your 350 degree line.
Attached Images
File Type: jpg scale.JPG (8.0 KB, 7 views)
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #10  
Old 03-06-2010, 10:09 AM
GlynD GlynD is offline
Newcomer
 
Join Date: Mar 2010
Location: Telford, UK
Posts: 6
Default

Ah ha I see what you are saying now, and yes you are indeed correct... I have added the extra bit to the source image!

Cheers
Reply With Quote
  #11  
Old 03-06-2010, 10:19 AM
GlynD GlynD is offline
Newcomer
 
Join Date: Mar 2010
Location: Telford, UK
Posts: 6
Default

Thanks Andorsay that is just what I needed! Excellent

And thanks to all that replied

Cheers
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
BitBlt scroll left AND right
BitBlt scroll left AND right
BitBlt scroll left AND right BitBlt scroll left AND right
BitBlt scroll left AND right
BitBlt scroll left AND right
BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right BitBlt scroll left AND right
BitBlt scroll left AND right
BitBlt scroll left AND right
 
BitBlt scroll left AND right
BitBlt scroll left AND right
 
-->