Terenz

File size conversion and sum/subtract

5 posts in this topic

#1 ·  Posted (edited)

Hello guys,

Maybe a stupid problem but i can't solve it. A reproducer script:

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

Global $fItem = -1

$Form = GUICreate("Form1", 266, 233, 204, 144)
$ListView1 = GUICtrlCreateListView("AAA", 8, 8, 250, 150, -1, BitOR($WS_EX_CLIENTEDGE, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT))
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 100)

$hListView = GUICtrlGetHandle($ListView1)

$ListView1_0 = GUICtrlCreateListViewItem("7.03_MB", $ListView1)
$ListView1_1 = GUICtrlCreateListViewItem("317_byte", $ListView1)
$ListView1_2 = GUICtrlCreateListViewItem("113.30_KB", $ListView1)
$ListView1_3 = GUICtrlCreateListViewItem("36.61_KB", $ListView1)
$ListView1_4 = GUICtrlCreateListViewItem("5.97_MB", $ListView1)
$Label = GUICtrlCreateLabel("10000000", 8, 168)

_GUICtrlListView_SetItemChecked($ListView1, 0)
_GUICtrlListView_SetItemChecked($ListView1, 1)
_GUICtrlListView_SetItemChecked($ListView1, 2)
_GUICtrlListView_SetItemChecked($ListView1, 3)
_GUICtrlListView_SetItemChecked($ListView1, 4)

$a = _Convert("7.03_MB")
$b = _Convert("317_BYTE")
$c = _Convert("113.30_KB")
$d = _Convert("36.61_KB")
$e = _Convert("5.97_MB")
GUICtrlSetData($Label, _Final($a + $b + $c + $d + $e))

GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    If $fItem <> -1 Then
        _Func($fItem)
        $fItem = -1
    EndIf ;==>
WEnd

Func _Func($fItem)
    $sTest = _GUICtrlListView_GetItemChecked($ListView1, $fItem)
    If $sTest = False Then
        $y = _Convert(_GUICtrlListView_GetItemText($ListView1, $fItem))
        $z = _Convert(GUICtrlRead($Label))
        GUICtrlSetData($Label, _Final($z-$y))
    Else
        $y = _Convert(_GUICtrlListView_GetItemText($ListView1, $fItem))
        $z = _Convert(GUICtrlRead($Label))
        GUICtrlSetData($Label, _Final($z+$y))
    EndIf
EndFunc

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
                    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    Local $iItem = DllStructGetData($tInfo, "Index")
                    $fItem = $iItem
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _Convert($sNumber)
    Switch StringRight($sNumber, 2)
        Case "GB"
            Return StringRegExpReplace(StringTrimRight($sNumber, 3) * 1073741824, "(\.\d{2}).*", "$1")
        Case "MB"
            Return StringRegExpReplace(StringTrimRight($sNumber, 3) * 1048576, "(\.\d{2}).*", "$1")
        Case "KB"
            Return StringRegExpReplace(StringTrimRight($sNumber, 3) * 1024, "(\.\d{2}).*", "$1")
        Case Else
            Return StringRegExpReplace(StringTrimRight($sNumber, 5), "(\.\d{2}).*", "$1")
    EndSwitch
EndFunc   ;==>_Convert

Func _Final($iSize)
    Select
        Case $iSize >= 1073741824
            Return StringRegExpReplace($iSize / 1073741824, "(\.\d{2}).*", "$1") & "_GB"
        Case $iSize >= 1048576
            Return StringRegExpReplace($iSize / 1048576, "(\.\d{2}).*", "$1") & "_MB"
        Case $iSize >= 1024
            Return StringRegExpReplace($iSize / 1024, "(\.\d{2}).*", "$1") & "_KB"
        Case $iSize >= 0
            Return StringRegExpReplace($iSize, "(\.\d{2}).*", "$1") & "_BYTE"
    EndSelect
EndFunc   ;==>_Final

Yes, is not "perfect" ( like the click on the checkbox and not on the text!) but it just reproduce the problem. I have a list of size, MB-GB-KB-BYTE i want to add-subtract that value in a label of the total size...easy? Seems not

Example, start it and uncheck the 5.97_MB, the label become 7.17_MB, if i click again 5.97_MB the label come back to 13.14_MB, until here is working

Again, lauch it and uncheck the 113.30_KB...the label become 13.02_MB, click it again and then become 13.13_MB, unclick 13.01_MB, click 13.12_MB and so on..always the wrong value and still decreasing

What are my (many) mistakes? Thanks

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I think StringRegExpReplace

( StringTrimRight ( $sNumber , 3 ) * 1073741824 , "(.

d{2}).*" , "$1" )

rounds the number.

'I am not good at stringRegExp'

Store the value in a different variable without rounding it.

Like $actual_size= StringTrimRight ( $sNumber , 3 ) * 1073741824

StringRegExpReplace

( $ actual_size , "(.

d{2}).*" , "$1" )

and instead of

_Convert ( GUICtrlRead ( $Label ))

use

_Convert ( $actual_size)

Edited by sdfaheemuddin

Share this post


Link to post
Share on other sites

I agree.  Rounding errors  are the problem.

Try this.

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

Global $fItem = -1
$Form = GUICreate("Form1", 266, 233, 204, 144)
$ListView1 = GUICtrlCreateListView("AAA", 8, 8, 250, 150, -1, BitOR($WS_EX_CLIENTEDGE, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT))
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 100)

$hListView = GUICtrlGetHandle($ListView1)

$ListView1_0 = GUICtrlCreateListViewItem("7.03_MB", $ListView1)
$ListView1_1 = GUICtrlCreateListViewItem("317_byte", $ListView1)
$ListView1_2 = GUICtrlCreateListViewItem("113.30_KB", $ListView1)
$ListView1_3 = GUICtrlCreateListViewItem("36.61_KB", $ListView1)
$ListView1_4 = GUICtrlCreateListViewItem("5.97_MB", $ListView1)
$Label = GUICtrlCreateLabel("10000000", 8, 168)

_GUICtrlListView_SetItemChecked($ListView1, -1) ;  -1 sets all items

$a = _Convert("7.03_MB")
$b = _Convert("317_BYTE")
$c = _Convert("113.30_KB")
$d = _Convert("36.61_KB")
$e = _Convert("5.97_MB")
GUICtrlSetData($Label,  _Final($a + $b + $c + $d + $e))

GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    If $fItem <> -1 Then
        _Func($fItem)
        $fItem = -1
    EndIf ;==>
WEnd

Func _Func($fItem)
    $sTest = _GUICtrlListView_GetItemChecked($ListView1, $fItem)
    $y = _Convert(_GUICtrlListView_GetItemText($ListView1, $fItem))
    $z = _Convert(GUICtrlRead($Label))
    If $sTest = False Then
        GUICtrlSetData($Label, _Final($z - $y))
    Else
        GUICtrlSetData($Label, _Final($z + $y))
    EndIf
EndFunc   ;==>_Func

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
                    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    Local $iItem = DllStructGetData($tInfo, "Index")
                    $fItem = $iItem
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _Convert($sNumber)
    Switch StringRight($sNumber, 2)
        Case "GB"
            Return $sNumber * 2 ^ 30
        Case "MB"
            Return $sNumber * 2 ^ 20
        Case "KB"
            Return $sNumber * 2 ^ 10
        Case Else
            Return $sNumber
    EndSwitch
EndFunc   ;==>_Convert

Func _Final($iSize)
    Select
        Case $iSize >= 1073741824
            Return Round($iSize / 1073741824, 2) & "_GB"
        Case $iSize >= 1048576
            Return Round($iSize / 1048576, 2) & "_MB"
        Case $iSize >= 1024
            Return Round($iSize / 1024, 2) & "_KB"
        Case $iSize >= 0
            Return Round($iSize, 2) & "_BYTE"
    EndSelect
EndFunc   ;==>_Final

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

There is a problem with Round. Example in this scenario:

$ListView1_0 = GUICtrlCreateListViewItem("2_GB", $ListView1)
$ListView1_1 = GUICtrlCreateListViewItem("211_byte", $ListView1)
$ListView1_2 = GUICtrlCreateListViewItem("4.84_KB", $ListView1)
$ListView1_3 = GUICtrlCreateListViewItem("46.45_KB", $ListView1)
$ListView1_4 = GUICtrlCreateListViewItem("0_Byte", $ListView1)

