Jump to content

Read Values out of Table on a Window


Recommended Posts

Hi & "Guetä Morgä!" M23

Thanks for your answers and of course the new code. I don't think that there are lurking away more surprises in my bottomn line.

I've played around with the screen resolution but this din't improve the quality of the bitmap but I've found out, that the first time, the window was activated as I took the snapshot (with snagIt from techsmith com). So maybe we have to consider that the code should also work when the window is deactivated (surprise surprise!) :-). I would be useful if the code runs on the deactivated window because of i have lot's of other windows open. I hope this is not unsolvable for a genius like you.

At the moment, I don't have a row containing XPD but I'll send you the new PICs as soon I have one. In the meantime, I've made to PICs containing a D from 'USD'. Maybe this is already enough for you.

It may be that we get more than 2 rows at the same time so I think we should consider the total of rows in the status row. Because of then it might be easier to determine how many new rows came in and thus must be displayed in the POPUP.

I'll now jump over to your next post and aswer the questions from "there".

thanks

Janpost-56750-12692530090142_thumb.gifpost-56750-12692530345264_thumb.gifpost-56750-12692530435994_thumb.gifpost-56750-12692530555636_thumb.gif

Link to comment
Share on other sites

  • Replies 41
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

Jaenchen,

1. I would like an image of the "D" letter from the screen to confirm what I believe is the pattern to match,

2. I would like to know the number of pixels between the vertical line at the left of the "Curr.1" column (where we place the first cross) and the leftmost pixel of the third letter in the currency code. You can do this with the Au3 Window Info tool which you find at "C:\Program Files\AutoIt3\Au3Info.exe" with a standard AutoIt install. Select the "Mouse" tab and then move the target into the correct places on the app and read the values shown. You can use the <Options - Magnify> menu item to get a better guide as to where to place the cursor. I am currently using a figure of 20 pixels based on the blurred image you sent. Alternatively, send me a better quality picture!

Ha! M23,

Thanks again for the code. It seems to work quite well and please be sure, I'm not cutting the tree, I'm sitting on, by myself.

Your App will prevent us from losing PNL :-) just because of one crapy little window out of about 30-40 you have on your desktop, have not been monitored enough. The worstcase would be you're getting a row droped into, the user does not notice it and the prices are going ballistic.... Ofcourse: All will be the users fault and nobody will blame you or anyone else. Your Tool will be a very decent App the user will appreciate very well to work with it. Btw. NICE Messagebox Formatings and the beet is also great. :-)

Now back to work:

1) I'll send you one as soon as I can create one - in the meantime I hope the one containing USD is sufficient

2) I'm placing the mouse on these areas and I'm getting 52/123 and 74/123 = 22 Pixels in the WindoInfoTool.

((If everything is getting too complicated - what I not really beleave into after all I've seen here - , the user

just would be happy to get messagebox opened saying "NEW ROW IN FX-DEALBLOTTER"))

Best regards

Jan

Yes, YOU!

Edited by Jaenchen
Link to comment
Share on other sites

  • Moderators

Jaenchen,

And a good morning to you too. :( Under sunny skies I won the match on the final green with a round of 6 under my handicap - all is well with the world! :) So to your questions:

the code should also work when the window is deactivated

It will work if the window is visible on screen - it needs to see the pixels, so the app window cannot be minimised or hidden by other windows, it must be visible somewhere on the screen.

a D from 'USD'. Maybe this is already enough

It is - and my guess was correct.

It may be that we get more than 2 rows at the same time

The code as it stands will read up to 13 new rows on each pass - which I hope will be sufficient. I do NOT want to read the status bar - it means another cross to position.

22 Pixels in the WindoInfoTool

Thanks - that was the final piece of the jigsaw!

OK, time to try on the real thing! :) Make sure the app window is visible, with the GMT, Curr.1 and Amount1 columns showing, and run this script. You will have to place the 2 crosses and then you should see a dialog displaying the first 14 lines of the contents of your app with the correct values.

#Region ; ----- Includes -----

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include <Array.au3>
#include <Misc.au3>

#EndRegion
#Region ; ----- Get App handle -----

; Get handle of app window
$iOldMode = Opt("WinTitleMatchMode", 2)
$hGUI = WinGetHandle("FX daily deal blotter")
If @error Then MsgBox(16, "Disaster!", "Could not find the Window")
Opt("WinTitleMatchMode", $iOldMode)

#EndRegion ; ----- Find fxddb GUI -----
#Region ; ----- Determine ini path

; Determine location for ini file
If @ScriptDir = @ProgramFilesDir Then
    ; If app in C:\Program Files need to save elsewhere
    If Not FileExists(@AppDataDir & "\fxddb") Then DirCreate(@AppDataDir & "\fxddb")
    $sIniFile = @AppDataDir & "\fxddb\fxddb.ini"
Else
    ; Can use app folder
    $sIniFile = @ScriptDir & "\fxddb.ini"
EndIf

#EndRegion
#Region ; ----- Declarations -----


; Array of digit and sign codes
Global $aChecks[12] = [ _
        "011110100001100001100001100001100001100001100001100001011110", _
        "000100001100010100000100000100000100000100000100000100000100", _
        "011110100001000001000001000001000010000100001000010000111111", _
        "011110100001000001000001001110000001000001000001100001011110", _
        "000010000110000110001010001010010010010010111111000010000010", _
        "011111010000010000100000111110100001000001000001100001011110", _
        "011110100001100000100000101110110001100001100001100001011110", _
        "111111000010000010000100000100001000001000010000010000010000", _
        "011110100001100001100001011110100001100001100001100001011110", _
        "011110100001100001100001100011011101000001000001100010011100", _
        "000000000000000100000100000100111111000100000100000100000000", _
        "000000000000000000000000000000000000000111000000000000000000"]

; Array of Curr.1 letter edges (D, G, T, U)
Global $aCurr[4] = [ _
        "1111111111", _
        "0011111100", _
        "1000000000", _
        "1111111100"]

; Array to hold numbers read from app
Global $aCurrArray[15][3]

; Find position of the app window
Global $aAppPos = WinGetPos($hGUI)

; Coords of the 2 points user will mark
Global $iX_Cross_1, $iY_Cross_1, $iX_Cross_2, $iY_Cross_2, $iX_Colon = $aAppPos[0] - 1

#EndRegion
#Region ; ----- Initialisation -----

; Get user to mark the points
Mark_Cross()

#EndRegion
#Region ; ----- Read values -----
; Read the numbers in GMT, Curr.1 and Amount1 columns to set the base array
Read_Values()

_ArrayDisplay($aCurrArray)

Exit

#EndRegion
#Region ; ----- Read_Values -----

