none
Colour detection in game RRS feed

  • Question

  • I am creating a top down maze game for a project in Visual studio, using forms etc.

    To create collision detection in this game, I need to get the colour name of the screen next to where the character is. If this pixel is black then the player moves back to where they were before moving. I got the code to work when using cursor position, but changing it to the character position messes it up (to test colour detection, I use PictureBox1).

    Another thing I have tested, is moving the PosX and PosY by a pixel incase it was the player's border causing the issue, however, this did not fix the problem.


    My form's code:


    Public Class Game

        'Position of player
        Dim PosX As Integer
        Dim PosY As Integer
        'Colour of pixel
        Dim RGBVal As String

        'Player movement
        Private Sub Form_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown

            PosX = 495
            PosY = 401

            Select Case e.KeyCode
                Case Keys.Left
                    Player.Left -= 12
                    PosX = PosX - 12
                Case Keys.Right
                    Player.Left += 12
                    PosX = PosX + 12
                Case Keys.Down
                    Map.Top -= 12
                Case Keys.Up
                    Map.Top += 12

            End Select

        End Sub

        'Colour detection
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Dim a As New Drawing.Bitmap(1, 1)
            Dim b As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(a)
            b.CopyFromScreen(New Drawing.Point(PosX, PosY), New Drawing.Point(0, 0), a.Size)
            Dim c As Drawing.Color = a.GetPixel(0, 0)
            PictureBox1.BackColor = c
            RGBVal = PictureBox1.BackColor.Name
        End Sub

    End Class

    Sunday, March 18, 2018 3:04 PM

