B4J Question To dip or not to dip - 4k display question

Discussion in 'B4J Questions' started by jroriz, Aug 5, 2019.

  1. jroriz

    jroriz Active Member Licensed User

    I have a project that works by reading and showing graphics on the screen from ordinary windows.

    Everything was fine until I bought a 4K monitor. Everything is out of position, and I can't solve this problem.

    I attached a project trying to replicate my scenario.

    Download the project here: https://1drv.ms/f/s!ArdqlgJhFnmYkiHuImTcA5_GVX89

    Result in my good old 21 inch display:
    result1.PNG

    4K display result:

    result4k.PNG

    Entire project:
    Code:
    #Region Project Attributes
        
    #MainFormWidth: 600
        
    #MainFormHeight: 600

        
    #AdditionalJar: jna-5.2.0
        
    #AdditionalJar: jna-platform-5.2.0
    #End Region

    Sub Process_Globals
        
    Private fx As JFX
        
    Private MainForm As Form
        
        
    Dim OriginX, OriginY As Int
        
    Dim SecondForm As Form
        
    Dim img As ImageView
    End Sub

    Sub AppStart (Form1 As Form, Args() As String)
        MainForm = Form1

        
    ' I read graphical elements from ordinary Windows forms wich i get by window name
        ' Mainform will play this part. See Scanwindow sub
        MainForm.RootPane.LoadLayout("main")
        MainForm.Title = 
    "Window that I need to scan some graphical elements"
        MainForm.Show
        
        MainForm.AlwaysOnTop = 
    True
        
        ScanWindow    
    ' as if mainform does not belong to the project
        
        img.Initialize(
    "")
        
        SecondForm.Initialize(
    ""300,300)
        SecondForm.RootPane.AddNode(img,
    0,0,SecondForm.Width, SecondForm.Height)
        
        SecondForm.WindowLeft = OriginX + 
    300
        SecondForm.WindowTop = OriginY + 
    300
        SecondForm.Title = 
    "Second"
        
        SecondForm.BackColor = fx.Colors.Blue
        
        SecondForm.AlwaysOnTop = 
    True

    End Sub

    Sub Capture(x As Int, y As Int, width As Int, height As Int) As B4XBitmap

        
    Dim c3po As AWTRobot

        c3po.ScreenCurrentRectangleSetAsArbitrary(x, y, width, height)
        
    Return BytesToImage(c3po.ScreenCaptureAsByteArray)

    End Sub

    Public Sub BytesToImage(bytes() As Byte) As B4XBitmap
        
    Dim In As InputStream
        
    In.InitializeFromBytesArray(bytes, 0, bytes.Length)

        
    Dim bmpret As Image
        bmpret.Initialize2(
    In)

        
    Return bmpret
    End Sub


    Sub ScanWindow
        
        
    Dim wu As JavaObject
        
        wu.InitializeStatic(
    "com.sun.jna.platform.WindowUtils")

        
    ' I need a list cause I scan several windows
        Dim Ls As List = wu.RunMethod("getAllWindows",Array(True))

        
    Dim tit As String

        
    For Each JO As JavaObject In Ls
            tit = JO.RunMethod(
    "getTitle",Null)
            
            
    If tit = "Window that I need to scan some graphical elements" Then

                    
    Dim awtrect As JavaObject = JO.RunMethod("getLocAndSize"Null)
                    
                    OriginX = awtrect.GetField(
    "x")
                    OriginY = awtrect.GetField(
    "y")
                    
    Log("Form found")
                    
    Return

            
    End If
            
        
    Next

    End Sub

    Sub MainForm_CloseRequest (EventData As Event)
        
        SecondForm.Close

    End Sub



    'Return true to allow the default exceptions handler to handle the uncaught exception.
    Sub Application_Error (Error As Exception, StackTrace As StringAs Boolean
        
    Return True
    End Sub

    Sub Button1_Click
        
    Dim bmp As B4XBitmap
        bmp = Capture(OriginX + 
    100, OriginY + 100300300)
        img.SetImage(bmp)

        SecondForm.Show

    End Sub
     
    Last edited: Aug 6, 2019
  2. emexes

    emexes Well-Known Member Licensed User

    I am guessing that OriginX and OriginY are already in screen-coordinate scale and don't need to be put through DipToCurrent().
    Code:
    SecondForm.WindowLeft = DipToCurrent(OriginX) + 300dip
    SecondForm.WindowTop = 
    DipToCurrent(OriginY) + 300dip
    Code:
    Dim awtrect As JavaObject = JO.RunMethod("getLocAndSize"Null)
    OriginX = awtrect.GetField(
    "x")
    OriginY = awtrect.GetField(
    "y")
    Code:
    bmp = Capture(DipToCurrent(OriginX) + 100dipDipToCurrent(OriginY) + 100dip300dip300dip)
    so delete the four DipToCurrent() calls and give it a run.
     
  3. jroriz

    jroriz Active Member Licensed User

    Nice try but the result was the same.
     
  4. emexes

    emexes Well-Known Member Licensed User

    I knew my lucky sage streak would end someday. I am sad that day is today but I am honored that it ended on a worthy problem.

    :)
     
  5. emexes

    emexes Well-Known Member Licensed User

    Having said that, could you try the following Logs? Because if:
    then that would imply that DipToCurrent() has no effect, which... hmm...
    Code:
    SecondForm.WindowLeft = DipToCurrent(OriginX) + 300dip
    SecondForm.WindowTop = 
    DipToCurrent(OriginY) + 300dip
    Log("OriginX = " & OriginX)
    Log("OriginY = " & OriginY)
    Log(DipToCurrent(OriginX))
    Log("300dip = " & 300dip)
    Code:
    bmp = Capture(DipToCurrent(OriginX) + 100dipDipToCurrent(OriginY) + 100dip300dip300dip)
    Log("OriginX = " & OriginX)
    Log("OriginY = " & OriginY)
    Log(DipToCurrent(OriginX))
    Log("100dip = " & 100dip)
    Log(DipToCurrent(OriginX) + 100dip)
    Log("300dip = " & 300dip)
     
  6. emexes

    emexes Well-Known Member Licensed User

    Just out of interest: is there a reason for not using the regular graphics operations, eg:
    Code:
    Dim bb As B4XBitmap = MainForm.RootPane.Snapshot    'grab entire content of pane (not including window borders)
    img.SetImage(bb.Crop(92dip70dip300dip300dip))    'and copy cropped part to ImageView on second form
    other than the grab only being from within the full window pane rather than from the entire screen?
     
  7. Erel

    Erel Administrator Staff Member Licensed User

    dip in B4J always equals 1.

    JavaFX takes care of handling the scale for you.

    I haven't checked your project. Make sure to test it with Java 11 as it better handles higher scales.
     
  8. jroriz

    jroriz Active Member Licensed User

    As said by Erel in post 7, dip is always 1 in B7J.
     
  9. jroriz

    jroriz Active Member Licensed User

    Because I'm grabbing small portions of windows that do not belong to my project, they are ordinary windows from other applications.
     
    emexes likes this.
  10. jroriz

    jroriz Active Member Licensed User

    Changed to java java 11.0.1 (java 11.0.4 raises the error "module not found: javafx.swing").
    Now the compiled jar does not run animore. Running from the IDE works, both in debug and release mode.
    Changed to java 11.0.1 (java 11.0.4 raises the error "module not found: javafx.swing").
    Now the compiled jar does not run anymore. Does not show any error, just nothing happens. I have tryed a default new project, and the same happens: the compiled jar does not work, only if I run from the IDE.
     
  11. Erel

    Erel Administrator Staff Member Licensed User

Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice