dcsimg
Page 1 of 2 12 LastLast
Results 1 to 40 of 41

Thread: How can I draw OVER MSFlexGrid display?

  1. #1

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    How can I draw OVER MSFlexGrid display?

    Hi,

    I've been trying to figure out a way to draw a small circle over an MSFlexGrid table using standard VB drawing command "Circle(XY)", etc. Only problem is that any graphics produced this way are BEHIND the grid itself.

    What I am trying to do here is to draw a small circle that indicates the current X,Y position on the table which are two analog datapoints being acquired by a DAQ setup - at about 30 samples per second.

    I tried using the CellBackColor to highlight the current cell, however, it is INCREDIBLY slow to redraw the grid's backcolor and it causes the digital display of those input values in two textboxes to stumble as new data comes in.

    I've considered using a picturebox and overlaying that atop the MSFlexGrid and using a transparent background in the picturebox,however, the examples I found for doing that have not worked. I'm not even sure that this would work in the way I need it to?

    Perhaps there is a way to push the circle drawing itself to the top, displayed "in front" of the flexgrid rather than how it is now, displaying behind it?

    Here is a screenshot of what I mean: The red half-circle at the top edge of the MSFlexGrid... It is a full circle but half is hidden behind the grid.
    Attached Images Attached Images  

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,577

    Re: How can I draw OVER MSFlexGrid display?

    Drawing commands and windowless controls (shape/image controls for example) can never be drawn above a windowed control - your flex grid.

    Not that familiar with the MSHFlexGrid, but if there is another way to highlight, i.e., bold or text color change, you may want to look at that. If you want to overlay a picturebox, you can do that via transparency, but requires Win8+ I believe. Another option, available to all O/S versions is to punch a hole in a picturebox and paint the remainder however you'd like (one or multiple colors). Then position the picturebox over the control and ensuring its ZOrder is top most.

    Give above a thought along with whatever others may offer and let us know which way you are leaning.

    Welcome to the forums
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    Hi LaVolpe! Ironic that I came across a few code snippets regarding transparent pictureboxes last night that I was trying but could not get the code to run. I am on Win7 (yeah, I know, but it is ROCK solid) but not sure if that was the limitation I was running into.

    On the method of punching holes, If I could punch just a "cylinder wall", if you will, so that you can still see through the inside of the circle, then that would work. I could make the circle much smaller and have it filled, something like 5x5 pixels in size and that would work too as it won't make it too difficult to see the actual numerical value in the grid. I think that may be a simpler approach and would work just fine. I just need a position indicator on the grid to reflect current input values.

    I do prefer this application to have backward compatibility to Win7 for anyone wanting to run it so if the transparent picturebox approach will be backward compatible to Win7 after compilation then I'm game for that. If not then I'll probably need hack about it another way.

    Thanks for replying!! And thank you for the welcome!

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,808

    Re: How can I draw OVER MSFlexGrid display?

    Is this 30 events/sec activity also scrolling this cell into view?

    Or if this tabular data is static and all fits within the view why not draw it statically instead of using a grid control? Such controls have a ton of built-in functionality and that doesn't come for free. Most of it is meant to operate at human-input rates, not automated streaming activity.

    I'm not sure we have enough information. As a result all we can do is throw out suggestions and let you shoot them down one by one.

    It is pretty easy to use a UserControl with mask transparency as a canvas.

    We also have layered child windows in Win8+, see http://www.vbforums.com/showthread.p...-child-windows

  5. #5

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    Dilettante,
    Not sure what you mean by scrolling the cell. The grid values are ~static. The green highlight indicates a grid position focus where the user can + or - the value (and use arrowkeys to change focus) but those events are only happening at the rate in which a user can press a key. This does cause a brief hiccup in the textboxes that are showing the sampled data coming in but it isn't a big issue because it only affects the application when a user changes the value. The grid values are all pulled from EEPROM within a micro connected via usb and changes to grid values are sent/stored in the micros EEPROM space. I imagine I *could* make each cell a textbox and create the same appearance (for sake of possibly faster operation) but textboxes have the same issue as the grid does - graphics get placed behind them.

    Having a "floating" circle or dot over this grid would be very ideal as there is bilinear interpolation occurring within the micro in how it accesses this table anyway. A floating pointer could actually point to a more "exact" X and Y coordinate rather than having just one cell being highlighted.

    I'm also running Win7 and would like to maintain backwards compatibility for the sake of customers wanting to use an older system. If push comes to shove I can upgrade the system but that's more of a last ditch effort.

  6. #6
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,968

    Re: How can I draw OVER MSFlexGrid display?

    Hello.

    The way I suggest is to use regions. Place a picturebox over the grid, then draw whatever you want into it (a circle) and then make a region with all the remaining (untouched) background color and apply that region to the picturebox window.

    API's: CreateRectRgn, SetWindowRgn and DeleteObject.

  7. #7

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    Having issues with this forum.. it thinks I Am trying to double post

  8. #8

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    Quote Originally Posted by Eduardo- View Post
    Hello.

    The way I suggest is to use regions. Place a picturebox over the grid, then draw whatever you want into it (a circle) and then make a region with all the remaining (untouched) background color and apply that region to the picturebox window.

    API's: CreateRectRgn, SetWindowRgn and DeleteObject.
    Hi Eduardo,

    That is what I was thinking would be the way to go about this. Only problem is in my attempts to do this I could not find any example of working code that shows how to do JUST this. Also, will this approach work on a Win7 system as well?

  9. #9
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,577

    Re: How can I draw OVER MSFlexGrid display?

    Yes, the SetWindowRgn is compatible all the way back to Win95. Here's a quick example

    1. Add a command button and picturebox to a form, leave all defaults as is
    2. Paste this code & run the project
    Code:
    Option Explicit
    
    Private Declare Function SetWindowRgn Lib "user32.dll" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Long) As Long
    Private Declare Function CreateRectRgn Lib "gdi32.dll" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
    Private Declare Function CombineRgn Lib "gdi32.dll" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
    Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
    Private Const RGN_XOR As Long = 3
    
    
    Private Sub Command1_Click()
    
        Dim hRgn As Long, hRgnInner As Long
        
        Picture1.ScaleMode = vbPixels
        
        ' create overall region the size of the picturebox
        hRgn = CreateRectRgn(0, 0, ScaleX(Picture1.Width, Me.ScaleMode, vbPixels), ScaleY(Picture1.Height, Me.ScaleMode, vbPixels))
        ' create region size of hole we want to punch out
        hRgnInner = CreateRectRgn(10, 10, Picture1.ScaleWidth - 10, Picture1.ScaleHeight - 10)
        ' combine the two to remove the hole from the overall region
        CombineRgn hRgn, hRgn, hRgnInner, RGN_XOR
        ' destroy the "hole" region
        DeleteObject hRgnInner
        ' assign region to the picture box & position it
        SetWindowRgn Picture1.hWnd, hRgn, True
        Picture1.Move 0, 0
        Picture1.BackColor = vbRed
    
    End Sub
    
    Private Sub Form_Load()
        With Command1
            .Move 330, 495
        End With
        With Picture1
            .Move 1830, 225, 2190, 1530
        End With
    End Sub
    Last edited by LaVolpe; Jan 9th, 2019 at 10:25 PM. Reason: Fixed API parameter vartype
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    Lavolpe,

    OK, upon running, the picturebox is transparent. But when trying to draw a circle within the picturebox either before or after the lines in the Form_Load, I See nothing. What's up, Doc?

  11. #11
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,577

    Re: How can I draw OVER MSFlexGrid display?

    Using regions, you have to be familiar enough with the various options. There is an API to create circle/oval regions: CreateEllipticRgn

    Substitute that API call for the CreateRectRgn API call I used in the sample. The region will have a rough, not smooth, shape. Very similar to your drawn circle/oval in your original post.

    Drawing a circle isn't in play here, per se. What you are doing is reshaping the picturebox via regions to the shape it the way you want, in this case, a circle. You are treating the picturebox as a "drawn circle"; just move it to where you need it & hide it when you don't need it. Note. You'll probably want to make the picturebox borderless
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  12. #12

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    OK, scratch that first call. In your code you are moving the picturebox well out of my form, LOL. I trimmed the move values and I Can see the picturebox. When I click the command button it moves the box and fills it in with red. I presume what you are suggesting is that I can change this picturebox from a rectangle into an elliptical region that has red within it and then use the move command to position it where I need it? I'll give that a whirl. Thanks!

  13. #13
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,577

    Re: How can I draw OVER MSFlexGrid display?

    You got it.

    Picturebox moved well out of your form? I moved it to 0,0 which is the top/left corner of the form. That part confused me. The moving was to place the picturebox over the button so that you can clearly see the "hole" we created inside the picturebox. That was the intent anyway.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  14. #14
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,968

    Re: How can I draw OVER MSFlexGrid display?

    Here is another example.
    Attached Files Attached Files

  15. #15

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    Quote Originally Posted by Eduardo- View Post
    Here is another example.
    Eduardo,

    I'm working with the code you sent and trying to integrate it. The picturebox goes transparent in the call but it isn't drawing a circle in my code. You have the picturebox ScaleMode set to 1-Twip and I See you are making calls to the circle size using this. I have set my picturebbox to the same scalemode as I had to in order to get it to run. Are there any other critical settings on the form or picturebox I need to be aware of that could be causing it not to draw in the red circle?

  16. #16
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,968

    Re: How can I draw OVER MSFlexGrid display?

    Quote Originally Posted by AshPowers View Post
    Eduardo,

    I'm working with the code you sent and trying to integrate it. The picturebox goes transparent in the call but it isn't drawing a circle in my code. You have the picturebox ScaleMode set to 1-Twip and I See you are making calls to the circle size using this. I have set my picturebbox to the same scalemode as I had to in order to get it to run.
    Change these lines if you want to work with any ScaleMode:

    Code:
        iHeight = nPic.Parent.ScaleX(nPic.Height, nPic.ScaleMode, vbPixels)
        iWidth = nPic.Parent.ScaleY(nPic.Width, nPic.ScaleMode, vbPixels)
    Quote Originally Posted by AshPowers View Post
    Are there any other critical settings on the form or picturebox I need to be aware of that could be causing it not to draw in the red circle?
    Yes, vbRed in:

    Code:
    Picture1.Circle (Picture1.ScaleWidth / 2, Picture1.ScaleWidth / 2), Picture1.ScaleWidth / 2 - Screen.TwipsPerPixelX * 4, vbRed

  17. #17

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    OK, I have made those changes and it still refuses to paint the red circle. I have drawn a circle in the picturebox within the form_load and without calling the PutCircle sub, it clearly shows a red circle in the picturebox, but the background is white as expected. I'm thinking it may have something to do with my Form settings?Name:  speed-density-formsettings.png
Views: 244
Size:  24.9 KB

  18. #18
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,577

    Re: How can I draw OVER MSFlexGrid display?

    You are using a custom scalemode. Can you post the exact code you are using in your project for scaling? At least Eduardo and others can take a look-see and maybe pinpoint the problem. I'm betting it's because of the custom scale.

    Edited: Now I know why my first example I posted way above moved off your form . You tried that example on your project, not a test project. That explains why moving to 0,0 didn't line up in the top/left portion of the form.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  19. #19

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    LaVolpe,
    AutoRedraw doesn't fix the issue, not to mention, I Cannot have that on for the main form. The 3D map you see is drawn from lines using matrix mathematics and transformations. The autoredraw = true never clears the lines once drawn... But this change didn't make it produce the red circle either, so...

  20. #20
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,968

    Re: How can I draw OVER MSFlexGrid display?

    Yes, if possible try to narrow down the issue and post a sample project to see what is happening.

  21. #21
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,968

    Re: How can I draw OVER MSFlexGrid display?

    One thing (a shot in the dark):

    Add Picture1.ZOrder somewhere.

    The picturebox could be staying behind the grid.

  22. #22

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    Quote Originally Posted by LaVolpe View Post
    You are using a custom scalemode. Can you post the exact code you are using in your project for scaling? At least Eduardo and others can take a look-see and maybe pinpoint the problem. I'm betting it's because of the custom scale.

    Edited: Now I know why my first example I posted way above moved off your form . You tried that example on your project, not a test project. That explains why moving to 0,0 didn't line up in the top/left portion of the form.
    I understand what you are saying. But in the case of Eduardo's code, everything is contained within the picturebox region itself and I have drawn a simple circle within that box and not called the transparency/masking module routines in his code, and it puts a red circle within the picturebox, dead center. His actual sample program works like a charm by itself so I'm not sure what the difference is between his program and how it is behaving within mine. My program is kindof lengthy and moving through it may take a bit, but here are the important subs:

    Code:
    Option Explicit
    
    Dim EyeX As Single
    Dim EyeY As Single
    Dim EyeZ As Single
    
    Const Xmin = 0
    Const Xmax = 19
    Const Ymin = 0
    Const Ymax = 19
    
    Dim Points(Xmin To Xmax, Ymin To Ymax) As Point3D
    
    Dim ZVe(439) As Integer
    Dim XVe(20) As Integer
    Dim YVe(20) As Integer
    Dim VEMap(440) As Integer
    Dim DataRcd As Integer
    Dim MapPos As Integer
    Dim MapPosX As Integer
    Dim MapPosY As Integer
    Dim GridUpdate As Integer
    Dim CellColorX As Integer
    Dim CellColorY As Integer
    Dim AxesMoved As Integer
    Dim MapDownload As Integer
    Dim DataStream As Integer
    Dim PSensor As Single
    Dim EngineRPM As Single
    Dim TempSensor As Single
    Dim MASSFlow As Single
    Dim MAFOutV As Single
    Dim SensorLoop As Byte
    Dim RTMapX As Byte
    Dim RTMapY As Byte
    Dim RTTableX As Byte
    Dim RTTableY As Byte
    Dim OldGridTraceX As Byte
    Dim OldGridTraceY As Byte
    Dim OldGridPointerX As Byte
    Dim OldGridPointerY As Byte
    Dim RealTimeData As Byte
    Dim OldX As Integer
    Dim OldY As Integer
    Dim OldTrans(2) As Integer
    Dim MapRefresh As Integer
    Dim OldTraceX As Integer
    Dim OldTraceY As Integer
    Dim Junk As String
    Dim Axes(1 To 3) As Point3D
    Private mRgn As Long
     
    Public Sub Form_Load()
    'Picture1.Circle (Picture1.ScaleWidth / 2, Picture1.ScaleWidth / 2), Picture1.ScaleWidth / 2 - Screen.TwipsPerPixelX * 3, vbRed
    Dim i As Integer
    MSComm1.CommPort = 5
    MSComm1.Settings = "115200,N,8,1"
    MSComm1.RThreshold = 1
    MSComm1.PortOpen = True
    DataRcd = 0
    GridUpdate = 0
    RealTimeData = 0
    Label1.Caption = "^v<> Arrow Keys to Position Marker" & vbNewLine & "CTRL-^v<> to Rotate 3D Map" & vbNewLine & "SHIFT-^v<> to Shift Map Position" & vbNewLine & "+ or - Key To Change Map Value"
    
    
      MapPos = 0
      MapPosX = 0
      MapPosY = 0
      MapDownload = 1
      MSComm1.Output = "<201>"
      Junk = MSComm1.Input
      MSComm1.Output = "<121>"
    
        EyeX = -40
        EyeY = 40
        EyeZ = 60
    With Me.MSFlexGrid1
        .Clear
        For i = 0 To 20
            .ColWidth(i) = 650
            .RowHeight(i) = 275
            .BackColor = RGB(0, 0, 80)
            .GridLineWidth = 1
        Next i
        .ColWidth(0) = 900
    End With
    'PutCircle
    DataStream = 0
    RunMe
    End Sub
    
    Private Sub RunMe()
    Dim x As Single
    Dim y As Single
    Dim R As Single
    Form3D.BackColor = RGB(1, 1, 1)
    Dim i As Integer
    Dim v As Integer
    Dim c As Integer
    c = 0
    i = 0
    v = 0
      
        For i = 0 To 19
            For x = Xmin To Xmax
                For y = Ymin To Ymax
                    Points(x, y).Coord(1) = x   ' X coordinate.
                    Points(x, y).Coord(2) = y   ' Y coordinate.
                    Points(x, y).Coord(4) = 0.7 ' Scale factor.
                    R = ZVe(v) / 10
                    Points(x, y).Coord(3) = R
                    v = v + 1
                    If v > 399 Then
                        v = 0
                    End If
                Next y
            Next x
        Next i
         
        ' Initialize the axes.
        Axes(1).Coord(1) = 20   ' X axis.
        Axes(1).Coord(4) = 1
        Axes(2).Coord(2) = 20   ' Y axis.
        Axes(2).Coord(4) = 1
        Axes(3).Coord(3) = 20   ' Z axis.
        Axes(3).Coord(4) = 1
    
    Draw_Grid
    
    MapRefresh = 1
    
    DrawSurface
    
    End Sub
    
    Private Sub Draw_Grid()
    
    Dim i As Integer
    Dim v As Integer
    Dim c As Integer
    c = 0
    i = 0
    v = 0
    v = 1
        With Me.MSFlexGrid1
            For i = 400 To 419
                .TextMatrix(v, 0) = ZVe(i) * 100
                v = v + 1
            Next i
    v = 1
        
            For i = 420 To 439
                .TextMatrix(0, v) = ZVe(i) - 14.6
                v = v + 1
            Next i
            For i = 1 To 20
                For v = 1 To 20
                    .TextMatrix(v, i) = ZVe(c)
                    c = c + 1
                Next v
            Next i
                           
        End With
    'PutCircle
    'DataRcd = 0
    'GridUpdate = 0
    'Form3D.Refresh
    End Sub
    
    Private Sub ProcessSerial()
    Dim VEData() As String
    Dim i As Integer
    Dim sTemp As String
    Dim Splitter As String
    Dim A As Integer
    Dim EndSearch As Integer
        
        sTemp = MSComm1.Input
        
    If MapDownload = 1 Then
        Splitter = ","
        VEData = Split(sTemp, Splitter)
        A = 0
        For i = 0 To 439
            ZVe(i) = VEData(A)
            A = A + 1
        Next i
        MapDownload = 0
        DataRcd = 1
        RunMe
    End If
        
        
    If DataStream = 1 Then
        A = 0
        Splitter = ","
        VEData = Split(sTemp, Splitter)
        For i = 0 To 5
            If VEData(i) = "255" Then
                A = i
            End If
        Next i
        
        PSensor = VEData(A + 1) - 14.67
        txtPressure.Text = Format(PSensor, "0.0") & " PSI"
        EngineRPM = VEData(A + 2)
        If EngineRPM < 150 Then
            EngineRPM = 0
        End If
        txtRPM.Text = Format(EngineRPM, "0") & " RPM"
        TempSensor = VEData(A + 3)
        txtTemp.Text = TempSensor & " F"
        MASSFlow = VEData(A + 4)
        txtMASS = Format(MASSFlow, "0") & " Kg/hr"
        txtMAFOut.Text = Format(VEData(A + 5), "0.00") & "V Out"
        For i = 400 To 419
            If EngineRPM / 100 > ZVe(i) Then
                RTMapY = i - 400
            End If
        Next i
        PSensor = PSensor + 14.67
        For i = 420 To 439
            If PSensor > ZVe(i) Then
                RTMapX = i - 420
            End If
        Next i
        RealTimeData = 0
        MapRefresh = 0
        DrawSurface
    End If
    'DrawSurface
    End Sub
    ' ********************************************************
    ' Calculate the transformation matrix.
    ' ********************************************************
    Private Sub CalculateTransformation(T() As Single)
    ReDim T1(1 To 4, 1 To 4) As Single
    ReDim T2(1 To 4, 1 To 4) As Single
    Dim r1 As Single
    Dim r2 As Single
    Dim ctheta As Single
    Dim stheta As Single
    Dim cphi As Single
    Dim sphi As Single
    
        ' Rotate around the Z axis so the
        ' eye lies in the Y-Z plane.
        r1 = Sqr(EyeX * EyeX + EyeY * EyeY)
        stheta = EyeX / r1
        ctheta = EyeY / r1
        MakeIdentity T1()
        T1(1, 1) = ctheta
        T1(1, 2) = stheta
        T1(2, 1) = -stheta
        T1(2, 2) = ctheta
    
        ' Rotate around the X axis so the
        ' eye lies in the Z axis.
        r2 = Sqr(EyeX * EyeX + EyeY * EyeY + EyeZ * EyeZ)
        sphi = -r1 / r2
        cphi = -EyeZ / r2
        MakeIdentity T2()
        T2(2, 2) = cphi
        T2(2, 3) = sphi
        T2(3, 2) = -sphi
        T2(3, 3) = cphi
    
        ' Project along the Z axis. (Actually we do nothing
        ' here. We just ignore the Z coordinate when drawing.)
    
        ' Combine the transformations.
        MatrixMatrixMult T(), T1(), T2()
    End Sub
    
    ' ********************************************************
    ' Draw the surface.
    ' ********************************************************
    Private Sub DrawSurface()
    ReDim T(1 To 4, 1 To 4) As Single
    Dim x As Single
    Dim y As Single
    Dim j As Integer
    Dim k As Integer
    
    
        ' Calculate the transformation matrix.
        CalculateTransformation T()
    
        ' Apply the transformation matrix to the points.
        For x = Xmin To Xmax
            For y = Ymin To Ymax
                VectorMatrixMult Points(x, y).Trans(), Points(x, y).Coord(), T()
            Next y
        Next x
    
        ' Draw lines parallel to the X axis.
        If MapRefresh = 1 Then
        Form3D.Refresh
        ForeColor = RGB(128, 128, 128)
        For x = Xmin To Xmax
            CurrentX = Points(x, Ymin).Trans(1)
            CurrentY = Points(x, Ymin).Trans(2)
            For y = Ymin + 1 To Ymax
                Line -(Points(x, y).Trans(1), Points(x, y).Trans(2))
            Next y
        Next x
    
        ' Draw lines parallel to the Y axis.
        ForeColor = RGB(128, 128, 128)
        For y = Ymin To Ymax
            CurrentX = Points(Xmin, y).Trans(1)
            CurrentY = Points(Xmin, y).Trans(2)
            For x = Xmin + 1 To Xmax
                Line -(Points(x, y).Trans(1), Points(x, y).Trans(2))
            Next x
        Next y
          
         ' Transform and draw the axes.
        ForeColor = RGB(255, 0, 0)
        For x = 1 To 3
            VectorMatrixMult Axes(x).Trans(), Axes(x).Coord(), T()
            Line (0, 0)-(Axes(x).Trans(1), Axes(x).Trans(2))
        Next x
        End If
        
        x = MapPosX     ' Declaration for map pointers from keystrokes
        y = MapPosY
        Circle (Points(x, y).Trans(1), Points(x, y).Trans(2)), 0.3, vbGreen  ' Draw green circle in 3D map
        
        OldX = x ' Storage parameters for changing the old cell block back to blue
        OldY = y
    
    '    With Me.MSFlexGrid1
            If MapRefresh = 0 Then
            MSFlexGrid1.Row = y + 1
            MSFlexGrid1.Col = x + 1
            MSFlexGrid1.CellBackColor = RGB(20, 150, 20)
            OldGridPointerX = MSFlexGrid1.Col
            OldGridPointerY = MSFlexGrid1.Row
            End If
    '    End With
            
        x = RTMapX  'RealTime Position Indicators from COM receive event
        y = RTMapY
        
        If x <> OldTraceX Or y <> OldTraceY Then
        Circle (Points(OldTraceX, OldTraceY).Trans(1), Points(OldTraceX, OldTraceY).Trans(2)), 0.3, vbBlack
        Circle (Points(x, y).Trans(1), Points(x, y).Trans(2)), 0.3, vbRed
        Circle (OldTraceY, OldTraceX - 19), 1, vbRed
        'MSFlexGrid1.Row = OldTraceY + 1
        'MSFlexGrid1.Col = OldTraceX + 1
        'MSFlexGrid1.CellBackColor = RGB(0, 0, 80)
        'MSFlexGrid1.Row = y + 1
        'MSFlexGrid1.Col = x + 1
        'MSFlexGrid1.CellBackColor = RGB(200, 0, 0)
        OldTraceY = y
        OldTraceX = x
        End If
    MapRefresh = 0
    End Sub
    
    Private Sub Form_Paint()  ' This gets called on form3d refresh command
        'DrawSurface
    End Sub
    
    Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Const PI = 3.14159
    Const Dtheta = PI / 16
    Const Dphi = PI / 8
    
    Dim theta As Single
    Dim phi As Single
    Dim r1 As Single
    Dim r2 As Single
    Dim ZVal As Integer
    Dim Command As String
     
     
        theta = Atan(EyeX, EyeY)
        r1 = Sqr(EyeX * EyeX + EyeY * EyeY)
        r2 = Sqr(EyeX * EyeX + EyeY * EyeY + EyeZ * EyeZ)
        phi = Atan(r1, EyeZ)
    
          ' ****************************  ROTATION OF MAP *****************************
            If (KeyCode = vbKeyRight) And (Shift = vbCtrlMask) Then
                theta = theta - Dtheta
                MapRefresh = 1
            End If
            
            If (KeyCode = vbKeyDown) And (Shift = vbCtrlMask) Then
                phi = phi + Dphi
                If phi > PI / 2 Then phi = PI / 2
                MapRefresh = 1
            End If
    
            If (KeyCode = vbKeyLeft) And (Shift = vbCtrlMask) Then
                theta = theta + Dtheta
                MapRefresh = 1
            End If
    
            If (KeyCode = vbKeyUp) And (Shift = vbCtrlMask) Then
                phi = phi - Dphi
                If phi < -PI / 2 Then phi = -PI / 2
                MapRefresh = 1
            End If
            
        EyeX = r1 * Cos(theta)
        EyeY = r1 * Sin(theta)
        EyeZ = r2 * Sin(phi)
            
            '*************************** MAP POSITION MOVEMENTS *************************
            
            If KeyCode = vbKeyLeft And Not (Shift = vbCtrlMask) And Not (Shift = vbShiftMask) Then
                If MapPos >= 20 Then
                    MapPos = MapPos - 20
                    MapPosX = MapPosX - 1
                    Circle (Points(OldX, OldY).Trans(1), Points(OldX, OldY).Trans(2)), 0.3, vbBlack
                    MSFlexGrid1.Col = OldGridPointerX     'Set old cell back to blue
                    MSFlexGrid1.Row = OldGridPointerY
                    MSFlexGrid1.CellBackColor = RGB(0, 0, 80)
                    MapRefresh = 0
                End If
               
            End If
            
            If KeyCode = vbKeyRight And Not (Shift = vbCtrlMask) And Not (Shift = vbShiftMask) Then
                If MapPos <= 379 Then
                    MapPos = MapPos + 20
                    MapPosX = MapPosX + 1
                    Circle (Points(OldX, OldY).Trans(1), Points(OldX, OldY).Trans(2)), 0.3, vbBlack
                    MSFlexGrid1.Col = OldGridPointerX     'Set old cell back to blue
                    MSFlexGrid1.Row = OldGridPointerY
                    MSFlexGrid1.CellBackColor = RGB(0, 0, 80)
                    MapRefresh = 0
                End If
               
            End If
            
            If KeyCode = vbKeyDown And Not (Shift = vbCtrlMask) And Not (Shift = vbShiftMask) Then
                    If MapPosY < 19 Then
                    MapPos = MapPos + 1
                    MapPosY = MapPosY + 1
                    Circle (Points(OldX, OldY).Trans(1), Points(OldX, OldY).Trans(2)), 0.3, vbBlack
                    MSFlexGrid1.Col = OldGridPointerX     'Set old cell back to blue
                    MSFlexGrid1.Row = OldGridPointerY
                    MSFlexGrid1.CellBackColor = RGB(0, 0, 80)
                    MapRefresh = 0
            End If
             
            End If
            
            If KeyCode = vbKeyUp And Not (Shift = vbCtrlMask) And Not (Shift = vbShiftMask) Then
                    If MapPosY > 0 Then
                    MapPos = MapPos - 1
                    MapPosY = MapPosY - 1
                    Circle (Points(OldX, OldY).Trans(1), Points(OldX, OldY).Trans(2)), 0.3, vbBlack
                    MSFlexGrid1.Col = OldGridPointerX     'Set old cell back to blue
                    MSFlexGrid1.Row = OldGridPointerY
                    MSFlexGrid1.CellBackColor = RGB(0, 0, 80)
                    MapRefresh = 0
            End If
                  
        End If
            
            ' ************************** MAP VALUE CHANGES *********************************
            
            If KeyCode = 189 Then  ' Minus Key
                    ZVe(MapPos) = ZVe(MapPos) - 1
                    Command = "<234" & "," & (MapPos) & ":" & (ZVe(MapPos)) & ">"
                    MSComm1.Output = Command
                    With Me.MSFlexGrid1
                    .TextMatrix(MapPosY + 1, MapPosX + 1) = ZVe(MapPos)
                    End With
                    Points(MapPosX, MapPosY).Coord(3) = ZVe(MapPos) / 10
                    MapRefresh = 1
            End If
        
            If KeyCode = 187 Then   ' PLUS key
                    ZVe(MapPos) = ZVe(MapPos) + 1
                    Command = "<234" & "," & (MapPos) & ":" & (ZVe(MapPos)) & ">"
                    MSComm1.Output = Command
                    With Me.MSFlexGrid1
                    .TextMatrix(MapPosY + 1, MapPosX + 1) = ZVe(MapPos)
                    End With
                    Points(MapPosX, MapPosY).Coord(3) = ZVe(MapPos) / 10
                    MapRefresh = 1
            End If
            
            If (KeyCode = vbKeyLeft) And (Shift = vbShiftMask) Then  ' A Key
                Form3D.ScaleLeft = Form3D.ScaleLeft + 3
                MapRefresh = 1
            End If
            
            If (KeyCode = vbKeyRight) And (Shift = vbShiftMask) Then ' F Key
                Form3D.ScaleLeft = Form3D.ScaleLeft - 3
                MapRefresh = 1
            End If
            
            If (KeyCode = vbKeyDown) And (Shift = vbShiftMask) Then  ' D Key
                Form3D.ScaleTop = Form3D.ScaleTop + 3
                MapRefresh = 1
            End If
            
            If (KeyCode = vbKeyUp) And (Shift = vbShiftMask) Then  ' E Key
                Form3D.ScaleTop = Form3D.ScaleTop - 3
                MapRefresh = 1
            End If
                
    DrawSurface
    End Sub
    
    Private Sub mnuDownload_Click()
     MapDownload = 1
     DataStream = 0
     MSComm1.Output = "<201>"
     MSComm1.Output = "<121>"
     End Sub
    
    
    Private Sub btnRT_Click()
        DataStream = 1
        MSComm1.PortOpen = False
        MSComm1.RThreshold = 1
        MSComm1.PortOpen = True
        MSComm1.Output = "<255>"
    End Sub
    
    Private Sub btnCMDOFF_Click()
        DataStream = 0
        MSComm1.Output = "<201>"
    End Sub
    
    Private Sub MSComm1_OnComm()
    ProcessSerial
    End Sub
    
    Private Sub PutCircle()
        Picture1.BorderStyle = 0
        Picture1.AutoRedraw = True
        Picture1.DrawWidth = 5
        Picture1.Circle (Picture1.ScaleWidth / 2, Picture1.ScaleWidth / 2), Picture1.ScaleWidth / 2 - Screen.TwipsPerPixelX * 3, vbRed
        If mRgn <> 0 Then
            DeleteObject mRgn
        End If
        mRgn = RegionFromPic(Picture1)
        SetWindowRgn Picture1.hWnd, mRgn, True
    End Sub
    
    
    Private Sub Form_Unload(Cancel As Integer)
        If mRgn <> 0 Then
            DeleteObject mRgn
        End If
    End Sub
    Last edited by AshPowers; Jan 10th, 2019 at 12:39 AM.

  23. #23
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,577

    Re: How can I draw OVER MSFlexGrid display?

    Autoredraw was pertinent for the picturebox, not the form.

    I think this may be the problem Eduardo, relative to your code
    Code:
        iHeight = nPic.Parent.ScaleX(nPic.Height, nPic.ScaleMode, vbPixels)
        iWidth = nPic.Parent.ScaleY(nPic.Width, nPic.ScaleMode, vbPixels)
    Using the ScaleX/ScaleY method of a object with custom scalemode can give values that are wildly different than expected.

    I think it should be this instead:
    Code:
        iHeight = nPic.ScaleX(nPic.ScaleHeight, nPic.ScaleMode, vbPixels)
        iWidth = nPic.ScaleY(nPic.ScaleWidth, nPic.ScaleMode, vbPixels)
    P.S. Ash, you forgot your closing /CODE tag
    Last edited by LaVolpe; Jan 10th, 2019 at 12:37 AM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  24. #24
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,968

    Re: How can I draw OVER MSFlexGrid display?

    Yes, that needs to be changed.
    Still I don't know if that was the problem.

  25. #25

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    LaVolpe, Picturebox autoredraw, got it. I set it to True, still no dice.

    I also removed .Parent. in both of those lines to no avail.

  26. #26

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    Also, here are my picturebox settings:
    Attachment 164595

  27. #27
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,577

    Re: How can I draw OVER MSFlexGrid display?

    Quote Originally Posted by AshPowers View Post
    LaVolpe, Picturebox autoredraw, got it. I set it to True, still no dice.

    I also removed .Parent. in both of those lines to no avail.
    It wasn't just .Parent being removed. Please double check or copy/paste.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  28. #28

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    Quote Originally Posted by LaVolpe View Post
    It wasn't just .Parent being removed. Please double check or copy/paste.
    An BOOM! I got a circle... Almost. I overlooked the scaleheight change. Kindof strange though.. the lower ~20% of the circle is cut off.

    "EDIT" That was just how the picturebox was scaled.

  29. #29
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,577

    Re: How can I draw OVER MSFlexGrid display?

    That's progress and it's my bedtime, so I'll leave this to you and Eduardo. But before I go, a couple things just in case it applies

    1. Hopefully you didn't overlook the ScaleWidth change too

    2. Leave the picturebox scalemode to standard: twips or pixels. Your attachment didn't come through, so I don't know its settings. Ensure it's a square and not rectangle, else won't get a complete circle possibly

    3. Not a player in why you lost the bottom 20%, but you may want to make your circle thicker. If so, change the DrawWidth property of the picturebox to 2 and try that for size.

    4. And keep in mind that Eduardo's code requires the top left pixel to be the color made transparent, so never draw into that pixel. If keeping to a circle, that's not a problem since that pixel should never be drawn over.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  30. #30

    Thread Starter
    New Member
    Join Date
    Jan 2019
    Posts
    15

    Re: How can I draw OVER MSFlexGrid display?

    Quote Originally Posted by LaVolpe View Post
    That's progress and it's my bedtime, so I'll leave this to you and Eduardo. But before I go, a couple things just in case it applies

    1. Hopefully you didn't overlook the ScaleWidth change too

    2. Leave the picturebox scalemode to standard: twips or pixels. Your attachment didn't come through, so I don't know its settings

    3. Not a player in why you lost the bottom 20%, but you may want to make your circle thicker. If so, change the DrawWidth property of the picturebox to 2 and try that for size.

    4. And keep in mind that Eduardo's code requires the top left pixel to be the transparent color, so never draw into that pixel. If keeping to a circle, that's not a problem since that pixel should never be drawn over.
    Perfect. Yes, I got the ScaleWidth as well and the circle bottom taken care of. It is looking good now. Now I just need to see about moving this picturebox around over the grid based on RPM and manifold pressure. Seems straightforward. Just hope I dont get flickering. it was a PITA to get rid of all the flickering before.

    Thanks again to both of you! Very much! Goodnight and sleep well!

  31. #31
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,577

    Re: How can I draw OVER MSFlexGrid display?

    One last suggestion. Make the picturebox Enabled property False. This way users can't click on it and take focus away from the underlying grid. Good night
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  32. #32
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,968

    Re: How can I draw OVER MSFlexGrid display?

    Good night.

    Sorry that I overlooked that couple of "details" that caused problems.
    I was doing something else while I was trying to make that sample by copying code from another project.

    Thank you LaVolpe.

  33. #33
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,808

    Re: How can I draw OVER MSFlexGrid display?

    Here's an approach that uses a UserControl (called "Overlay" here) that gets positioned over the top of the flexgrid. Rather than messing around with API calls it makes use of the region manipulation built into the infrastructure of VB6 ActiveX controls.

    Note that it sticks to twips scaling, since the MSHFlexGrid does the same. That probably won't make much difference in your program no matter what scaling you are using since the twips are all basically internal.

    Name:  sshot.png