Answers

  • Again, I need to stitcha bunch of them atop one another.

    Either way, I have now figured the colour detection out (sort of). I changed the resolution to that of my monitor to bypass convertions (wont work on anything other than 1080p now though. I didn't want to do it this way but I an really running out of time, so had to.

    Thanks to everyone for trying to help with this issue though.


    • Edited by TheChapster Saturday, March 31, 2018 1:42 PM
    • Marked as answer by TheChapster Saturday, March 31, 2018 1:42 PM
    Saturday, March 31, 2018 1:42 PM

All replies

  • I believe the problem is you get the color from the screen which is using screen coordinates where 0,0 origin is upper left of the whole screen. But your player picturebox coordinates are relative to the form where 0,0 is upper left of the form. And then 0,0 on the picturebox is relative to the picturebox upper left. So you have 3 differenct coordinate systems.

    Instead of capturing the screen image you should capture the form image and test against that. And when you get the player coords you use the postion of the picturebox on the form. So you have one image (the form) and one coordinate system (the form). ie picturebox.location is in form coordinates.

    Tell us how the image gets on the form. ie how does the black color get on the form?
    Sunday, March 18, 2018 3:37 PM
  • Since your question is about windows forms you should ask this at the windows Forms forum below instead of here on the VB.Net (VB General) forum.

    Windows Forms Forum


    Success
    Cor

    Sunday, March 18, 2018 4:28 PM
  • This question is fine in this forum as it relates to GDI imaging more than the controls using GDI.

    I can't go on without saying, as I always do in these situations, that using picutreboxes and reading pixel information is not the best way to make a game.  That said, if you do need a pixel map for game data you should read it all at once and build an efficient lookup model for the actual game execution to use.

    In this case I presume you have a black and white image of a maze and want the picturebox to move only in the white areas of the image.  This image won't change during execution of the program (at least for this "level" in the game) so the information about where the player can move could all be gathered at once when the level is loaded.  Then you would have an efficient way of looking up the player movement information while the game is being played.

    The easiest thing to do is to generate the maze image on a grid, where each cell in the grid is the size of the width of the wall in the maze.  This way all of the walls and movement spaces align to cells in a grid and you can quickly enumerate the image to generate a table of cell data that specifies wall or floor.

    If you can tell us more about the maze image you are using, or post an example in the thread, I'm sure we can help further.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Sunday, March 18, 2018 5:50 PM
    Moderator
  • Thanks for your reply.

    I am using a separate picture box for the mazes (will be randomly selected from multiple and added one above another to make a continuous maze out of smaller ones).

    I will try to use the form coordinates in the colour detection area of code. Hope it will fix the issue :D

    Wednesday, March 21, 2018 9:44 AM
  • Thanks for your suggestion. I will struggle to do this as I am using "procedural generation" for the order of the sections I have made.

    I was going to post a picture of it, however... I am not verified, so the forum wouldn't let me post it. I will try later when I have access to my code.


    If you are creating the maze in code then you don't need the picture at all.  When generating the maze, also generate a list of rectangles that represent each wall.  Then you code can simply loop through this list of rectangles to see if the player's bounds intersect any of the wall bounds.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, March 21, 2018 12:35 PM
    Moderator
  • If you are creating the maze in code then you don't need the picture at all.  When generating the maze, also generate a list of rectangles that represent each wall.  Then you code can simply loop through this list of rectangles to see if the player's bounds intersect any of the wall bounds.

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    It is not generated by the code, just ordered. It uses a set of picture boxes with segments of the maze and queues them, one on top of the other, linking them together.

    • Edited by TheChapster Saturday, March 24, 2018 2:48 PM
    Saturday, March 24, 2018 2:47 PM
  • I believe the problem is you get the color from the screen which is using screen coordinates where 0,0 origin is upper left of the whole screen. But your player picturebox coordinates are relative to the form where 0,0 is upper left of the form. And then 0,0 on the picturebox is relative to the picturebox upper left. So you have 3 differenct coordinate systems.

    Instead of capturing the screen image you should capture the form image and test against that. And when you get the player coords you use the postion of the picturebox on the form. So you have one image (the form) and one coordinate system (the form). ie picturebox.location is in form coordinates.

    Tell us how the image gets on the form. ie how does the black color get on the form?
    This is definitely the issue. I checked it by moving the character down to the right and it detected different colours. How would I change my colour detection code to the form coordinates from screen ones?

    Here is that section of code again:

      Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Dim a As New Drawing.Bitmap(1, 1)
            Dim b As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(a)
            b.CopyFromScreen(New Drawing.Point(PosX, PosY), New Drawing.Point(0, 0), a.Size)
            Dim c As Drawing.Color = a.GetPixel(0, 0)
            PictureBox1.BackColor = c
            RGBVal = PictureBox1.BackColor.Name
        End Sub
    Saturday, March 24, 2018 2:53 PM
  • I believe the problem is you get the color from the screen which is using screen coordinates where 0,0 origin is upper left of the whole screen. But your player picturebox coordinates are relative to the form where 0,0 is upper left of the form. And then 0,0 on the picturebox is relative to the picturebox upper left. So you have 3 differenct coordinate systems.

    Instead of capturing the screen image you should capture the form image and test against that. And when you get the player coords you use the postion of the picturebox on the form. So you have one image (the form) and one coordinate system (the form). ie picturebox.location is in form coordinates.

    Tell us how the image gets on the form. ie how does the black color get on the form?

    This is definitely the issue. I checked it by moving the character down to the right and it detected different colours. How would I change my colour detection code to the form coordinates from screen ones?

    Here is that section of code again:

      Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Dim a As New Drawing.Bitmap(1, 1)
            Dim b As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(a)
            b.CopyFromScreen(New Drawing.Point(PosX, PosY), New Drawing.Point(0, 0), a.Size)
            Dim c As Drawing.Color = a.GetPixel(0, 0)
            PictureBox1.BackColor = c
            RGBVal = PictureBox1.BackColor.Name
        End Sub

    Chap,

    Yes well, you dont HAVE to do it that way. You can work in screen coords and convert back and forth.

        https://msdn.microsoft.com/en-us/library/system.windows.forms.control.pointtoscreen%28v=vs.110%29.aspx

    Or you can capture the form image as I mention


        https://msdn.microsoft.com/en-us/library/system.windows.forms.control.drawtobitmap(v=vs.110).aspx


    Problem here is the coords include the caption and the border width so you need to get just the form drawing surface.


    So maybe the simplest is to use a picturebox and dock to the form. Put the player pictureboxes on the form picturebox. Then there is truly just one parent coord system.

    However, I agree with Reed it would be best in the long run to learn how to generate the maze walls using a logical method thaqt you can also use for the collision detection.

    So it just depends on what direction you want to go now.

    First study the point to screen and etc functions to just use what you already have and convert from screen to form coords.

          https://msdn.microsoft.com/en-us/library/system.windows.forms.control.pointtoclient(v=vs.110).aspx

    Then you will see how you could use the control to bitmap to capture the form only... and etc.

    I know it sounds wishy washy but the methods are all related and can be combined as required. Good to learn it all now.

    Look over the links and come back.

    Saturday, March 24, 2018 3:17 PM
  • Thanks for your reply tommytwotrain.

    I will stick the the coord system for now as I have to have the entire project including writeup complete for this friday and I am new to coding so I really don't know what I am doing.

    I tried to implement the PointToScreen function, however, it won't work, probably since I didn't know how to use it at all. I also added a coord viewer for testing to make sure this was the problem, which it was. It was changing the coords to 0,0 after running it through the function. I will post my new code below.

    Public Class Game
    
        'Position of player
        Dim Pointer As Point
        'Colour of pixel
        Dim RGBVal As String
    
        'Converting form to screen coords
        Public Function PointToScreen(
            p As Point
        ) As Point
        End Function
    
        'Starting player coords
        Public Sub Form_Load() Handles Me.Load
            Pointer.X = 495
            Pointer.Y = 401
            Pointer = PointToScreen(Pointer)
        End Sub
    
        'Player movement
        Public Sub Form_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    
            Select Case e.KeyCode
                Case Keys.Left
                    Player.Left -= 12
                    Pointer.X = Pointer.X - 12
                Case Keys.Right
                    Player.Left += 12
                    Pointer.X = Pointer.X + 12
                Case Keys.Down
                    Map.Top -= 12
                Case Keys.Up
                    Map.Top += 12
    
            End Select
    
            TextBox1.Text = Pointer.ToString
    
        End Sub
    
        'Colour detection
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Dim a As New Drawing.Bitmap(1, 1)
            Dim b As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(a)
            b.CopyFromScreen(New Drawing.Point(Pointer), New Drawing.Point(0, 0), a.Size)
            Dim c As Drawing.Color = a.GetPixel(0, 0)
            PictureBox1.BackColor = c
            RGBVal = PictureBox1.BackColor.Name
        End Sub
    
    End Class





    Sunday, March 25, 2018 3:06 PM
  • Thanks for your reply tommytwotrain.

    I will stick the the coord system for now as I have to have the entire project including writeup complete for this friday and I am new to coding so I really don't know what I am doing.

    I tried to implement the PointToScreen function, however, it won't work, probably since I didn't know how to use it at all. I also added a coord viewer for testing to make sure this was the problem, which it was. It was changing the coords to 0,0 after running it through the function. I will post my new code below.

    Chap,

    You don't make the pointtoscreen function it is built into the .net platform and the vb.net language. You call the function with a known point and it returns the other point that you want.

    Yeah, why do you have a timer? What does it do?

    Have you been going to class? This stuff tends to creep up on you if you don't learn each step along the way. Then your bridge is full of holes and hard to walk on.

    Why don't we start over and you describe in a series of numbered steps exactly what you want to do.

    For example, player presses key, key event moves picturebox to new location, test if new location is valid, etc... don't worry yet exactly how to test new location yet. So you have a plan from start to finish.

    You seem to be hinting you want a game of some kind but are not specific as to what the game should do. So you need to plan out exactly what the game should do. Leave out anything to do with code to start with. Just describe what the game should do best you can with what you have. Then the next step is to find code that does what you describe. You will have to change and adapt as you go and learn.

    Sunday, March 25, 2018 3:49 PM
  • PS Here is an example of the client coordinate system point to screen coordinates function and the various coordinate systems. Just add a picture box to a form and paste this example code. As you move the form on the screen, note the screen coordinates are updated on the form display.

    See how the pointtoscreen function is used to convert from the form client area (0,0) to the screen coordinate system?

    Public Class Form6
        Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.DoubleBuffered = True
            Me.BackColor = Color.White
            Me.ClientSize = New Size(300, 300)
    
            'move the picture box to 100,100 in form client coordinates
            PictureBox1.Location = New Point(100, 100)
    
            'make the pic size
    
            PictureBox1.Size = New Size(180, 50)
            PictureBox1.BackColor = Color.Red
    
    
        End Sub
    
        Private Sub Form6_LocationChanged(sender As Object, e As EventArgs) Handles Me.LocationChanged
            'update the form client area with the paint event
            Me.Invalidate()
    
    
        End Sub
    
        Private Sub Form6_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    
            'draw coordinate 0,0 in form client coordinate system 
            e.Graphics.DrawLine(Pens.Blue, 0, 0, 20, 20)
            e.Graphics.DrawString("(0,0) form client area", Me.Font, Brushes.Blue, 20, 20)
    
            'get the screen coordinate of the form origin
            Dim formOriginPt As New Point(0, 0)
            Dim ScreenPt As Point
            ScreenPt = Me.PointToScreen(formOriginPt)
            e.Graphics.DrawString("Screen: " & ScreenPt.ToString, Me.Font, Brushes.Blue, 20, 40)
    
    
            'draw the coordinates of the picturebox in form client area coordinate system.
            e.Graphics.DrawLine(Pens.ForestGreen, PictureBox1.Location.X, PictureBox1.Location.Y, 120, 80)
            e.Graphics.DrawString("Form Client Coords: " & PictureBox1.Location.ToString, Me.Font, Brushes.ForestGreen, 120, 70)
    
    
    
        End Sub
    
        Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
    
            'draw coordinate 0,0 in picturebox client coordinate system 
            e.Graphics.DrawLine(Pens.AntiqueWhite, 0, 0, 20, 20)
            e.Graphics.DrawString("(0,0) Picturebox Client Area", Me.Font, Brushes.AntiqueWhite, 20, 20)
        End Sub
    End Class

    So what you want to do is get an image of the form client area where the origin (0,0) is the same coordinate system as the picturebox that is moving.


    Sunday, March 25, 2018 4:25 PM
  • I'm not sure why you have the timer, but here is a simple example program that uses two picture boxes and tests for collision by examining the color values of the pixels.  Comments explain what the code does and indicate place for improvement and expansion.

    Public Class Form1
        Private mazeImageUrl As String = "https://upload.wikimedia.org/wikipedia/commons/thumb/2/28/Prim_Maze.svg/1024px-Prim_Maze.svg.png"
    
        Friend WithEvents MazePictureBox As New PictureBox
        Friend WithEvents PlayerPictureBox As New PictureBox With {.BackColor = Color.Transparent}
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'load maze image into picture box
            MazePictureBox.Load(mazeImageUrl)
            'size according to image size
            MazePictureBox.Size = MazePictureBox.Image.Size
            'load player image into picture box
            PlayerPictureBox.Image = SystemIcons.WinLogo.ToBitmap
            'size according to image size
            PlayerPictureBox.Size = PlayerPictureBox.Image.Size
            'set form size to maze size
            ClientSize = MazePictureBox.Size
            'add maze picturebox to form
            Controls.Add(MazePictureBox)
            'add player picturebox to maze
            MazePictureBox.Controls.Add(PlayerPictureBox)
        End Sub
    
        Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
            'determine the desired direction of movement
            Dim deltaX, deltaY As Integer
            Select Case e.KeyCode
                Case Keys.Up, Keys.W
                    deltaY = -1
                Case Keys.Down, Keys.S
                    deltaY = 1
                Case Keys.Left, Keys.A
                    deltaX = -1
                Case Keys.Right, Keys.D
                    deltaX = 1
            End Select
            'test if moving in the direction would collide with a wall
            If Not WouldPlayerCollideWithWall(deltaX, deltaY) Then
                'if not, move in that direction
                PlayerPictureBox.Location = New Point(PlayerPictureBox.Left + deltaX, PlayerPictureBox.Top + deltaY)
            End If
        End Sub
        'TODO: Refactor to track key state with KeyDown/KeyUp events and process input during game loop
        '      implemented with timer or other synchronized looping mechanism
    
        Private Function WouldPlayerCollideWithWall(xOffset As Integer, yOffset As Integer) As Boolean
            'get the current player bounds
            Dim bounds = PlayerPictureBox.Bounds
            'modify the location of the bounds by the proposed amount
            bounds.Offset(xOffset, yOffset)
            'if the bounds would move outside the maze image, return true
            If Not MazePictureBox.Bounds.Contains(bounds) Then Return True
            'check each pixel of the bounds against the maze image
            For y = bounds.Top To bounds.Bottom - 1
                For x = bounds.Left To bounds.Right - 1
                    'if this pixel is transparent in the player image, ignore it
                    If CType(PlayerPictureBox.Image, Bitmap).GetPixel(x - bounds.Left, y - bounds.Top).A = 0 Then Continue For
                    'the "floor" of the maze is transparent so just check for nontransparent pixels
                    If Not CType(MazePictureBox.Image, Bitmap).GetPixel(x, y).A = 0 Then Return True
                Next
            Next
            Return False
        End Function
        'TODO: Optimize function by storing pixel collision data in varaibles loaded once when the program starts,
        '      factoring out calls To GetPixel()
    End Class


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


    Sunday, March 25, 2018 4:40 PM
    Moderator
  • tommytwotrain,

    I haven't learnt coding in class. This is for computing in school so have learnt only the theory, and therefore have to teach myself code (without having any time to learn).

    The timer is for the colour detection. Every time the timer ticks, the colour information is detected. This is set to 10ms, meaning every 10ms, the colour information is set into the variable.

    The problem I need to solve is getting the pixel information from next to the character at all times, tracking it to make sure it is not touching a wall.
    This character moves left and right across the screen, with the map moving up and down so that multiple map segments (.jpg) can be linked together without the character teleporting at checkpoints. After I have got the colour detection working, I should know how to do the rest, but I cannot get it to that until collision detection for the walls is corrected, since this is the most important part of a maze runner game.
    Each map segment is 31x31 squares (each wall/path completely fills a square) and the character moves exactly 1 square (12px) per key press.

    Thanks for your help.

    Tuesday, March 27, 2018 9:28 AM
  • ...

    Each map segment is 31x31 squares (each wall/path completely fills a square) and the character moves exactly 1 square (12px) per key press.

    Thanks for your help.

    Then this makes it easy to generate a 2-dimensional array of Booleans that say whether or not a tile is passable.  Keep track of everything by tile index instead of by pixel.  You can easily convert tile index to pixel index by multiplying by 12.

    You can use code something like:

    Dim wallData(30, 30) As Boolean
    For y = 0 To 30
        For x = 0 To 30
            If CType(PlayerPictureBox.Image, Bitmap).GetPixel(x * 12 - 6, y * 12 - 6) = Color.Black Then
                wallData(x, y) = False
            Else
                wallData(x, y) = True
            End If
        Next
    Next
    

    ...to load the passage data and then you can simply test if wallData(newLocation.x, newLocation.y) = True to determine if the character should move.

    The character position in tiles becomes a point with values 0 to 30 for x and y, and the character picturebox position in pixels is the character tile position times 12.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Tuesday, March 27, 2018 11:58 AM
    Moderator
  • Then this makes it easy to generate a 2-dimensional array of Booleans that say whether or not a tile is passable.  Keep track of everything by tile index instead of by pixel.  You can easily convert tile index to pixel index by multiplying by 12.

    You can use code something like:

    Dim wallData(30, 30) As Boolean
    For y = 0 To 30
        For x = 0 To 30
            If CType(PlayerPictureBox.Image, Bitmap).GetPixel(x * 12 - 6, y * 12 - 6) = Color.Black Then
                wallData(x, y) = False
            Else
                wallData(x, y) = True
            End If
        Next
    Next

    ...to load the passage data and then you can simply test if wallData(newLocation.x, newLocation.y) = True to determine if the character should move.

    The character position in tiles becomes a point with values 0 to 30 for x and y, and the character picturebox position in pixels is the character tile position times 12.

    I have considered this previously, however, the problem is the fact that it is "procedurally generated" in a way that I never know which segment will be first and all map segments are "stitched" together into one continuous map. Which then moves down to give the impression that the character is moving up, without running out of screen space.

    Wednesday, March 28, 2018 8:31 AM
  • I have considered this previously, however, the problem is the fact that it is "procedurally generated" in a way that I never know which segment will be first and all map segments are "stitched" together into one continuous map. Which then moves down to give the impression that the character is moving up, without running out of screen space.

    That's OK.  All you need to do is create a class to hold the image and the wall data.  Then instead of randomly picking an image, you pick a instance of this class.  Now the code has the image and its wall data to work with.

    Public Class MapData
        Public Property MapImage As Bitmap
        Public Property WallData As Boolean(,)
    End Class
    So on Form.Load create a MapData instance for each maze image.  Store the picture and build the list of wall data.  Then when the game starts, randomly choose a MapData in the same way that you are currently randomly choosing a bitmap image.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Wednesday, March 28, 2018 3:41 PM
    Moderator
  • Again, I need to stitcha bunch of them atop one another.

    Either way, I have now figured the colour detection out (sort of). I changed the resolution to that of my monitor to bypass convertions (wont work on anything other than 1080p now though. I didn't want to do it this way but I an really running out of time, so had to.

    Thanks to everyone for trying to help with this issue though.


    • Edited by TheChapster Saturday, March 31, 2018 1:42 PM
    • Marked as answer by TheChapster Saturday, March 31, 2018 1:42 PM
    Saturday, March 31, 2018 1:42 PM
  • Again, I need to stitcha bunch of them atop one another.

    Either way, I have now figured the colour detection out (sort of). I changed the resolution to that of my monitor to bypass convertions (wont work on anything other than 1080p now though. I didn't want to do it this way but I an really running out of time, so had to.

    Thanks to everyone for trying to help with this issue though.


    Again, that doesn't matter; it wouldn't affect your stitching at all.

    In any event, if the only remaining issue is converting a screen coordinate to a local coordinate, have you look at the PointToClient() method that is on every control?


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Saturday, March 31, 2018 2:06 PM
    Moderator
  • Again, I need to stitcha bunch of them atop one another.

    Either way, I have now figured the colour detection out (sort of). I changed the resolution to that of my monitor to bypass convertions (wont work on anything other than 1080p now though. I didn't want to do it this way but I an really running out of time, so had to.

    Thanks to everyone for trying to help with this issue though.


    Chap,

    I still think you just dont quite understand all the details. Its tricky. Its easy to be doing something backwards for the wrong reasons. I am not trying to put you down. Just saying that is why it does not work.

    What you describe with monitor resolution is probababy the screen text and other items scaling which is a  simulated thing windows does based on your windows control panel display settings for 100-125 or 150 percent. Today's hi-res displays may use this. Its sometimes called the dpi or dpi aware but technically it is not only the actual monitor dpi (which you can objtain using graphics.dpix) there is a windows scaling as well.

    So you need to take this setting into account when you are using bitmaps in various controls. If the setting is 125 and above you have to use it for scaling bitmaps in certain controls . win7:  Control Panel\Appearance and Personalization\Display

    We cant help you nail it down exactly because we don't know exactly what you are doing.

    :)

       

    https://msdn.microsoft.com/library/windows/desktop/mt843498%28v=vs.85%29.aspx%28d=robot%29?f=255&MSPPError=-2147217396

    Saturday, March 31, 2018 3:12 PM