Func Read_Values()

    ; Coords of zones to check for digit/sign
    Local $aX_Coords_1[4] = [-15, -8, 3, 10]
    Local $aX_Coords_2[9] = [65, 58, 51, 47, 40, 33, 26, 15, 8]
    $iY_Coord = $iY_Cross_1 + 3

    ; Reset array
    Global $aCurrArray[15][3]

    ; Find colon if not yet set
    If $iX_Colon = $aAppPos[0] - 1 Then Find_Colon()

    ; Move down line by line
    For $iY_Index = 0 To 14

        $iBackgroundColour = Hex(PixelGetColor($iX_Colon - 1, $iY_Coord + ($iY_Index * 16) + 1), 6)

        ; Start in the GMT column

        ; Zero the code
        $sCode = ""

        ; Move through the digit/sign spaces from left
        For $iX_Index = 0 To 3

            ; Move through the space to build the code
            $sString = ""
            For $y = 0 To 9
                For $x = 0 To 5
                    $sString &= Read_Pixel($iX_Colon + $aX_Coords_1[$iX_Index] + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
                Next
            Next

            ; Check in the index for a match
            $iIndex = _ArraySearch($aChecks, $sString)

            ; Add the correct digit/sign to the list
            Switch $iIndex
                Case 0 To 9
                    $sCode &= $iIndex
            EndSwitch

            ; Add colon in correct place
            If $iX_Index = 1 Then $sCode &= ":"

        Next

        ; Check if we have reached the end of entries
        If $sCode = ":" Then ExitLoop

        ; Store the GMT
        $aCurrArray[$iY_Index][0] = $sCode

        ; Now move on to Curr.1 column

        ; To distinguish between the possible values, we need only look at the left edge of the 3rd letter
        $iX_Curr = $iX_Cross_1 + 22

        ; Read the edge line
        $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($iX_Curr, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
        Next

        ; Check in the index for a match and write to the array
        $iIndex = _ArraySearch($aCurr, $sString)
        Switch $iIndex
            Case 0
                $aCurrArray[$iY_Index][1] = "XPD"
            Case 1
                $aCurrArray[$iY_Index][1] = "XAG"
            Case 2
                $aCurrArray[$iY_Index][1] = "XPT"
            Case 3
                $aCurrArray[$iY_Index][1] = "XAU"
        EndSwitch

        ; Now move on to the Amount1 column

        ; Zero the code
        $sCode = ""

        ; Move through the digit/sign spaces from left
        For $iX_Index = 0 To 8

            ; Move through the space
            $sString = ""
            For $y = 0 To 9
                For $x = 0 To 5
                    $sString &= Read_Pixel($iX_Cross_2 - $aX_Coords_2[$iX_Index] + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
                Next
            Next

            ; Check in the index for a match
            $iIndex = _ArraySearch($aChecks, $sString)

            ; Add the correct digit/sign to the list
            Switch $iIndex
                Case 0 To 9
                    $sCode &= $iIndex
                Case 10
                    $sCode &= "+"
                Case 11
                    $sCode &= "-"
            EndSwitch

            If $iX_Index = 2 Then
                ; If we did not find a digit at the thousands point, check for a sign
                ; If we did, add a comma
                If $iIndex > 0 Then
                    $iX_Index = 3
                    $sCode &= ","
                EndIf
            EndIf

            ; Add the decimal at the correct point
            If $iX_Index = 6 Then $sCode &= "."

        Next

        ; Store the Amount 1
        $aCurrArray[$iY_Index][2] = $sCode

    Next

EndFunc   ;==>Read_Values

#EndRegion
#Region ; ----- Find_Colon -----

Func Find_Colon()

    ; Set Y coord
    $iY_Coord = $iY_Cross_1 + 3

    ; Check colour of background
    $iBackgroundColour = Hex(PixelGetColor($iX_Cross_1 - 1, $iY_Coord), 6)

    ; Move across app window to find colon
    For $x = $iX_Cross_1 To $aAppPos[0] Step -1
        $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($x, $iY_Coord + $y, $iBackgroundColour)
        Next
        ; Found it
        If $sString = "0001000001" Then ExitLoop
    Next

    ; Set the coordinate to the colon
    $iX_Colon = $x

EndFunc   ;==>Find_Colon

#EndRegion
#Region ; ----- Read_ Pixel -----

Func Read_Pixel($iX_Pixel, $iY_Pixel, $iBackgroundColour)

    $sColour = Hex(PixelGetColor($iX_Pixel, $iY_Pixel), 6)
    ; If pixel colour is not the background colour - set the code
    If $sColour <> $iBackgroundColour Then
        Return "1"
    Else
        Return "0"
    EndIf

EndFunc   ;==>Read_Pixel

#EndRegion
#Region ; ----- Mark_Cross -----

Func Mark_Cross()

    ; Open dll for _IsPressed
    Local $UserDLL = DllOpen("user32.dll")

    While 1

        ; Read ini values for GMT cross intial position
        Local $iX_Start = IniRead($sIniFile, "GMT Cross", "X-Coord", 45) + $aAppPos[0]
        Local $iY_Start = IniRead($sIniFile, "GMT Cross", "Y-Coord", 100) + $aAppPos[1]


        ;SplashImageOn("Place the cross here", "fxddb_Splash_1.jpg", 250, 76)

        ; Set GMT cross
        $aRet = Move_Cross($iX_Start, $iY_Start, "fxddb_Splash_1.jpg", $UserDLL)
        $iX_Cross_1 = $aRet[0]
        $iY_Cross_1 = $aRet[1]

        $iCheckSum_1 = PixelChecksum($iX_Cross_1 - 1, $iY_Cross_1 - 1, $iX_Cross_1 + 1, $iY_Cross_1)

        ; Read ini values for Amount1 cross intial position
        Local $iX_Start = IniRead($sIniFile, "Amount1 Cross", "X-Coord", 200) + $aAppPos[0]
        Local $iY_Start = IniRead($sIniFile, "Amount1 Cross", "Y-Coord", 100) + $aAppPos[1]

        ;SplashImageOn("Place the cross here", "fxddb_Splash_2.jpg", 250, 76)

        ; Set Amount1 cross
        $aRet = Move_Cross($iX_Start, $iY_Start, "fxddb_Splash_2.jpg", $UserDLL)
        $iX_Cross_2 = $aRet[0]
        $iY_Cross_2 = $aRet[1]

        $iCheckSum_2 = PixelChecksum($iX_Cross_2 - 1, $iY_Cross_2 - 1, $iX_Cross_2 + 1, $iY_Cross_2)

        ;SplashOff()

        ; Check for confirmation of correct positioning
        If $iCheckSum_1 = $iCheckSum_2 Then
            ExitLoop
        Else
            MsgBox(48, "fxddb Error", "The crosses were not properly positioned" & @CRLF & "Please try again")
        EndIf

        While _IsPressed("0D", $UserDLL)
            Sleep(10)
        WEnd

    WEnd

    ; Save values 1 pixel off
    IniWrite($sIniFile, "GMT Cross", "X-Coord", $iX_Cross_1 - $aAppPos[0] - 1)
    IniWrite($sIniFile, "GMT Cross", "Y-Coord", $iY_Cross_1 - $aAppPos[1] - 1)
    IniWrite($sIniFile, "Amount1 Cross", "X-Coord", $iX_Cross_2 - $aAppPos[0] - 1)
    IniWrite($sIniFile, "Amount1 Cross", "Y-Coord", $iY_Cross_2 - $aAppPos[1] - 1)

    ; Close dll
    DllClose($UserDLL)

EndFunc   ;==>Mark_Cross

#EndRegion
#Region ; ----- Move_Cross -----

Func Move_Cross($iX_Mark, $iY_Mark, $sImage, $UserDLL)

    Local $aRet[2]

    ; Determine location of example GUI
    $iX_Loc = $aAppPos[0] - 250
    If $aAppPos[0] < 300 Then $iX_Loc = $aAppPos[0] + $aAppPos[2]
    $iY_Loc = $aAppPos[1] + 100

    ; Create example GUI
    $hExampleGUI = GUICreate("Place the cross here", 250, 96, $iX_Loc, $iY_Loc, $WS_POPUPWINDOW, -1, WinGetHandle(AutoitWinGetTitle()))
    GUICtrlCreateLabel("Place cross on intersection in centre of circle", 0, 0, 250, 20, BitOR($SS_CENTER, $SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFFFF00)
    GUICtrlCreatePic($sImage, 0, 20, 250, 76)
    GUISetState()

    ; Create transparent GUI over the app with Cross cursor
    $hCross_GUI = GUICreate("Test", $aAppPos[2], $aAppPos[3], $aAppPos[0], $aAppPos[1], $WS_POPUP, $WS_EX_TOPMOST)
    WinSetTrans($hCross_GUI, "", 8)
    GUISetState(@SW_SHOW, $hCross_GUI)
    GUISetCursor(3, 1, $hCross_GUI)

    MouseMove($iX_Mark, $iY_Mark, 0)

    ; Wait for adjustments or confirmation
    While 1
        If _IsPressed("25", $UserDLL) Then
            $iX_Mark -= 1
            While _IsPressed("25", $UserDLL)
                Sleep(10)
            WEnd
        EndIf
        If _IsPressed("26", $UserDLL) Then
            $iY_Mark -= 1
            While _IsPressed("26", $UserDLL)
                Sleep(10)
            WEnd
        EndIf
        If _IsPressed("27", $UserDLL) Then
            While _IsPressed("27", $UserDLL)
                Sleep(10)
            WEnd
            $iX_Mark += 1
        EndIf
        If _IsPressed("28", $UserDLL) Then
            While _IsPressed("28", $UserDLL)
                Sleep(10)
            WEnd
            $iY_Mark += 1
        EndIf
        If _IsPressed("0D", $UserDLL) Then
            While _IsPressed("0D", $UserDLL)
                Sleep(10)
            WEnd
            $aRet[0] = $iX_Mark
            $aRet[1] = $iY_Mark
            GUIDelete($hCross_GUI)
            GUIDelete($hExampleGUI)
            Return $aRet
        EndIf

        MouseMove($iX_Mark, $iY_Mark)

    WEnd

EndFunc   ;==>Move_Cross

#EndRegion

Let me know how it works - my fingers are firmly crossed! ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Wahoo! Hello again M23

Ok, the Window get's found it reads 14 rows, GMT is correct, Curr1. there's only XPD filled from 14:18, Amount1 are all ok. I would say, that's qute a good work until here, dear M23.

Unfortunately I don't play Golf but if I would have time for, I'd like to start with..

As you maybe have seen, we've got also a KPT in the Curr1 List. Does this matter as you only check the last Char? For me, K=X.

Ah, yes. Can we limit the trys of positioning the + to 3 because of otherwise it ends up in a loop.

Do you have any Idea why it's not recognizing the Curr1. ?

Back to you.

Jan

..Added new PIC containing all Curr.1

post-56750-12692725121859_thumb.gif

Link to comment
Share on other sites

  • Moderators

Jaenchen,

It is not recognising the Curr.1 data because there are only 20 pixels between the cross and the third letter and not 22 as we measured last time! :(

I will have to work on an algoritm to find the letter rather than just rely on a pixel count. :)

Can we limit the trys of positioning the + to 3 because of otherwise it ends up in a loop

Of course, but if you do not position the crosses, you do not get the results!

See you tomorrow with a new version. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

M23

I've re-checked the Pixcels from the top left Curr.1 to the last letter and I've seen, that it's 20 now (odd) if I replace the 22 with 20 in your code, all works well, except the "KPT". Should we reduce the check to the last Char of the Curr.1 Picture?

So: All my fault! :( Sorry for wasting your time in that case. This just as an update from my (learning) side.

Jan

Update: "KPT" works with 21 all the rest with 20. So it must be depending on the first letter X or K. :-(

Edited by Jaenchen
Link to comment
Share on other sites

  • Moderators

Jaenchen,

I now have a working algorithm to detect the start of the third letter (it depends on the size of the 2 previous letters :( ), so at least that is taken care of. :)

What other currency abbreviations might appear in that column? I ask because at the moment I am only checking the left edge of the third letter (as that is enough to distinguish between D, G, T and U. If there are other abbreviations this might not be enough to distinguish between them and the 4 we are looking for. Do all the codes you are interested in begin with X? Is that a unique identifier? I do not want to have to identify all 26 letters, but if we have to....... :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

Jaenchen,

Try this script - it should return an array with the Curr.1 codes that begin with X written in full and anything else marked as "Other". Is that good enough? :(

#Region ; ----- Includes -----

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include <Array.au3>
#include <Misc.au3>

#EndRegion
#Region ; ----- Get App handle -----

; Get handle of app window
$iOldMode = Opt("WinTitleMatchMode", 2)
$hGUI = WinGetHandle("FX daily deal blotter")
If @error Then MsgBox(16, "Disaster!", "Could not find the Window")
Opt("WinTitleMatchMode", $iOldMode)

#EndRegion ; ----- Find fxddb GUI -----
#Region ; ----- Determine ini path

; Determine location for ini file
If @ScriptDir = @ProgramFilesDir Then
    ; If app in C:\Program Files need to save elsewhere
    If Not FileExists(@AppDataDir & "\fxddb") Then DirCreate(@AppDataDir & "\fxddb")
    $sIniFile = @AppDataDir & "\fxddb\fxddb.ini"
Else
    ; Can use app folder
    $sIniFile = @ScriptDir & "\fxddb.ini"
EndIf

#EndRegion
#Region ; ----- Declarations -----


; Array of digit and sign codes
Global $aChecks[12] = [ _
        "011110100001100001100001100001100001100001100001100001011110", _
        "000100001100010100000100000100000100000100000100000100000100", _
        "011110100001000001000001000001000010000100001000010000111111", _
        "011110100001000001000001001110000001000001000001100001011110", _
        "000010000110000110001010001010010010010010111111000010000010", _
        "011111010000010000100000111110100001000001000001100001011110", _
        "011110100001100000100000101110110001100001100001100001011110", _
        "111111000010000010000100000100001000001000010000010000010000", _
        "011110100001100001100001011110100001100001100001100001011110", _
        "011110100001100001100001100011011101000001000001100010011100", _
        "000000000000000100000100000100111111000100000100000100000000", _
        "000000000000000000000000000000000000000111000000000000000000"]

; Array of Curr.1 letter edges (D, G, T, U)
Global $aCurr[4] = [ _
        "1111111111", _
        "0011111100", _
        "1000000000", _
        "1111111100"]

; Array to hold numbers read from app
Global $aCurrArray[15][3]

; Find position of the app window
Global $aAppPos = WinGetPos($hGUI)

; Coords of the 2 points user will mark
Global $iX_Cross_1, $iY_Cross_1, $iX_Cross_2, $iY_Cross_2, $iX_Colon = $aAppPos[0] - 1, $iX_3Letter

#EndRegion
#Region ; ----- Initialisation -----

; Get user to mark the points
Mark_Cross()

#EndRegion
#Region ; ----- Read values -----
; Read the numbers in GMT, Curr.1 and Amount1 columns to set the base array
Read_Values()

_ArrayDisplay($aCurrArray)

Exit

#EndRegion
#Region ; ----- Read_Values -----

Func Read_Values()

    ; Coords of zones to check for digit/sign
    Local $aX_Coords_1[4] = [-15, -8, 3, 10]
    Local $aX_Coords_2[9] = [65, 58, 51, 47, 40, 33, 26, 15, 8]
    $iY_Coord = $iY_Cross_1 + 3

    ; Reset array
    Global $aCurrArray[15][3]

    ; Find colon if not yet set
    If $iX_Colon = $aAppPos[0] - 1 Then Find_Colon()

    ; Move down line by line
    For $iY_Index = 0 To 14

        $iBackgroundColour = Hex(PixelGetColor($iX_Colon - 1, $iY_Coord + ($iY_Index * 16) + 1), 6)

        ; Start in the GMT column

        ; Zero the code
        $sCode = ""

        ; Move through the digit/sign spaces from left
        For $iX_Index = 0 To 3

            ; Move through the space to build the code
            $sString = ""
            For $y = 0 To 9
                For $x = 0 To 5
                    $sString &= Read_Pixel($iX_Colon + $aX_Coords_1[$iX_Index] + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
                Next
            Next

            ; Check in the index for a match
            $iIndex = _ArraySearch($aChecks, $sString)

            ; Add the correct digit/sign to the list
            Switch $iIndex
                Case 0 To 9
                    $sCode &= $iIndex
            EndSwitch

            ; Add colon in correct place
            If $iX_Index = 1 Then $sCode &= ":"

        Next

        ; Check if we have reached the end of entries
        If $sCode = ":" Then ExitLoop

        ; Store the GMT
        $aCurrArray[$iY_Index][0] = $sCode

        ; Now move on to Curr.1 column

        ; Determine the X-Coord for the third letter
        $iX_3Letter = Find_Letter($iY_Coord, $iY_Index, $iBackgroundColour)
        ; Check if the first letter is an X
        If $iX_3Letter = 0 Then
            $aCurrArray[$iY_Index][1] = "Other"
        Else

            ; To distinguish between the possible values, we need only look at the left edge of the 3rd letter
            $iX_Curr = $iX_Cross_1 + $iX_3Letter

            ; Read the edge line
            $sString = ""
            For $y = 0 To 9
                $sString &= Read_Pixel($iX_Curr, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
            Next

            ; Check in the index for a match and write to the array
            $iIndex = _ArraySearch($aCurr, $sString)
            Switch $iIndex
                Case 0
                    $aCurrArray[$iY_Index][1] = "XPD"
                Case 1
                    $aCurrArray[$iY_Index][1] = "XAG"
                Case 2
                    $aCurrArray[$iY_Index][1] = "XPT"
                Case 3
                    $aCurrArray[$iY_Index][1] = "XAU"
            EndSwitch
        EndIf

        ; Now move on to the Amount1 column

        ; Zero the code
        $sCode = ""

        ; Move through the digit/sign spaces from left
        For $iX_Index = 0 To 8

            ; Move through the space
            $sString = ""
            For $y = 0 To 9
                For $x = 0 To 5
                    $sString &= Read_Pixel($iX_Cross_2 - $aX_Coords_2[$iX_Index] + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
                Next
            Next

            ; Check in the index for a match
            $iIndex = _ArraySearch($aChecks, $sString)

            ; Add the correct digit/sign to the list
            Switch $iIndex
                Case 0 To 9
                    $sCode &= $iIndex
                Case 10
                    $sCode &= "+"
                Case 11
                    $sCode &= "-"
            EndSwitch

            If $iX_Index = 2 Then
                ; If we did not find a digit at the thousands point, check for a sign
                ; If we did, add a comma
                If $iIndex > 0 Then
                    $iX_Index = 3
                    $sCode &= ","
                EndIf
            EndIf

            ; Add the decimal at the correct point
            If $iX_Index = 6 Then $sCode &= "."

        Next

        ; Store the Amount 1
        $aCurrArray[$iY_Index][2] = $sCode

    Next

EndFunc   ;==>Read_Values

#EndRegion
#Region ; ----- Find_Colon -----

Func Find_Colon()

    ; Set Y coord
    $iY_Coord = $iY_Cross_1 + 3

    ; Check colour of background
    $iBackgroundColour = Hex(PixelGetColor($iX_Cross_1 - 1, $iY_Coord), 6)

    ; Move across app window to find colon
    For $x = $iX_Cross_1 To $aAppPos[0] Step -1
        $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($x, $iY_Coord + $y, $iBackgroundColour)
        Next
        ; Found it
        If $sString = "0001000001" Then ExitLoop
    Next

    ; Set the coordinate to the colon
    $iX_Colon = $x

EndFunc   ;==>Find_Colon

#EndRegion

Func Find_Letter($iY_Coord, $iY_Index, $iBackgroundColour)

    ; Move across app to ID first letter
    For $x = 2 To 10
        $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($iX_Cross_1 + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
        Next
        Switch $sString
            ; If blank keep going to find start of letter
            Case "0000000000"
                ContinueLoop
            ; If X Then ExitLoop to find 3rd letter
            Case "1000000001"
                ExitLoop
            Case Else
                Return 0
        EndSwitch
    Next

    Local $fBlank = False

    ; Move across app window to find third letter
    For $x = 15 To 30
        $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($iX_Cross_1 + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
        Next
        Switch $fBlank
            Case False
                ; Check for blank line
                If $sString = "0000000000" Then $fBlank = True
            Case True
                ; Check for beginning of letter
                If $sString <> "0000000000" Then ExitLoop
        EndSwitch
    Next

    ; Set the cordinate to the left edge of the third letter
    Return $x

EndFunc
#Region ; ----- Read_ Pixel -----

Func Read_Pixel($iX_Pixel, $iY_Pixel, $iBackgroundColour)

    $sColour = Hex(PixelGetColor($iX_Pixel, $iY_Pixel), 6)
    ; If pixel colour is not the background colour - set the code
    If $sColour <> $iBackgroundColour Then
        Return "1"
    Else
        Return "0"
    EndIf

EndFunc   ;==>Read_Pixel

#EndRegion
#Region ; ----- Mark_Cross -----

Func Mark_Cross()

    ; Open dll for _IsPressed
    Local $UserDLL = DllOpen("user32.dll")

    For $i = 1 To 3

        ; Read ini values for GMT cross intial position
        Local $iX_Start = IniRead($sIniFile, "GMT Cross", "X-Coord", 45) + $aAppPos[0]
        Local $iY_Start = IniRead($sIniFile, "GMT Cross", "Y-Coord", 100) + $aAppPos[1]

        ; Set GMT cross
        $aRet = Move_Cross($iX_Start, $iY_Start, "fxddb_Splash_1.jpg", $UserDLL)
        $iX_Cross_1 = $aRet[0]
        $iY_Cross_1 = $aRet[1]

        $iCheckSum_1 = PixelChecksum($iX_Cross_1 - 1, $iY_Cross_1 - 1, $iX_Cross_1 + 1, $iY_Cross_1)

        ; Read ini values for Amount1 cross intial position
        Local $iX_Start = IniRead($sIniFile, "Amount1 Cross", "X-Coord", 200) + $aAppPos[0]
        Local $iY_Start = IniRead($sIniFile, "Amount1 Cross", "Y-Coord", 100) + $aAppPos[1]

        ; Set Amount1 cross
        $aRet = Move_Cross($iX_Start, $iY_Start, "fxddb_Splash_2.jpg", $UserDLL)
        $iX_Cross_2 = $aRet[0]
        $iY_Cross_2 = $aRet[1]

        $iCheckSum_2 = PixelChecksum($iX_Cross_2 - 1, $iY_Cross_2 - 1, $iX_Cross_2 + 1, $iY_Cross_2)

        ; Check for confirmation of correct positioning

        If $iY_Cross_1 <> $iY_Start And $iY_Cross_1 = $iY_Cross_2 Then
            ; Save values 1 pixel off
            IniWrite($sIniFile, "GMT Cross", "X-Coord", $iX_Cross_1 - $aAppPos[0] - 1)
            IniWrite($sIniFile, "GMT Cross", "Y-Coord", $iY_Cross_1 - $aAppPos[1] - 1)
            IniWrite($sIniFile, "Amount1 Cross", "X-Coord", $iX_Cross_2 - $aAppPos[0] - 1)
            IniWrite($sIniFile, "Amount1 Cross", "Y-Coord", $iY_Cross_2 - $aAppPos[1] - 1)
            ; Close dll
            DllClose($UserDLL)
            Return
        Else
            If $i = 3 Then
                MsgBox(48, "fxddb Error", "If you do not want to set me up properly then I am not going to play!")
                Exit
            Else
                MsgBox(48, "fxddb Error", "The crosses were not properly positioned" & @CRLF & "Please try again")
            EndIf
        EndIf

        While _IsPressed("0D", $UserDLL)
            Sleep(10)
        WEnd

    Next

EndFunc   ;==>Mark_Cross

#EndRegion
#Region ; ----- Move_Cross -----

Func Move_Cross($iX_Mark, $iY_Mark, $sImage, $UserDLL)

    Local $aRet[2]

    ; Determine location of example GUI
    $iX_Loc = $aAppPos[0] - 250
    If $aAppPos[0] < 300 Then $iX_Loc = $aAppPos[0] + $aAppPos[2]
    $iY_Loc = $aAppPos[1] + 100

    ; Create example GUI
    $hExampleGUI = GUICreate("Place the cross here", 250, 96, $iX_Loc, $iY_Loc, $WS_POPUPWINDOW, -1, WinGetHandle(AutoitWinGetTitle()))
    GUICtrlCreateLabel("Place cross on intersection in centre of circle", 0, 0, 250, 20, BitOR($SS_CENTER, $SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFFFF00)
    GUICtrlCreatePic($sImage, 0, 20, 250, 76)
    GUISetState()

    ; Create transparent GUI over the app with Cross cursor
    $hCross_GUI = GUICreate("Test", $aAppPos[2], $aAppPos[3], $aAppPos[0], $aAppPos[1], $WS_POPUP, $WS_EX_TOPMOST)
    WinSetTrans($hCross_GUI, "", 8)
    GUISetState(@SW_SHOW, $hCross_GUI)
    GUISetCursor(3, 1, $hCross_GUI)

    MouseMove($iX_Mark, $iY_Mark, 0)

    ; Wait for adjustments or confirmation
    While 1
        If _IsPressed("25", $UserDLL) Then
            $iX_Mark -= 1
            While _IsPressed("25", $UserDLL)
                Sleep(10)
            WEnd
        EndIf
        If _IsPressed("26", $UserDLL) Then
            $iY_Mark -= 1
            While _IsPressed("26", $UserDLL)
                Sleep(10)
            WEnd
        EndIf
        If _IsPressed("27", $UserDLL) Then
            While _IsPressed("27", $UserDLL)
                Sleep(10)
            WEnd
            $iX_Mark += 1
        EndIf
        If _IsPressed("28", $UserDLL) Then
            While _IsPressed("28", $UserDLL)
                Sleep(10)
            WEnd
            $iY_Mark += 1
        EndIf
        If _IsPressed("0D", $UserDLL) Then
            While _IsPressed("0D", $UserDLL)
                Sleep(10)
            WEnd
            $aRet[0] = $iX_Mark
            $aRet[1] = $iY_Mark
            GUIDelete($hCross_GUI)
            GUIDelete($hExampleGUI)
            Return $aRet
        EndIf

        MouseMove($iX_Mark, $iY_Mark)

    WEnd

EndFunc   ;==>Move_Cross

#EndRegion

M23

Edit: Typnig!

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

M23,

Thanks for the fixes. Yes, this would work. In that case, the messagebox then could be "NEW ROW in FX-Dealblotter"

But if we want to make it perfect, then the tool should maybe figure out X or K at the begining and then start from

if X, then 20 else 19 and we would get the correct Curr.1 too.

What do you think?

Jan

Link to comment
Share on other sites

  • Moderators

Jaenchen,

No need for 19 or 20 - the script is now much cleverer than that. It will find the actual edge of the first and third letters - no matter where in the column. :(

Detecting X or K as the first letter of the Curr.1 code is easy - but I am now confused (not uncommon ;) ) about what exactly you want. Is this correct?

- You want "BUY/SELL" messageboxes if the Curr.1 code is XPD, XAG, APT or XAU and the limits you mentioned earlier are exceeded.

- You want a "NEW ENTRY" messagebox if any other Curr.1 code arrives in the app.

- What happens if one of the "X" codes arrives and does NOT exceed the limits? Do you want any kind of alert when that happens? It is really easy to produce a "NEW ENTRY" messagebox. :)

That is all simple to code - just let me know if I am right tomorrow :)

M23

Edit: A few changes above and.....

There are only 2. X and K at the begining, so total max 8

I missed this earlier. Does this mean we are looking at XPD, XAG, APT, XAU, KPD, KAG, KPT and KAU as the only options in the Curr.1 column? I do hope so as it simplifies things enormously! :D Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I missed this earlier. Does this mean we are looking at XPD, XAG, APT, XAU, KPD, KAG, KPT and KAU as the only options in the Curr.1 column? I do hope so as it simplifies things enormously! :(

Hi M23

Yes, that means exactly we're looking (checking exceeding amounts) for

- XAU, XAG, XPD, XPT (this is representing Ouces)

- KAU, KAG, KPD, KPT (this is representing Kilogram)

Sorry (again) for not beeing that clear. Fouuuuuuur!!!!!! or Foooooooor!!!!! :-)

back to you.

jan

Link to comment
Share on other sites

  • Moderators

Jaenchen,

Good Morning,

Ok final (I hope!) questions:

- You imply you have limits for the K codes as well? If so, what are they?

- Would you like the possibilty to adjust these limits as and when necessary? It is trivial to do this and it would save you having to rewrite the code if the limits change.

- If the trade does not meet or exceed the limit you want a simple notification alert. Otherwise a BUY/SELL alert. Correct?

Once you give me answers to these questios I believe we are very close to the solution. :)

I am off to the gym now :( - I will be back after lunch.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

- You imply you have limits for the K codes as well? If so, what are they?

- Would you like the possibilty to adjust these limits as and when necessary? It is trivial to do this and it would save you having to rewrite the code if the limits change.

- If the trade does not meet or exceed the limit you want a simple notification alert. Otherwise a BUY/SELL alert. Correct?

M23,

Good question(s)! I hope, I can now provide the final Answers too :(

- Yes but the Values coming with K could be multiplyed with 32.1507425 so we're getting the Ounces and could check against them.

For sure it would be useful to have a nice GUI to maintain the limits so we (yes you!) :) wouldn't have to rewrite the code all the time

I suggest a gui like

Monitor: ON/OFF

LIMITS: Oz / KG

XAU 1000 / 30

XAG 25000 / 777

XPT 1000 / 30

XPD 1000 / 30

- No messagebox/action at all if a trade don't exceed the limit

Have fun at the gym, I should do some too, the summer is close! Enjoy your salad(!?!)

Jan

Edited by Jaenchen
Link to comment
Share on other sites

  • Moderators

Jaenchen,

Feeling very virtuous after my exercise :( , I return to offer what I hope is a pretty definitive version to be run on your app.

When you first run the script, you will be asked to insert the transaction limit values you require (I know you told me what they are, but you need to get them into the ini file :) ). Then the crosses are placed as usual and - I hope - you will be alerted whenever a transaction passes the limit (you might want to set some artificially low limits initially to check this).

The code:

#region ; ----- Includes -----

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include <Array.au3>
#include <Misc.au3>

#endregion ; ----- Includes -----
; ############# fxddb #############
;
; Reading from the FX daily deal blotter
;
; Initial release
;
; Script Version: 1.0.0.0
;   As at 23 Mar 10
;
#region ; ----- Get App handle -----

; Get handle of app window
Global $iOldMode = Opt("WinTitleMatchMode", 2)
Global $hGUI = WinGetHandle("FX daily deal blotter")
If @error Then
    MsgBox(16, "fxddb Disaster!", "Cannot find the window!")
    Exit
EndIf
Opt("WinTitleMatchMode", $iOldMode)

#endregion ; ----- Get App handle -----
#region ; ----- HotKey Exit -----

; Set exit strategy
HotKeySet("{ESC}", "On_Exit")

#endregion ; ----- HotKey Exit -----
#region ; ----- Declarations -----

; Array of digit and sign codes
Global $aChecks[12] = [ _
        "011110100001100001100001100001100001100001100001100001011110", _
        "000100001100010100000100000100000100000100000100000100000100", _
        "011110100001000001000001000001000010000100001000010000111111", _
        "011110100001000001000001001110000001000001000001100001011110", _
        "000010000110000110001010001010010010010010111111000010000010", _
        "011111010000010000100000111110100001000001000001100001011110", _
        "011110100001100000100000101110110001100001100001100001011110", _
        "111111000010000010000100000100001000001000010000010000010000", _
        "011110100001100001100001011110100001100001100001100001011110", _
        "011110100001100001100001100011011101000001000001100010011100", _
        "000000000000000100000100000100111111000100000100000100000000", _
        "000000000000000000000000000000000000000111000000000000000000"]

; Array of Curr.1 letter edges (D, G, T, U)
Global $aCurr[4] = [ _
        "1111111111", _
        "0011111100", _
        "1000000000", _
        "1111111100"]

; Array to hold numbers read from app
Global $aCurrArray[15][3], $aOldArray[15][3]

; Find position of the app window
Global $aAppPos = WinGetPos($hGUI)

; Coords of the 2 points user will mark
Global $iX_Cross_1, $iY_Cross_1, $iX_Cross_2, $iY_Cross_2, $iX_Colon = $aAppPos[0] - 1, $iX_3Letter

; Checksum of top line
Global $iChecksum

; Conversion from kilos to ounces
Global $nConvFactor = 32.1507425

#endregion ; ----- Declarations -----
#region ; ----- Determine ini path

Global $sIniFile

; Determine location for ini file
If @ScriptDir = @ProgramFilesDir Then
    ; If app in C:\Program Files need to save elsewhere
    If Not FileExists(@AppDataDir & "\fxddb") Then DirCreate(@AppDataDir & "\fxddb")
    $sIniFile = @AppDataDir & "\fxddb\fxddb.ini"
Else
    ; Can use app folder
    $sIniFile = @ScriptDir & "\fxddb.ini"
EndIf

IniReadSection($sIniFile, "Limits")
If @error Then
    MsgBox(48, "fxddb Alert", "No transaction limits haver been set" & @CRLF & "Please set them now")
    On_Limits()
EndIf

#endregion ; ----- Determine ini path
#region ; ----- Tray menu -----

Opt("TrayOnEventMode", 1) ; Use event trapping for tray menu
Opt("TrayMenuMode", 3) ; Default tray menu items will not be shown.

; Create tray menu
TrayCreateItem("Set Limits")
TrayItemSetOnEvent(-1, "On_Limits")
TrayCreateItem("")
TrayCreateItem("About")
TrayItemSetOnEvent(-1, "On_About")
TrayCreateItem("")
TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "On_Exit")

#endregion ; ----- Tray menu -----
#region ; ----- Initialisation -----

; Get user to mark the points
Mark_Cross()

; Read the numbers in GMT, Curr.1 and Amount1 columns to set the base array
Read_Values()
$aOldArray = $aCurrArray

; Set the original checksum for the top line
Global $iCurrChecksum = PixelChecksum($aAppPos[0], $iY_Cross_1 + 3, $aAppPos[0] + $aAppPos[2], $iY_Cross_1 + 13)

#endregion ; ----- Initialisation -----
#region ; ----- Main loop -----

; Now start infinite loop
While 1

    ; Check if the top line has changed
    $iChecksum = PixelChecksum($aAppPos[0], $iY_Cross_1 + 3, $aAppPos[0] + $aAppPos[2], $iY_Cross_1 + 13)
    If $iChecksum <> $iCurrChecksum Then

        ; Retain new checksum for future checks
        $iCurrChecksum = $iChecksum

        ; Read the values in GMT, Curr.1 and Amount1 columns
        Read_Values()

        ; Check the new values and send any necessary alerts
        Check_Values()

        ; All warnings sent so replace $aOldArray
        $aOldArray = $aCurrArray

    EndIf

    ; Idle 10 Secs before relooping
    Sleep(10000)

WEnd

; ~~~~~ Functions ~~~~~

#endregion ; ----- Main loop -----
#region ; ----- Read_Values -----

Func Read_Values()

    ; Coords of zones to check for digit/sign
    Local $aX_Coords_1[4] = [-15, -8, 3, 10]
    Local $aX_Coords_2[9] = [65, 58, 51, 47, 40, 33, 26, 15, 8]
    Local $iY_Coord = $iY_Cross_1 + 3

    ; Reset array
    Global $aCurrArray[15][3]

    ; Find colon if not yet set
    If $iX_Colon = $aAppPos[0] - 1 Then Find_Colon()

    ; Move down line by line
    For $iY_Index = 0 To 14

        Local $iBackgroundColour = Hex(PixelGetColor($iX_Colon - 1, $iY_Coord + ($iY_Index * 16) + 1), 6)

        ; Start in the GMT column

        ; Zero the code
        Local $sCode = ""

        ; Move through the digit/sign spaces from left
        For $iX_Index = 0 To 3

            ; Move through the space to build the code
            Local $sString = ""
            For $y = 0 To 9
                For $x = 0 To 5
                    $sString &= Read_Pixel($iX_Colon + $aX_Coords_1[$iX_Index] + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
                Next
            Next

            ; Check in the index for a match
            Local $iIndex = _ArraySearch($aChecks, $sString)

            ; Add the correct digit/sign to the list
            Switch $iIndex
                Case 0 To 9
                    $sCode &= $iIndex
            EndSwitch

            ; Add colon in correct place
            If $iX_Index = 1 Then $sCode &= ":"

        Next

        ; Check if we have reached the end of entries
        If $sCode = ":" Then ExitLoop

        ; Store the GMT
        $aCurrArray[$iY_Index][0] = $sCode

        ; Now move on to Curr.1 column

        ; Determine the first letter and the X-Coord for the third letter
        Local $aLetters = Find_Letters($iY_Coord, $iY_Index, $iBackgroundColour)
        $iX_3Letter = $aLetters[1]

        ; To distinguish between the possible values, we need only look at the left edge of the 3rd letter
        Local $iX_Curr = $iX_Cross_1 + $iX_3Letter

        ; Read the edge line
        $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($iX_Curr, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
        Next

        ; Check in the index for a match and write to the array
        $iIndex = _ArraySearch($aCurr, $sString)
        Switch $iIndex
            Case 0
                $aCurrArray[$iY_Index][1] = $aLetters[0] & "PD"
            Case 1
                $aCurrArray[$iY_Index][1] = $aLetters[0] & "AG"
            Case 2
                $aCurrArray[$iY_Index][1] = $aLetters[0] & "PT"
            Case 3
                $aCurrArray[$iY_Index][1] = $aLetters[0] & "AU"
        EndSwitch

        ; Now move on to the Amount1 column

        ; Zero the code
        $sCode = ""

        ; Move through the digit/sign spaces from left
        For $iX_Index = 0 To 8

            ; Move through the space
            $sString = ""
            For $y = 0 To 9
                For $x = 0 To 5
                    $sString &= Read_Pixel($iX_Cross_2 - $aX_Coords_2[$iX_Index] + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
                Next
            Next

            ; Check in the index for a match
            $iIndex = _ArraySearch($aChecks, $sString)

            ; Add the correct digit/sign to the list
            Switch $iIndex
                Case 0 To 9
                    $sCode &= $iIndex
                Case 10
                    $sCode &= "+"
                Case 11
                    $sCode &= "-"
            EndSwitch

            If $iX_Index = 2 Then
                ; If we did not find a digit at the thousands point, check for a sign
                ; If we did, add a comma
                If $iIndex > 0 Then
                    $iX_Index = 3
                    $sCode &= ","
                EndIf
            EndIf

            ; Add the decimal at the correct point
            If $iX_Index = 6 Then $sCode &= "."

        Next

        ; Store the Amount 1
        $aCurrArray[$iY_Index][2] = $sCode

    Next

EndFunc   ;==>Read_Values

#endregion ; ----- Read_Values -----
#region ; ----- Find_Colon -----

Func Find_Colon()

    ; Set Y coord
    Local $iY_Coord = $iY_Cross_1 + 3

    ; Check colour of background
    Local $iBackgroundColour = Hex(PixelGetColor($iX_Cross_1 - 1, $iY_Coord), 6)

    ; Move across app window to find colon
    For $x = $iX_Cross_1 To $aAppPos[0] Step -1
        Local $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($x, $iY_Coord + $y, $iBackgroundColour)
        Next
        ; Found it
        If $sString = "0001000001" Then ExitLoop
    Next

    ; Set the coordinate to the colon
    $iX_Colon = $x

EndFunc   ;==>Find_Colon

#endregion ; ----- Find_Colon -----
#region ; ----- Find Letter -----

Func Find_Letters($iY_Coord, $iY_Index, $iBackgroundColour)

    ; Move across app to ID first letter
    Local $aRet[2]
    For $x = 2 To 10
        Local $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($iX_Cross_1 + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
        Next
        Switch $sString
            ; If blank keep going to find start of letter
            Case "0000000000"
                ContinueLoop
                ; If X Then ExitLoop to find 3rd letter
            Case "1000000001"
                $aRet[0] = "X"
                ExitLoop
            Case Else
                $aRet[0] = "K"
                ExitLoop
        EndSwitch
    Next

    Local $fBlank = False
    ; Move across app window to find third letter
    For $x = 15 To 30
        $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($iX_Cross_1 + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
        Next
        Switch $fBlank
            Case False
                ; Check for blank line
                If $sString = "0000000000" Then $fBlank = True
            Case True
                ; Check for beginning of letter
                If $sString <> "0000000000" Then ExitLoop
        EndSwitch
    Next

    ; We now have the cordinate to the left edge of the third letter
    $aRet[1] = $x
    Return $aRet

EndFunc   ;==>Find_Letters

#endregion ; ----- Find Letter -----
#region ; ----- Read_ Pixel -----

Func Read_Pixel($iX_Pixel, $iY_Pixel, $iBackgroundColour)

    Local $sColour = Hex(PixelGetColor($iX_Pixel, $iY_Pixel), 6)
    ; If pixel colour is not the background colour - set the code
    If $sColour <> $iBackgroundColour Then
        Return "1"
    Else
        Return "0"
    EndIf

EndFunc   ;==>Read_Pixel

#endregion ; ----- Read_ Pixel -----
#region ; ----- Mark_Cross -----

Func Mark_Cross()

    ; Open dll for _IsPressed
    Local $UserDLL = DllOpen("user32.dll")

    For $i = 1 To 3

        ; Read ini values for GMT cross intial position
        Local $iX_Start = IniRead($sIniFile, "GMT Cross", "X-Coord", 45) + $aAppPos[0]
        Local $iY_Start = IniRead($sIniFile, "GMT Cross", "Y-Coord", 100) + $aAppPos[1]

        ; Set GMT cross
        Local $aRet = Move_Cross($iX_Start, $iY_Start, "fxddb_Splash_1.jpg", $UserDLL)
        $iX_Cross_1 = $aRet[0]
        $iY_Cross_1 = $aRet[1]

        Local $iCheckSum_1 = PixelChecksum($iX_Cross_1 - 1, $iY_Cross_1 - 1, $iX_Cross_1 + 1, $iY_Cross_1)
        ConsoleWrite("CheckSum 1: " & $iCheckSum_1 & @CRLF)

        ; Read ini values for Amount1 cross intial position
        $iX_Start = IniRead($sIniFile, "Amount1 Cross", "X-Coord", 200) + $aAppPos[0]
        $iY_Start = IniRead($sIniFile, "Amount1 Cross", "Y-Coord", 100) + $aAppPos[1]

        ; Set Amount1 cross
        $aRet = Move_Cross($iX_Start, $iY_Start, "fxddb_Splash_2.jpg", $UserDLL)
        $iX_Cross_2 = $aRet[0]
        $iY_Cross_2 = $aRet[1]

        Local $iCheckSum_2 = PixelChecksum($iX_Cross_2 - 1, $iY_Cross_2 - 1, $iX_Cross_2 + 1, $iY_Cross_2)
        ConsoleWrite("CheckSum 2: " & $iCheckSum_2 & @CRLF) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

        ; Check for confirmation of correct positioning

        If $iY_Cross_1 <> $iY_Start And $iY_Cross_1 = $iY_Cross_2 Then
            ; Save values 1 pixel off
            IniWrite($sIniFile, "GMT Cross", "X-Coord", $iX_Cross_1 - $aAppPos[0] - 1)
            IniWrite($sIniFile, "GMT Cross", "Y-Coord", $iY_Cross_1 - $aAppPos[1] - 1)
            IniWrite($sIniFile, "Amount1 Cross", "X-Coord", $iX_Cross_2 - $aAppPos[0] - 1)
            IniWrite($sIniFile, "Amount1 Cross", "Y-Coord", $iY_Cross_2 - $aAppPos[1] - 1)
            ; Close dll
            DllClose($UserDLL)
            Return
        Else
            If $i = 3 Then
                MsgBox(16, "fxddb Error", "If you do not want to set me up properly then I am not going to play!")
                Exit
            Else
                MsgBox(48, "fxddb Error", "The crosses were not properly positioned" & @CRLF & "Please try again")
            EndIf
        EndIf

        While _IsPressed("0D", $UserDLL)
            Sleep(10)
        WEnd

    Next

EndFunc   ;==>Mark_Cross

#endregion ; ----- Mark_Cross -----
#region ; ----- Move_Cross -----

Func Move_Cross($iX_Mark, $iY_Mark, $sImage, $UserDLL)

    Local $aRet[2]

    ; Determine location of example GUI
    Local $iX_Loc = $aAppPos[0] - 250
    If $aAppPos[0] < 300 Then $iX_Loc = $aAppPos[0] + $aAppPos[2]
    Local $iY_Loc = $aAppPos[1] + 100

    ; Create example GUI
    Local $hExampleGUI = GUICreate("Place the cross here", 250, 96, $iX_Loc, $iY_Loc, $WS_POPUPWINDOW, -1, WinGetHandle(AutoItWinGetTitle()))
    GUICtrlCreateLabel("Place cross on intersection in centre of circle", 0, 0, 250, 20, BitOR($SS_CENTER, $SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFFFF00)
    GUICtrlCreatePic($sImage, 0, 20, 250, 76)
    GUISetState()

    ; Create transparent GUI over the app with Cross cursor
    Local $hCross_GUI = GUICreate("Test", $aAppPos[2], $aAppPos[3], $aAppPos[0], $aAppPos[1], $WS_POPUP, $WS_EX_TOPMOST)
    WinSetTrans($hCross_GUI, "", 8)
    GUISetState(@SW_SHOW, $hCross_GUI)
    GUISetCursor(3, 1, $hCross_GUI)

    MouseMove($iX_Mark, $iY_Mark, 0)

    ; Wait for adjustments or confirmation
    While 1
        If _IsPressed("25", $UserDLL) Then
            $iX_Mark -= 1
            While _IsPressed("25", $UserDLL)
                Sleep(10)
            WEnd
        EndIf
        If _IsPressed("26", $UserDLL) Then
            $iY_Mark -= 1
            While _IsPressed("26", $UserDLL)
                Sleep(10)
            WEnd
        EndIf
        If _IsPressed("27", $UserDLL) Then
            While _IsPressed("27", $UserDLL)
                Sleep(10)
            WEnd
            $iX_Mark += 1
        EndIf
        If _IsPressed("28", $UserDLL) Then
            While _IsPressed("28", $UserDLL)
                Sleep(10)
            WEnd
            $iY_Mark += 1
        EndIf
        If _IsPressed("0D", $UserDLL) Then
            While _IsPressed("0D", $UserDLL)
                Sleep(10)
            WEnd
            $aRet[0] = $iX_Mark
            $aRet[1] = $iY_Mark
            GUIDelete($hCross_GUI)
            GUIDelete($hExampleGUI)
            Return $aRet
        EndIf

        MouseMove($iX_Mark, $iY_Mark)

    WEnd

EndFunc   ;==>Move_Cross

#endregion ; ----- Move_Cross -----
#region ; ----- Check values -----

Func Check_Values()

    Local $iThreshold

    For $i = 0 To 14

        Local $sNewLine = $aCurrArray[$i][0] & $aCurrArray[$i][1] & $aCurrArray[$i][2]
        Local $sOldTopLine = $aOldArray[0][0] & $aOldArray[0][1] & $aOldArray[0][2]

        If $sNewLine <> $sOldTopLine Then
            ; New line so get code
            If $aCurrArray[$i][1] = "Other" Then
                Show_Alert("ALERT", $i, 0x80FF80)
            Else
                Local $nNumber = Number(StringReplace($aCurrArray[$i][2], ",", ""))
                ; Convert to ounces if necessary
                If StringLeft($aCurrArray[$i][1], 1) = "K" Then $nNumber *= $nConvFactor
                ; Set Threshold value
                Switch StringRight($aCurrArray[$i][1], 2)
                    Case "AG"
                        $iThreshold = IniRead($sIniFile, "Limits", "AG", "Error")
                    Case "AU"
                        $iThreshold = IniRead($sIniFile, "Limits", "AU", "Error")
                    Case "PD"
                        $iThreshold = IniRead($sIniFile, "Limits", "PD", "Error")
                    Case "PT"
                        $iThreshold = IniRead($sIniFile, "Limits", "PT", "Error")
                EndSwitch
                ; Check we have valid limits
                If $iThreshold = "Error" Then
                    MsgBox(16, "fxddb Error", "Limits are invalid" & @CRLF & "Please reset the limit values and restart!")
                    On_Limits()
                    Exit
                EndIf
                ; Check if limit exceeded
                If Abs($nNumber) >= $iThreshold Then
                    Local $sAction = "BUY"
                    Local $iColour = 0xFF8000
                    If StringLeft($aCurrArray[$i][2], 1) = "-" Then
                        $sAction = "SELL"
                        $iColour = 0xFFFF00
                    EndIf
                    Show_Alert($sAction, $i, $iColour)
                EndIf
            EndIf
        Else
            ; We have reached the top line of the last array so stop checking
            ExitLoop
        EndIf

    Next

EndFunc   ;==>Check_Values

#endregion ; ----- Check values -----
#region ; ----- Show_Alert -----

Func Show_Alert($sAction, $iIndex, $iColour)

    ; Create Alert GUI
    Local $hAlert = GUICreate("New Trade at " & $aCurrArray[$iIndex][0], 500, 160, Default, Default, BitOR($WS_POPUPWINDOW, $WS_CAPTION), $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle()))
    GUISetBkColor($iColour, $hAlert)
    GUICtrlCreateLabel("", 10, 10, 480, 100, $SS_CENTER)
    GUICtrlSetBkColor(-1, $iColour)
    GUICtrlSetFont(-1, 24)
    GUICtrlSetData(-1, "NEW TRADE" & @CRLF & "YOU " & $sAction & " " & $aCurrArray[$iIndex][1] & " : " & $aCurrArray[$iIndex][2])
    Local $hButton = GUICtrlCreateButton("OK", 210, 120, 80, 30, $BS_DEFPUSHBUTTON)
    GUISetState()

    Beep(500, 500)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $hButton
                GUIDelete($hAlert)
                Return
        EndSwitch
    WEnd

EndFunc   ;==>Show_Alert

#endregion ; ----- Show_Alert -----
#region ; ----- On Limits -----

Func On_Limits()

    Local $aLimits[4][3]

    ; Read current limits
    $aLimits[0][1] = IniRead($sIniFile, "Limits", "AG", "Not Set")
    $aLimits[1][1] = IniRead($sIniFile, "Limits", "AU", "Not Set")
    $aLimits[2][1] = IniRead($sIniFile, "Limits", "PD", "Not Set")
    $aLimits[3][1] = IniRead($sIniFile, "Limits", "PT", "Not Set")

    ; Create GUI
    Local $hLimits = GUICreate("Set Limits", 220, 190)
    GUICtrlCreateLabel("Metal" & @TAB & "Ounces" & @TAB & @TAB & "Kilos", 10, 10, 280, 20)
    GUICtrlCreateLabel("AG", 10, 30, 30, 20)
    GUICtrlCreateLabel("AU", 10, 60, 30, 20)
    GUICtrlCreateLabel("PD", 10, 90, 30, 20)
    GUICtrlCreateLabel("PT", 10, 120, 30, 20)
    ; Create inputs
    $aLimits[0][0] = GUICtrlCreateInput($aLimits[0][1], 50, 30, 70, 20)
    $aLimits[1][0] = GUICtrlCreateInput($aLimits[1][1], 50, 60, 70, 20)
    $aLimits[2][0] = GUICtrlCreateInput($aLimits[2][1], 50, 90, 70, 20)
    $aLimits[3][0] = GUICtrlCreateInput($aLimits[3][1], 50, 120, 70, 20)
    ; Show kilo equivalents
    For $i = 0 To 3
        If $aLimits[$i][1] = "Not Set" Then
            $aLimits[$i][2] = GUICtrlCreateLabel("Not Set", 130, 30 * ($i + 1), 70, 20)
        Else
            $aLimits[$i][2] = GUICtrlCreateLabel(Round($aLimits[$i][0] / $nConvFactor, 7), 130, 30 * ($i + 1), 70, 20)
        EndIf
    Next
    Local $hAccept_Button = GUICtrlCreateButton("Accept", 130, 150, 80, 30)
    Local $hCancel_Button = GUICtrlCreateButton("Cancel", 10, 150, 80, 30)

    GUISetState(@SW_SHOW, $hLimits)

    While 1

        Switch GUIGetMsg()
            Case $hAccept_Button
                ; Read required limits
                For $i = 0 To 3
                    $aLimits[$i][1] = GUICtrlRead($aLimits[$i][0])
                Next
                ; Write limits to ini file
                IniWrite($sIniFile, "Limits", "AG", $aLimits[0][1])
                IniWrite($sIniFile, "Limits", "AU", $aLimits[1][1])
                IniWrite($sIniFile, "Limits", "PD", $aLimits[2][1])
                IniWrite($sIniFile, "Limits", "PT", $aLimits[3][1])
                ContinueCase
            Case $GUI_EVENT_CLOSE, $hCancel_Button
                GUIDelete($hLimits)
                Return
        EndSwitch

        ; Keep kilo values synchronised with ounce inputs
        For $i = 0 To 3
            Local $nKVal = Round(GUICtrlRead($aLimits[$i][0]) / $nConvFactor, 7)
            If GUICtrlRead($aLimits[$i][2]) <> $nKVal Then GUICtrlSetData($aLimits[$i][2], $nKVal)
        Next

    WEnd

EndFunc   ;==>On_Limits

#endregion ; ----- On Limits -----
#region ; ----- On_About -----

Func On_About()

    Local $sMsg = "fxddb v1.0" & @CRLF & "(c) Melba23 UK 2010" & @CRLF & @CRLF & _
            "This software is released as Freeware.  It is provided 'as-is', without any express or implied warranty.  " & _
            "In no event shall the author be held liable for any damages arising from the use of this software." & @CRLF & @CRLF & _
            "fxddb built using AutoIt v" & @AutoItVersion & @CRLF & "(www.autoitscript.com/autoit3)"
    MsgBox(64, "About fxddb", $sMsg)

EndFunc   ;==>On_About

#endregion ; ----- On_About -----
#region ; ----- On_Exit -----

Func On_Exit()
    Exit
EndFunc   ;==>On_Exit

#endregion ; ----- On_Exit -----

Let me know how it goes. :)

M23

P.S. PD = palladium?

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Feeling very virtuous after my exercise :)

P.S. PD = palladium?

Houh! You must have done Pilates or something similar or you've just done too much of sport. What did you do? A Marathon? :(

Yes PD = Palladium 461.50 / 463.50 $ per Oz at the mom.

Thanks for the final code. Good thing with the Kilo limit calculations! also the ability to amend them at the statusbar.

With the "About" I'm happy to see your name in there and the statement you've made inthere.

Will test the code now and let you know as soon there's a new line droping in. At the mom it's spinning..

Some question: What happens if

- I accidently move the appwindow of the FX Dealblotter during the code is running? ==> Reset of the + needed?

- another Window from a different app temporarily (5 seconds / 20 Seconds hides the dealblotter (partially/full)? ==>does it get stale?

- is it possible for autoIt so set the FxDealblotter Appwindow = allwaysOnTop

I hope you're feeling already better after your 4h of gym

Will Keep you updated.

1'000'0000 and more Thanks.

Jan

Link to comment
Share on other sites

  • Moderators

Jaenchen,

4hrs = trip to gym + gym + lunch + trip home + coding the required changes to the script. Gym itself is about 90 minutes of that :) - and that is quite long enough at my age! :D

Some question: What happens if

- I accidently move the appwindow of the FX Dealblotter during the code is running? ==> Reset of the + needed?

- another Window from a different app temporarily (5 seconds / 20 Seconds hides the dealblotter (partially/full)? ==>does it get stale?

- is it possible for autoIt so set the FxDealblotter Appwindow = allwaysOnTop

- At present the script will fail, but it is trivial to fix that. :)

- The script checks for updates every 10 secs. If it cannot read the window it will probably fail at present - I assumed you would not want to cover the window. I will have a think about what we can do to get over that.

- We can certainly try, but some windows are resistant to this. ;)

I will think over these points while I am waiting for you tell me if the script works in the wild. :(

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

M23

I'll make it short:

IT WORKS! Yeah! YOU ARE ABSOLUTELY GREAT!

4 Shure I'll make a donnation to the hosting costs of AutoIt (of course out of my personal pocket) and will do lobbying as much I can.

What do you think? Can you make the errorcatching for the "accidently moving" window. The rest I think, the user can live with. Especially if we have 3 Users running all your script, so the chance it quite low that it fails 3 times at the same time on 3 diff workstations.

Take a break, relax! You've done a very good work! Also in the documentation/commention of the code. That's real professional work!

You deserve my respectful!

Jan

Edited: Just found out, that we should have the abortion of the app put to something else than {ESC} maybe {CTRL}+{ESC} otherwise it may exit accidently

Edited by Jaenchen
Link to comment
Share on other sites

  • Moderators

Jaenchen,

:):);)

I am really pleased to hear that! it has been a fun project!

Here is a new version which can cope with being hidden (it just sulks in the corner :D ) and being moved (it relocates the app window each time it tries to read it). Of course, you get no updates while the app is hidden.

#region ; ----- Includes -----

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <StaticConstants.au3>
#include <Array.au3>
#include <Misc.au3>
#include <WinAPI.au3>

#endregion ; ----- Includes -----
; ############# fxddb #############
;
; Reading from the FX daily deal blotter
;
; Initial release
;
; Script Version: 1.0.0.0
;   As at 23 Mar 10
;
#region ; ----- Get App handle -----

; Get handle of app window
Global $iOldMode = Opt("WinTitleMatchMode", 2)
Global $hGUI = WinGetHandle("FX daily deal blotter")
If @error Then
    MsgBox(16, "fxddb Disaster!", "Cannot find the window!")
    Exit
EndIf
Opt("WinTitleMatchMode", $iOldMode)

#endregion ; ----- Get App handle -----
#region ; ----- Declarations -----

; Array of digit and sign codes
Global $aChecks[12] = [ _
        "011110100001100001100001100001100001100001100001100001011110", _
        "000100001100010100000100000100000100000100000100000100000100", _
        "011110100001000001000001000001000010000100001000010000111111", _
        "011110100001000001000001001110000001000001000001100001011110", _
        "000010000110000110001010001010010010010010111111000010000010", _
        "011111010000010000100000111110100001000001000001100001011110", _
        "011110100001100000100000101110110001100001100001100001011110", _
        "111111000010000010000100000100001000001000010000010000010000", _
        "011110100001100001100001011110100001100001100001100001011110", _
        "011110100001100001100001100011011101000001000001100010011100", _
        "000000000000000100000100000100111111000100000100000100000000", _
        "000000000000000000000000000000000000000111000000000000000000"]

; Array of Curr.1 letter edges (D, G, T, U)
Global $aCurr[4] = [ _
        "1111111111", _
        "0011111100", _
        "1000000000", _
        "1111111100"]

; Array to hold numbers read from app
Global $aCurrArray[15][3], $aOldArray[15][3]

; Find position of the app window
Global $aAppPos = WinGetPos($hGUI)

; Coords of the 2 points user will mark
Global $iX_Cross_1, $iY_Cross_1, $iX_Cross_2, $iY_Cross_2, $iX_Colon = -1, $iX_3Letter

; Checksum of top line
Global $iChecksum

; Struct for window visible check
Global $tPOINT = DllStructCreate("int X;int Y")

; Conversion from kilos to ounces
Global $nConvFactor = 32.1507425

#endregion ; ----- Declarations -----
#region ; ----- Determine ini path

Global $sIniFile

; Determine location for ini file
If @ScriptDir = @ProgramFilesDir Then
    ; If app in C:\Program Files need to save elsewhere
    If Not FileExists(@AppDataDir & "\fxddb") Then DirCreate(@AppDataDir & "\fxddb")
    $sIniFile = @AppDataDir & "\fxddb\fxddb.ini"
Else
    ; Can use app folder
    $sIniFile = @ScriptDir & "\fxddb.ini"
EndIf

IniReadSection($sIniFile, "Limits")
If @error Then
    MsgBox(48, "fxddb Alert", "No transaction limits have been set" & @CRLF & "Please set them now")
    On_Limits()
EndIf

#endregion ; ----- Determine ini path
#region ; ----- Tray menu -----

Opt("TrayOnEventMode", 1) ; Use event trapping for tray menu
Opt("TrayMenuMode", 3) ; Default tray menu items will not be shown.

; Create tray menu
TrayCreateItem("Set Limits")
TrayItemSetOnEvent(-1, "On_Limits")
TrayCreateItem("")
TrayCreateItem("About")
TrayItemSetOnEvent(-1, "On_About")
TrayCreateItem("")
TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "On_Exit")

#endregion ; ----- Tray menu -----
#region ; ----- Initialisation -----

; Get user to mark the points
Mark_Cross()

; Get base window handle
DllStructSetData($tPOINT, "X", $aAppPos[0] + $iX_Cross_1)
DllStructSetData($tPOINT, "Y", $aAppPos[1] + $iY_Cross_1)
$hHandle = _WinAPI_WindowFromPoint($tPOINT)

; Read the numbers in GMT, Curr.1 and Amount1 columns to set the base array
Read_Values()
$aOldArray = $aCurrArray

; Set the original checksum for the top line
Global $iCurrChecksum = PixelChecksum($aAppPos[0], $iY_Cross_1 + 3, $aAppPos[0] + $aAppPos[2], $iY_Cross_1 + 13)

#endregion ; ----- Initialisation -----
#region ; ----- Main loop -----

; Now start infinite loop
While 1

    ; Check position of the app
    $aAppPos = WinGetPos($hGUI)

    ; Check if app is visible
    DllStructSetData($tPOINT, "X", $aAppPos[0] + $iX_Cross_1)
    DllStructSetData($tPOINT, "Y", $aAppPos[1] + $iY_Cross_1)
    If _WinAPI_WindowFromPoint($tPOINT) = $hHandle Then

        ; Check if the top line has changed
        $iChecksum = PixelChecksum($aAppPos[0], $aAppPos[1] + $iY_Cross_1 + 3, $aAppPos[0] + $aAppPos[2], $aAppPos[1] + $iY_Cross_1 + 13)
        If $iChecksum <> $iCurrChecksum Then

            ; Retain new checksum for future checks
            $iCurrChecksum = $iChecksum

            ; Read the values in GMT, Curr.1 and Amount1 columns
            Read_Values()

            ; Check the new values and send any necessary alerts
            Check_Values()

            ; All warnings sent so replace $aOldArray
            $aOldArray = $aCurrArray

        EndIf
    EndIf

    ; Idle 10 Secs before relooping
    Sleep(10000)

WEnd

; ~~~~~ Functions ~~~~~

#endregion ; ----- Main loop -----
#region ; ----- Read_Values -----

Func Read_Values()

    ; Coords of zones to check for digit/sign
    Local $aX_Coords_1[4] = [-15, -8, 3, 10]
    Local $aX_Coords_2[9] = [65, 58, 51, 47, 40, 33, 26, 15, 8]
    Local $iY_Coord = $aAppPos[1] + $iY_Cross_1 + 3

    ; Reset array
    Global $aCurrArray[15][3]

    ; Find colon if not yet set
    If $iX_Colon = -1 Then Find_Colon($iY_Coord)

    ; Move down line by line
    For $iY_Index = 0 To 14

        Local $iBackgroundColour = Hex(PixelGetColor($aAppPos[0] + $iX_Cross_1 - 1, $iY_Coord + ($iY_Index * 16) + 1), 6)

        ; Start in the GMT column

        ; Zero the code
        Local $sCode = ""

        ; Set the x-coord for this column
        Local $iX_Coord = $aAppPos[0] + $iX_Colon

        ; Move through the digit/sign spaces from left
        For $iX_Index = 0 To 3

            ; Move through the space to build the code
            Local $sString = ""
            For $y = 0 To 9
                For $x = 0 To 5
                    $sString &= Read_Pixel($iX_Coord + $aX_Coords_1[$iX_Index] + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
                Next
            Next

            ; Check in the index for a match
            Local $iIndex = _ArraySearch($aChecks, $sString)

            ; Add the correct digit/sign to the list
            Switch $iIndex
                Case 0 To 9
                    $sCode &= $iIndex
            EndSwitch

            ; Add colon in correct place
            If $iX_Index = 1 Then $sCode &= ":"

        Next

        ; Check if we have reached the end of entries
        If $sCode = ":" Then ExitLoop

        ; Store the GMT
        $aCurrArray[$iY_Index][0] = $sCode

        ; Now move on to Curr.1 column

        ; Determine the first letter and the X-Coord for the third letter
        Local $aLetters = Find_Letters($iY_Coord, $iY_Index, $iBackgroundColour)
        $iX_3Letter = $aLetters[1]

        ; To distinguish between the possible values, we need only look at the left edge of the 3rd letter
        Local $iX_Curr = $aAppPos[0] + $iX_Cross_1 + $iX_3Letter

        ; Read the edge line
        $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($iX_Curr, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
        Next

        ; Check in the index for a match and write to the array
        $iIndex = _ArraySearch($aCurr, $sString)
        Switch $iIndex
            Case 0
                $aCurrArray[$iY_Index][1] = $aLetters[0] & "PD"
            Case 1
                $aCurrArray[$iY_Index][1] = $aLetters[0] & "AG"
            Case 2
                $aCurrArray[$iY_Index][1] = $aLetters[0] & "PT"
            Case 3
                $aCurrArray[$iY_Index][1] = $aLetters[0] & "AU"
        EndSwitch

        ; Now move on to the Amount1 column

        ; Set base x-coord
        $iX_Coord = $aAppPos[0] + $iX_Cross_2

        ; Zero the code
        $sCode = ""

        ; Move through the digit/sign spaces from left
        For $iX_Index = 0 To 8

            ; Move through the space
            $sString = ""
            For $y = 0 To 9
                For $x = 0 To 5
                    $sString &= Read_Pixel($iX_Coord - $aX_Coords_2[$iX_Index] + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
                Next
            Next

            ; Check in the index for a match
            $iIndex = _ArraySearch($aChecks, $sString)

            ; Add the correct digit/sign to the list
            Switch $iIndex
                Case 0 To 9
                    $sCode &= $iIndex
                Case 10
                    $sCode &= "+"
                Case 11
                    $sCode &= "-"
            EndSwitch

            If $iX_Index = 2 Then
                ; If we did not find a digit at the thousands point, check for a sign
                ; If we did, add a comma
                If $iIndex > 0 Then
                    $iX_Index = 3
                    $sCode &= ","
                EndIf
            EndIf

            ; Add the decimal at the correct point
            If $iX_Index = 6 Then $sCode &= "."

        Next

        ; Store the Amount 1
        $aCurrArray[$iY_Index][2] = $sCode

    Next

EndFunc   ;==>Read_Values

#endregion ; ----- Read_Values -----
#region ; ----- Find_Colon -----

Func Find_Colon($iY_Coord)

    ; Check colour of background
    Local $iBackgroundColour = Hex(PixelGetColor($aAppPos[0] + $iX_Cross_1 - 1, $iY_Coord), 6)

    ; Move across app window to find colon
    For $x = $aAppPos[0] + $iX_Cross_1 To $aAppPos[0] Step -1
        Local $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($x, $iY_Coord + $y, $iBackgroundColour)
        Next
        ; Found it
        If $sString = "0001000001" Then ExitLoop
    Next

    ; Set the coordinate to the colon
    $iX_Colon = $x - $aAppPos[0]

EndFunc   ;==>Find_Colon

#endregion ; ----- Find_Colon -----
#region ; ----- Find Letter -----

Func Find_Letters($iY_Coord, $iY_Index, $iBackgroundColour)

    ; Move across app to ID first letter
    Local $aRet[2]
    For $x = 2 To 10
        Local $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($aAppPos[0] + $iX_Cross_1 + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
        Next
        Switch $sString
            ; If blank keep going to find start of letter
            Case "0000000000"
                ContinueLoop
                ; If X Then ExitLoop to find 3rd letter
            Case "1000000001"
                $aRet[0] = "X"
                ExitLoop
            Case Else
                $aRet[0] = "K"
                ExitLoop
        EndSwitch
    Next

    Local $fBlank = False
    ; Move across app window to find third letter
    For $x = 15 To 30
        $sString = ""
        For $y = 0 To 9
            $sString &= Read_Pixel($aAppPos[0] + $iX_Cross_1 + $x, $iY_Coord + ($iY_Index * 16) + $y, $iBackgroundColour)
        Next
        Switch $fBlank
            Case False
                ; Check for blank line
                If $sString = "0000000000" Then $fBlank = True
            Case True
                ; Check for beginning of letter
                If $sString <> "0000000000" Then ExitLoop
        EndSwitch
    Next

    ; We now have the cordinate to the left edge of the third letter
    $aRet[1] = $x
    Return $aRet

EndFunc   ;==>Find_Letters

#endregion ; ----- Find Letter -----
#region ; ----- Read_ Pixel -----

Func Read_Pixel($iX_Pixel, $iY_Pixel, $iBackgroundColour)

    Local $sColour = Hex(PixelGetColor($iX_Pixel, $iY_Pixel), 6)
    ; If pixel colour is not the background colour - set the code
    If $sColour <> $iBackgroundColour Then
        Return "1"
    Else
        Return "0"
    EndIf

EndFunc   ;==>Read_Pixel

#endregion ; ----- Read_ Pixel -----
#region ; ----- Mark_Cross -----

Func Mark_Cross()

    ; Open dll for _IsPressed
    Local $UserDLL = DllOpen("user32.dll")

    For $i = 1 To 3

        ; Read ini values for GMT cross intial position
        Local $iX_Start = IniRead($sIniFile, "GMT Cross", "X-Coord", 45) + $aAppPos[0]
        Local $iY_Start = IniRead($sIniFile, "GMT Cross", "Y-Coord", 100) + $aAppPos[1]

        ; Set GMT cross
        Local $aRet = Move_Cross($iX_Start, $iY_Start, "fxddb_Splash_1.jpg", $UserDLL)
        $iX_Cross_1 = $aRet[0]
        $iY_Cross_1 = $aRet[1]

        Local $iCheckSum_1 = PixelChecksum($iX_Cross_1 - 1, $iY_Cross_1 - 1, $iX_Cross_1 + 1, $iY_Cross_1)
        
        ; Read ini values for Amount1 cross intial position
        $iX_Start = IniRead($sIniFile, "Amount1 Cross", "X-Coord", 200) + $aAppPos[0]
        $iY_Start = IniRead($sIniFile, "Amount1 Cross", "Y-Coord", 100) + $aAppPos[1]

        ; Set Amount1 cross
        $aRet = Move_Cross($iX_Start, $iY_Start, "fxddb_Splash_2.jpg", $UserDLL)
        $iX_Cross_2 = $aRet[0]
        $iY_Cross_2 = $aRet[1]

        Local $iCheckSum_2 = PixelChecksum($iX_Cross_2 - 1, $iY_Cross_2 - 1, $iX_Cross_2 + 1, $iY_Cross_2)
        
        ; Check for confirmation of correct positioning
        If $iY_Cross_1 <> $iY_Start And $iY_Cross_1 = $iY_Cross_2 Then
            
            ; Set coords relative to the app window
            $iX_Cross_1 -= $aAppPos[0]
            $iY_Cross_1 -= $aAppPos[1]
            $iX_Cross_2 -= $aAppPos[0]
            $iY_Cross_2 -= $aAppPos[1]

            ; Save values 1 pixel off
            IniWrite($sIniFile, "GMT Cross", "X-Coord", $iX_Cross_1 - 1)
            IniWrite($sIniFile, "GMT Cross", "Y-Coord", $iY_Cross_1 - 1)
            IniWrite($sIniFile, "Amount1 Cross", "X-Coord", $iX_Cross_2 - 1)
            IniWrite($sIniFile, "Amount1 Cross", "Y-Coord", $iY_Cross_2 - 1)
            ; Close dll
            DllClose($UserDLL)
            Return
        Else
            If $i = 3 Then
                MsgBox(16, "fxddb Error", "If you do not want to set me up properly then I am not going to play!")
                Exit
            Else
                MsgBox(48, "fxddb Error", "The crosses were not properly positioned" & @CRLF & "Please try again")
            EndIf
        EndIf

        While _IsPressed("0D", $UserDLL)
            Sleep(10)
        WEnd

    Next

EndFunc   ;==>Mark_Cross

#endregion ; ----- Mark_Cross -----
#region ; ----- Move_Cross -----

Func Move_Cross($iX_Mark, $iY_Mark, $sImage, $UserDLL)

    Local $aRet[2]

    ; Determine location of example GUI
    Local $iX_Loc = $aAppPos[0] - 250
    If $aAppPos[0] < 300 Then $iX_Loc = $aAppPos[0] + $aAppPos[2]
    Local $iY_Loc = $aAppPos[1] + 100

    ; Create example GUI
    Local $hExampleGUI = GUICreate("Place the cross here", 250, 96, $iX_Loc, $iY_Loc, $WS_POPUPWINDOW, -1, WinGetHandle(AutoItWinGetTitle()))
    GUICtrlCreateLabel("Place cross on intersection in centre of circle", 0, 0, 250, 20, BitOR($SS_CENTER, $SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFFFF00)
    GUICtrlCreatePic($sImage, 0, 20, 250, 76)
    GUISetState()

    ; Create transparent GUI over the app with Cross cursor
    Local $hCross_GUI = GUICreate("Test", $aAppPos[2], $aAppPos[3], $aAppPos[0], $aAppPos[1], $WS_POPUP, $WS_EX_TOPMOST)
    WinSetTrans($hCross_GUI, "", 8)
    GUISetState(@SW_SHOW, $hCross_GUI)
    GUISetCursor(3, 1, $hCross_GUI)

    MouseMove($iX_Mark, $iY_Mark, 0)

    ; Wait for adjustments or confirmation
    While 1
        If _IsPressed("25", $UserDLL) Then
            $iX_Mark -= 1
            While _IsPressed("25", $UserDLL)
                Sleep(10)
            WEnd
        EndIf
        If _IsPressed("26", $UserDLL) Then
            $iY_Mark -= 1
            While _IsPressed("26", $UserDLL)
                Sleep(10)
            WEnd
        EndIf
        If _IsPressed("27", $UserDLL) Then
            While _IsPressed("27", $UserDLL)
                Sleep(10)
            WEnd
            $iX_Mark += 1
        EndIf
        If _IsPressed("28", $UserDLL) Then
            While _IsPressed("28", $UserDLL)
                Sleep(10)
            WEnd
            $iY_Mark += 1
        EndIf
        If _IsPressed("0D", $UserDLL) Then
            While _IsPressed("0D", $UserDLL)
                Sleep(10)
            WEnd
            $aRet[0] = $iX_Mark
            $aRet[1] = $iY_Mark
            GUIDelete($hCross_GUI)
            GUIDelete($hExampleGUI)
            Return $aRet
        EndIf

        MouseMove($iX_Mark, $iY_Mark)

    WEnd

EndFunc   ;==>Move_Cross

#endregion ; ----- Move_Cross -----
#region ; ----- Check values -----

Func Check_Values()

    Local $iThreshold

    For $i = 0 To 14

        Local $sNewLine = $aCurrArray[$i][0] & $aCurrArray[$i][1] & $aCurrArray[$i][2]
        Local $sOldTopLine = $aOldArray[0][0] & $aOldArray[0][1] & $aOldArray[0][2]

        If $sNewLine <> $sOldTopLine Then
            ; New line so get code
            If $aCurrArray[$i][1] = "Other" Then
                Show_Alert("ALERT", $i, 0x80FF80)
            Else
                Local $nNumber = Number(StringReplace($aCurrArray[$i][2], ",", ""))
                ; Convert to ounces if necessary
                If StringLeft($aCurrArray[$i][1], 1) = "K" Then $nNumber *= $nConvFactor
                ; Set Threshold value
                Switch StringRight($aCurrArray[$i][1], 2)
                    Case "AG"
                        $iThreshold = IniRead($sIniFile, "Limits", "AG", "Error")
                    Case "AU"
                        $iThreshold = IniRead($sIniFile, "Limits", "AU", "Error")
                    Case "PD"
                        $iThreshold = IniRead($sIniFile, "Limits", "PD", "Error")
                    Case "PT"
                        $iThreshold = IniRead($sIniFile, "Limits", "PT", "Error")
                EndSwitch
                ; Check we have valid limits
                If $iThreshold = "Error" Then
                    MsgBox(16, "fxddb Error", "Limits are invalid" & @CRLF & "Please reset the limit values and restart!")
                    On_Limits()
                    Exit
                EndIf
                ; Check if limit exceeded
                If Abs($nNumber) >= $iThreshold Then
                    Local $sAction = "BUY"
                    Local $iColour = 0xFF8000
                    If StringLeft($aCurrArray[$i][2], 1) = "-" Then
                        $sAction = "SELL"
                        $iColour = 0xFFFF00
                    EndIf
                    Show_Alert($sAction, $i, $iColour)
                EndIf
            EndIf
        Else
            ; We have reached the top line of the last array so stop checking
            ExitLoop
        EndIf

    Next

EndFunc   ;==>Check_Values

#endregion ; ----- Check values -----
#region ; ----- Show_Alert -----

Func Show_Alert($sAction, $iIndex, $iColour)

    ; Create Alert GUI
    Local $hAlert = GUICreate("New Trade at " & $aCurrArray[$iIndex][0], 500, 160, Default, Default, BitOR($WS_POPUPWINDOW, $WS_CAPTION), $WS_EX_TOPMOST, WinGetHandle(AutoItWinGetTitle()))
    GUISetBkColor($iColour, $hAlert)
    GUICtrlCreateLabel("", 10, 10, 480, 100, $SS_CENTER)
    GUICtrlSetBkColor(-1, $iColour)
    GUICtrlSetFont(-1, 24)
    GUICtrlSetData(-1, "NEW TRADE" & @CRLF & "YOU " & $sAction & " " & $aCurrArray[$iIndex][1] & " : " & $aCurrArray[$iIndex][2])
    Local $hButton = GUICtrlCreateButton("OK", 210, 120, 80, 30, $BS_DEFPUSHBUTTON)
    GUISetState()

    Beep(500, 500)

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE, $hButton
                GUIDelete($hAlert)
                Return
        EndSwitch
    WEnd

EndFunc   ;==>Show_Alert

#endregion ; ----- Show_Alert -----
#region ; ----- On Limits -----

Func On_Limits()

    Local $aLimits[4][3]

    ; Read current limits
    $aLimits[0][1] = IniRead($sIniFile, "Limits", "AG", "Not Set")
    $aLimits[1][1] = IniRead($sIniFile, "Limits", "AU", "Not Set")
    $aLimits[2][1] = IniRead($sIniFile, "Limits", "PD", "Not Set")
    $aLimits[3][1] = IniRead($sIniFile, "Limits", "PT", "Not Set")

    ; Create GUI
    Local $hLimits = GUICreate("Set Limits", 220, 190)
    GUICtrlCreateLabel("Metal" & @TAB & "Ounces" & @TAB & @TAB & "Kilos", 10, 10, 280, 20)
    GUICtrlCreateLabel("AG", 10, 30, 30, 20)
    GUICtrlCreateLabel("AU", 10, 60, 30, 20)
    GUICtrlCreateLabel("PD", 10, 90, 30, 20)
    GUICtrlCreateLabel("PT", 10, 120, 30, 20)
    ; Create inputs
    $aLimits[0][0] = GUICtrlCreateInput($aLimits[0][1], 50, 30, 70, 20)
    $aLimits[1][0] = GUICtrlCreateInput($aLimits[1][1], 50, 60, 70, 20)
    $aLimits[2][0] = GUICtrlCreateInput($aLimits[2][1], 50, 90, 70, 20)
    $aLimits[3][0] = GUICtrlCreateInput($aLimits[3][1], 50, 120, 70, 20)
    ; Show kilo equivalents
    For $i = 0 To 3
        If $aLimits[$i][1] = "Not Set" Then
            $aLimits[$i][2] = GUICtrlCreateLabel("Not Set", 130, 30 * ($i + 1), 70, 20)
        Else
            $aLimits[$i][2] = GUICtrlCreateLabel(Round($aLimits[$i][0] / $nConvFactor, 7), 130, 30 * ($i + 1), 70, 20)
        EndIf
    Next
    Local $hAccept_Button = GUICtrlCreateButton("Accept", 130, 150, 80, 30)
    Local $hCancel_Button = GUICtrlCreateButton("Cancel", 10, 150, 80, 30)

    GUISetState(@SW_SHOW, $hLimits)

    While 1

        Switch GUIGetMsg()
            Case $hAccept_Button
                ; Read required limits
                For $i = 0 To 3
                    $aLimits[$i][1] = GUICtrlRead($aLimits[$i][0])
                Next
                ; Write limits to ini file
                IniWrite($sIniFile, "Limits", "AG", $aLimits[0][1])
                IniWrite($sIniFile, "Limits", "AU", $aLimits[1][1])
                IniWrite($sIniFile, "Limits", "PD", $aLimits[2][1])
                IniWrite($sIniFile, "Limits", "PT", $aLimits[3][1])
                ContinueCase
            Case $GUI_EVENT_CLOSE, $hCancel_Button
                GUIDelete($hLimits)
                Return
        EndSwitch

        ; Keep kilo values synchronised with ounce inputs
        For $i = 0 To 3
            Local $nKVal = Round(GUICtrlRead($aLimits[$i][0]) / $nConvFactor, 7)
            If GUICtrlRead($aLimits[$i][2]) <> $nKVal Then GUICtrlSetData($aLimits[$i][2], $nKVal)
        Next

    WEnd

EndFunc   ;==>On_Limits

#endregion ; ----- On Limits -----
#region ; ----- On_About -----

Func On_About()

    Local $sMsg = "fxddb v1.0" & @CRLF & "(c) Melba23 UK 2010" & @CRLF & @CRLF & _
            "This software is released as Freeware.  It is provided 'as-is', without any express or implied warranty.  " & _
            "In no event shall the author be held liable for any damages arising from the use of this software." & @CRLF & @CRLF & _
            "fxddb built using AutoIt v" & @AutoItVersion & @CRLF & "(www.autoitscript.com/autoit3)"
    MsgBox(64, "About fxddb", $sMsg)

EndFunc   ;==>On_About

#endregion ; ----- On_About -----
#region ; ----- On_Exit -----

Func On_Exit()
    Exit
EndFunc   ;==>On_Exit

#endregion ; ----- On_Exit -----

I have removed the HotKey to exit - Windows uses too many Modifier+Esc key combinations already and we have the tray icon menu to exit gracefully now.

Now, would you be interested in the single compiled exe version with the example images stored inside? It would not be difficult to do - just let me know.

I'll make a donnation to the hosting costs of AutoIt

That is extremely generous and I am sure Jon (the owner and original author of AutoIt) woudl be most grateful. :(

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

:):);)

Now, would you be interested in the single compiled exe version with the example images stored inside? It would not be difficult to do - just let me know.

That is extremely generous and I am sure Jon (the owner and original author of AutoIt) woudl be most grateful. :(

Of course I'm interested to learn on how to compile it to a single exe containing also the images stored in it.

You are verry welcome! And of course just let me know if I can help you with anything else (except "DATA DVDs") :D

Have a great evening!

Jan

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...