Views: 216
Size:  5.2 KB

    This "Overlay" control only has two simple methods but you could easily add more as needed.
    Attached Files Attached Files

  34. #34
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,968

    Re: How can I draw OVER MSFlexGrid display?

    After seeing dilettante's project, I came with another idea: Windowed shapes.

    But I'm having a problem when the usercontrol background is set to transparent: It shows the contained shape with strange "bugs".

    Name:  WS.png
Views: 209
Size:  9.4 KB
    Attached Files Attached Files

  35. #35
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,808

    Re: How can I draw OVER MSFlexGrid display?

    That is odd. I tried fiddling but I had no luck. Windowless controls have a lot of quirks you have to work around, I just haven't found the right combination.

  36. #36
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,968

    Re: How can I draw OVER MSFlexGrid display?

    Quote Originally Posted by dilettante View Post
    That is odd. I tried fiddling but I had no luck. Windowless controls have a lot of quirks you have to work around, I just haven't found the right combination.
    My next test would be to draw the shape instead of using a Shape control.
    I think it would have to be drawn with API in order to support all the same shappes that the standard Shape control has.
    But I do not feel like getting into that job right now.

    Edit: I remember that the API PolyLine makes the lines with rounded corners when the DrawWidth > 1, unlike the Shape control that produce angled edges.

  37. #37
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,968

    Re: How can I draw OVER MSFlexGrid display?

    Here there is a version that seems to fix the bug, using MaskPicture.
    Perhaps I'll post it into the CodeBank.
    Attached Files Attached Files

  38. #38
    Hyperactive Member
    Join Date
    Aug 2016
    Posts
    377

    Re: How can I draw OVER MSFlexGrid display?

    used PNG control can easy do this.and can set Pretty mark

  39. #39
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    5,948

    Re: How can I draw OVER MSFlexGrid display?

    Just for fun, I worked out how I'd do this. I just used clipping regions on a custom user control. I didn't use any additional controls on it, so it's not terribly "heavy". Although it still has a hWnd, so it's in the same ZOrder plane as other windowed controls.

    Here's a video:



    And I've attached a little demo project.

    At present, it just does a rectangle and an ellipse (oval). Those can easily be used to make squares or circles. To do the rounded rectangle would take a bit more work, but it wouldn't be huge. I'll see if someone needs that before doing that work. To do it, I'd tend to just shove a circle into each of the corners, and then use the features of CombineRgn to get it done. (It's not quite that simple, but that's how I'd start to get it going.)

    Enjoy,
    Elroy

    EDIT1: I decided to show the code for the custom UC. Basically, all I did was start a new-empty UC, change the background to red (just for grins), and set AutoRedraw=True. I also turned off HasDC as I didn't think that would be needed, and that'll save a Windows resource.

    Code:
    
    Option Explicit
    '
    Public Enum ShapeExEnum
        ShapeExRectangle = 0&
        ShapeExOval = 2&
    End Enum
    '
    Private Type RECT
        Left   As Long
        Top    As Long
        Right  As Long ' This is +1 (right - left = width)
        Bottom As Long ' This is +1 (bottom - top = height)
    End Type
    '
    Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
    Private Declare Function CreateRectRgn Lib "Gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal y2 As Long) As Long
    Private Declare Function CreateEllipticRgn Lib "Gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal y2 As Long) As Long
    Private Declare Function CombineRgn Lib "Gdi32" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
    Private Declare Function DeleteObject Lib "Gdi32" (ByVal hObject As Long) As Long
    Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
    '
    Private Const RGN_AND   As Long = &H1&
    Private Const RGN_OR    As Long = &H2&
    Private Const RGN_XOR   As Long = &H3&
    Private Const RGN_DIFF  As Long = &H4&
    Private Const RGN_COPY  As Long = &H5&
    '
    Dim mlPelThick  As Long
    Dim mlShape     As ShapeExEnum
    '
    Event Click()
    Event DblClick()
    Event KeyDown(KeyCode As Integer, Shift As Integer)
    Event KeyUp(KeyCode As Integer, Shift As Integer)
    Event KeyPress(KeyAscii As Integer)
    Event MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    Event MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    Event MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    Event Paint()
    Event Resize()
    '
    
    
    Private Sub UserControl_Click():        RaiseEvent Click:       End Sub
    Private Sub UserControl_DblClick():     RaiseEvent DblClick:    End Sub
    Private Sub UserControl_KeyDown(KeyCode As Integer, Shift As Integer):      RaiseEvent KeyDown(KeyCode, Shift):     End Sub
    Private Sub UserControl_KeyUp(KeyCode As Integer, Shift As Integer):        RaiseEvent KeyUp(KeyCode, Shift):       End Sub
    Private Sub UserControl_KeyPress(KeyAscii As Integer):                      RaiseEvent KeyPress(KeyAscii):          End Sub
    Private Sub UserControl_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single):   RaiseEvent MouseDown(Button, Shift, x, y):  End Sub
    Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single):   RaiseEvent MouseMove(Button, Shift, x, y):  End Sub
    Private Sub UserControl_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single):     RaiseEvent MouseUp(Button, Shift, x, y):    End Sub
    Private Sub UserControl_Paint():        RaiseEvent Paint:       End Sub
    
    Private Sub UserControl_Resize()
        MakeShape                               ' Always redo our region when the size changes.
        RaiseEvent Resize
    End Sub
    
    Private Sub UserControl_InitProperties()
        mlPelThick = 2&
        mlShape = ShapeExRectangle
    End Sub
    
    Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
        mlPelThick = PropBag.ReadProperty("BorderWidth", 2&)
        UserControl.BackColor = PropBag.ReadProperty("BorderColor", UserControl.BackColor)
        mlShape = PropBag.ReadProperty("Shape", ShapeExRectangle)
    End Sub
    
    Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
        PropBag.WriteProperty "BorderWidth", mlPelThick
        PropBag.WriteProperty "BorderColor", UserControl.BackColor
        PropBag.WriteProperty "Shape", mlShape
    End Sub
    
    
    
    
    Public Property Let BorderWidth(lPelThick As Long)
        mlPelThick = lPelThick
        MakeShape                               ' Always redo our region when the border thickness changes.
        PropertyChanged "BorderWidth"
    End Property
    
    Public Property Get BorderWidth() As Long
        BorderWidth = mlPelThick
    End Property
    
    Public Property Let BorderColor(lBorderColor As OLE_COLOR)
        UserControl.BackColor = lBorderColor
        PropertyChanged "BorderColor"
    End Property
    
    Public Property Get BorderColor() As OLE_COLOR
        BorderColor = UserControl.BackColor
    End Property
    
    Public Property Let Shape(lShape As ShapeExEnum)
        mlShape = lShape
        MakeShape                               ' Always redo our region when the region's shape changes.
        PropertyChanged "Shape"
    End Property
    
    Public Property Get Shape() As ShapeExEnum
        Shape = mlShape
    End Property
    
    
    
    Private Sub MakeShape()
        Select Case mlShape
        Case ShapeExRectangle:  MakeRectangle
        Case ShapeExOval:       MakeEllipse
        End Select
    End Sub
    
    Private Sub MakeRectangle()
        Dim r       As RECT
        Dim Rgn1    As Long
        Dim Rgn2    As Long
        Dim RgnAll  As Long
        '
        GetWindowRect UserControl.hWnd, r                                                       ' Get our rectangle.
        RgnAll = CreateRectRgn(0&, 0&, 0&, 0&)                                                  ' A region for combining.
        Rgn1 = CreateRectRgn(0&, 0&, r.Right - r.Left, r.Bottom - r.Top)                        ' Outer border.
        Rgn2 = CreateRectRgn(mlPelThick, mlPelThick, _
                             r.Right - r.Left - mlPelThick, _
                             r.Bottom - r.Top - mlPelThick)                                     ' Inner border.
        CombineRgn RgnAll, Rgn1, Rgn2, RGN_XOR                                                  ' Mask out the inner border.
        SetWindowRgn UserControl.hWnd, RgnAll, True                                             ' Set our new region.
        DeleteObject Rgn1                                                                       ' Clean-up.
        DeleteObject Rgn2                                                                       ' Clean-up.
        'DeleteObject RgnAll ' Windows deletes this one because it was used in SetWindowRgn.
    End Sub
    
    Private Sub MakeEllipse()
        Dim r       As RECT
        Dim Rgn1    As Long
        Dim Rgn2    As Long
        Dim RgnAll  As Long
        '
        GetWindowRect UserControl.hWnd, r                                                       ' Get our rectangle.
        RgnAll = CreateRectRgn(0&, 0&, 0&, 0&)                                                  ' A region for combining.
        Rgn1 = CreateEllipticRgn(0&, 0&, r.Right - r.Left, r.Bottom - r.Top)                    ' Outer border.
        Rgn2 = CreateEllipticRgn(mlPelThick, mlPelThick, _
                             r.Right - r.Left - mlPelThick, _
                             r.Bottom - r.Top - mlPelThick)                                     ' Inner border.
        CombineRgn RgnAll, Rgn1, Rgn2, RGN_XOR                                                  ' Mask out the inner border.
        SetWindowRgn UserControl.hWnd, RgnAll, True                                             ' Set our new region.
        DeleteObject Rgn1                                                                       ' Clean-up.
        DeleteObject Rgn2                                                                       ' Clean-up.
        'DeleteObject RgnAll ' Windows deletes this one because it was used in SetWindowRgn.
    End Sub
    
    
    Attached Files Attached Files
    Last edited by Elroy; Jan 14th, 2019 at 01:28 PM.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  40. #40
    Hyperactive Member
    Join Date
    Aug 2016
    Posts
    377

    Re: How can I draw OVER MSFlexGrid display?

    Quote Originally Posted by dilettante View Post
    Here's an approach that uses a UserControl (called "Overlay" here) that gets positioned over the top of the flexgrid. Rather than messing around with API calls it makes use of the region manipulation built into the infrastructure of VB6 ActiveX controls.

    Note that it sticks to twips scaling, since the MSHFlexGrid does the same. That probably won't make much difference in your program no matter what scaling you are using since the twips are all basically internal.

    Name:  sshot.png