The total size reported is 2_GB, if i deselect the 2_GB the total size goes to 0 and isn't zero because there are other sizes. And another thing, that 2_GB isn't 2_GB but 1.99_GB ( information reported by Windows when you click on the proprieties ) for this reason i was using that regexp. Maybe the RegExp wasn't a good choice but with Round i'm still having problem :(

Another scenario:

$ListView1_0 = GUICtrlCreateListViewItem("7.03_MB", $ListView1)
$ListView1_1 = GUICtrlCreateListViewItem("113.24_KB", $ListView1)
$ListView1_2 = GUICtrlCreateListViewItem("36.62_KB", $ListView1)
$ListView1_3 = GUICtrlCreateListViewItem("5.97_MB", $ListView1)
$ListView1_4 = GUICtrlCreateListViewItem("3.39_KB", $ListView1)

Try to de-select all except 3.39_KB, the total size is 0 instead of 3.39_KB. I think i was clear enought, i need something "accurate" and the total result must be equal to the size selected ( and no other strange bug like decreasing total lol ) or i'm just losing time :D

Thanks again

Edited by Terenz

Nothing is so strong as gentleness. Nothing is so gentle as real strength

 

Share this post


Link to post
Share on other sites

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>

Global $fItem = -1
Global $actual_size

$Form = GUICreate("Form1", 266, 233, 204, 144)
$ListView1 = GUICtrlCreateListView("AAA", 8, 8, 250, 150, -1, BitOR($WS_EX_CLIENTEDGE, $LVS_EX_CHECKBOXES, $LVS_EX_FULLROWSELECT))
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 100)

$hListView = GUICtrlGetHandle($ListView1)

$ListView1_0 = GUICtrlCreateListViewItem("7.03_MB", $ListView1)
$ListView1_1 = GUICtrlCreateListViewItem("317_byte", $ListView1)
$ListView1_2 = GUICtrlCreateListViewItem("113.30_KB", $ListView1)
$ListView1_3 = GUICtrlCreateListViewItem("36.61_KB", $ListView1)
$ListView1_4 = GUICtrlCreateListViewItem("5.97_MB", $ListView1)
$Label = GUICtrlCreateLabel("10000000", 8, 168)

_GUICtrlListView_SetItemChecked($ListView1, 0)
_GUICtrlListView_SetItemChecked($ListView1, 1)
_GUICtrlListView_SetItemChecked($ListView1, 2)
_GUICtrlListView_SetItemChecked($ListView1, 3)
_GUICtrlListView_SetItemChecked($ListView1, 4)

$a = _Convert("7.03_MB")
$b = _Convert("317_BYTE")
$c = _Convert("113.30_KB")
$d = _Convert("36.61_KB")
$e = _Convert("5.97_MB")
$actual_size=($a + $b + $c + $d + $e)
GUICtrlSetData($Label, _Final($actual_size))
GUISetState(@SW_SHOW)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
    If $fItem <> -1 Then
        _Func($fItem)
        $fItem = -1
    EndIf ;==>
WEnd

Func _Func($fItem)
    $sTest = _GUICtrlListView_GetItemChecked($ListView1, $fItem)
    If $sTest = False Then
        $y = _Convert(_GUICtrlListView_GetItemText($ListView1, $fItem))
        $actual_size-=$y
;~      MsgBox(0,$actual_size,$y)
        GUICtrlSetData($Label, _Final($actual_size))
    Else
        $y = _Convert(_GUICtrlListView_GetItemText($ListView1, $fItem))
        $actual_size+=$y
;~      MsgBox(0,$actual_size,$y)
        GUICtrlSetData($Label, _Final($actual_size))
    EndIf
EndFunc

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndListView
            Switch $iCode
                Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button
                    Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
                    Local $iItem = DllStructGetData($tInfo, "Index")
                    $fItem = $iItem
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _Convert($sNumber)
    Switch StringRight($sNumber, 2)
        Case "GB"
            Return StringTrimRight($sNumber, 3) * 2 ^ 30
         Case "MB"
            Return StringTrimRight($sNumber, 3) * 2 ^ 20
         Case "KB"
            Return StringTrimRight($sNumber, 3) * 2 ^ 10
         Case Else
            Return StringTrimRight($sNumber, 3)
    EndSwitch
EndFunc   ;==>_Convert

Func _Final($iSize)
    Select
        Case $iSize >= 2 ^ 30
            Return StringRegExpReplace($iSize / 1073741824, "(\.\d{2}).*", "$1") & "_GB"
        Case $iSize >= 2 ^ 20
            Return StringRegExpReplace($iSize / 1048576, "(\.\d{2}).*", "$1") & "_MB"
        Case $iSize >= 2 ^ 10
            Return StringRegExpReplace($iSize / 1024, "(\.\d{2}).*", "$1") & "_KB"
        Case $iSize >= 0
            Return StringRegExpReplace($iSize, "(\.\d{2}).*", "$1") & "_BYTE"
    EndSelect
EndFunc   ;==>_Final 

This is Working but with one error

 

Case $NM_CLICK ; Sent by a list-view control when the user clicks an item with the left mouse button

Even if i click just on an item, it sums up or subtracts

Share this post


Link to post
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