Views: 216
Size:  5.2 KB

    This "Overlay" control only has two simple methods but you could easily add more as needed.
    Code:
    Option Explicit
    Dim I As Integer
    
    Private Sub Form_Load()
    
        Timer1.Interval = 1000
        ' Timer1.Enabled = True
    
        Overlay1.ZOrder vbBringToFront
    End Sub
    
    Private Sub Form_Resize()
    
        If WindowState <> vbMinimized Then
    
            With Picture1
                .Move 600, 600, ScaleWidth - 1200, ScaleHeight - 1200
                Overlay1.Move .Left, .Top, .Width, .Height
            End With
    
        End If
    
    End Sub
    
    Private Sub mnuClear_Click()
        mnuClear.Enabled = False
        Overlay1.Clear
    End Sub
    
    Private Sub Picture1_MouseDown(Button As Integer, _
                                   Shift As Integer, _
                                   x As Single, _
                                   y As Single)
        I = x
        Timer1.Enabled = True
    End Sub
    
    Private Sub Timer1_Timer()
        Overlay1.CircleAt I + 100, I + 100
        I = I + 20
        Debug.Print I
    
    End Sub

    I used a time control to test the effect of automatic clicks. I found that the timer control stopped automatically. Why?

    ok must change

    Code:
    Option Explicit
    
    Private Const RADIUS As Single = 420
    
    Private mX As Single
    Private my As Single
    
    Public Sub CircleAt(ByVal x As Single, ByVal y As Single)
        'Erase:
        mX = 0
        my = 0
        refresh
        DoEvents
        'Draw:
        mX = x
        my = y
        refresh
    End Sub
    
    Public Sub Clear()
        mX = 0
        my = 0
        refresh
    End Sub
    
    Private Sub Picture1_Click()
    
    End Sub
    
    Private Sub UserControl_Initialize()
        MaskColor = &HFF00FF    'Some unique color we don't otherwise use.
        BackColor = MaskColor
    End Sub
    
    Sub refresh()
     If Not Ambient.UserMode Then
          'Make it visible in design mode:
    '      ForeColor = FillColor
    '      FillStyle = vbCross
    '      BackStyle = 1 'Opaque, we want to see it.  We don't have an enumeration for these values.
    '      Line (0, 0)-(ScaleWidth - ScaleX(1, vbPixels, ScaleMode), ScaleHeight - ScaleY(1, vbPixels, ScaleMode)), , B
           
           BackStyle = 1
           Picture1.Visible = True
           Picture1.Move 0, 0
           UserControl.Width = Picture1.Width
           UserControl.Height = Picture1.Height
       Else
    
          If mX > 0 Or my > 0 Then
             AutoRedraw = True
             Cls
             Circle (mX, my), RADIUS
             UserControl.PaintPicture Picture1.Picture, mX - (Picture1.Width) / 2, my - (Picture1.Height) / 2
                
             AutoRedraw = False
             'SavePicture UserControl.Picture, "c:\1.bmp"
             'SavePicture UserControl.Image, "c:\2.bmp"
             Set MaskPicture = Image 'Render with mask transparency.
          Else
             Set MaskPicture = Nothing
    
          End If
    
       End If
    End Sub
    now timer can run ok
    Attached Files Attached Files
    Last edited by xxdoc123; Jan 15th, 2019 at 08:13 PM.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width