1 (изменено: Аскет, 2011-09-03 02:31:02)

Тема: HTA: Free RAM monitor

Продолжаю тему мониторинга ОС и ресурсов в частности.

На этот раз такая щепетильная составляющая как свободная оперативная память. Всегда полезно знать её размер.

http://img194.imageshack.us/img194/2404/freerammon.png

 <!-- Name:		Free_RAM_monitor.hta
	  Language:	HyperText Application
	  Author:	Аскет,	true-script@ya.ru
	  Description: This util displays 
															
 -->
 
 
 <HTML>
   <HEAD>
   <TITLE>Free RAM monitor v1.0</TITLE>
   <HTA:APPLICATION        ID="RamMon"        APPLICATIONNAME="RamMon"        BORDER="NONE"        BORDERSTYLE=""        SCROLL="NO"        SELECTION=NO        CAPTION="yes"        ICON="shell32.dll"       MAXIMIZEBUTTON="no"        MINIMIZEBUTTON="no"        SHOWINTASKBAR="no"        SINGLEINSTANCE="YES"       SYSMENU="NO"        VEотображаетRSION="1.0"        WINDOWSTATE="" />
 </HEAD>
 <meta author="Gorelov Alexander, July 2011">
 <script language=VBS>
	        Const WindowWidth = 85
        Const WindowHeight = 20
        window.resizeTo WindowWidth,WindowHeight
        window.moveTo screen.availWidth-122, screen.availHeight-100
</script>
 <style>
html, body{
   margin:0px;
   padding:0px;
   font:10;
   border-style: OUTset;
}
 </style>

   <BODY SCROLL="no" bgcolor="#88FFC4">
<!----------------------------->
<TABLE CELLSPACING="0" CELLPADDING="0"BORDER="0"WIDTH="100%" HEIGHT="100%" STYLE="FONT:11">
 <TR style="font-weight:bold">
      <TD >RAM: </TD>
      <TD ALIGN="RIGHT" id=RAMs>[<FONT COLOR=rED ID=RAM></FONT>] mb</TD>
 </TR>
</TABLE>
</style>
    <script type="text/javascript">
    
     var x0, y0;

     document.onmousemove=function () {
         //if ((event.button!=0)&&(event.button!=1)){
         if (event.button!=0){
             window.moveBy(event.x-x0, event.y-y0);
             return false;
         }
         document.body.style.cursor="auto";
     }

     document.onmousedown=function () {
         if (event.button!=1){
             x0=event.x; y0=event.y;
         }
     }
</script>

<script language=VBS>
	updateInfo()


	sub updateInfo()
		for each oOS in Getobject ("winmgmts:win32_operatingSystem").Instances_
			RAM.Innertext =  round(oOS.FreephysicalMemory /1024)
		next
		window.SetTimeout "updateInfo()",1000
	end sub
	
</script>

<!----------------------------->
	</BODY>
</HTML>

2

Re: HTA: Free RAM monitor

Было бы неплохо задействовать "игру цветом" при индикации - От спокойного зелёного при >80% свободной памяти до тревожно-красного при её нехватке.

Буду рад если кого-то заинтересует реализация этих дополнений.

3

Re: HTA: Free RAM monitor

Нормуль - робит...
вот эту бы штуку поверх всех окон можно...

Времени не хватает... :-(

4

Re: HTA: Free RAM monitor

Евген пишет:

вот эту бы штуку поверх всех окон можно...

Так вроде решили уже, что без посредников из скрипта до окошек не достучаться. Используем стороннюю либу, или пишем свою .

5

Re: HTA: Free RAM monitor

Угу...   я про Вашу либу и вспоминал...

Времени не хватает... :-(

6 (изменено: dab00, 2011-09-03 22:05:30)

Re: HTA: Free RAM monitor

Аскет пишет:

Было бы неплохо задействовать "игру цветом" при индикации - От спокойного зелёного при >80% свободной памяти до тревожно-красного при её нехватке.

Попробуйте, так пойдет?

<head>
  <title>ссс</title>
  <HTA:APPLICATION 
    ID = "ссс"
    APPLICATIONNAME="ссс"    
    SINGLEINSTANCE="yes"
    MAXIMIZEBUTTON = "no"
    SCROLL="no"
    ShowInTaskbar ="no"
    BORDER="none"    
    Version = "1.0">
    </HTA:APPLICATION>
</head>
<style type="text/css">
html, body{
    margin:1px;
    text-align: center;   
    font:bold 12 sans-serif;   
    border-style: outset;
    
 </style>
<script language="VBScript">
    Sub Window_OnLoad()        
        window.setTimeout "SetColor2 "& 0 & "," & 0 & "," & 255,1, "vbscript"
    End Sub
        
    Sub SetColor(x,y,z)        
        window.document.body.style.background = "#" & GetStrHex(x) & GetStrHex(y) & GetStrHex(z)
    End Sub        
    
    Function GetStrHex(i)
        If i < 16 Then
            GetStrHex = "0" & Hex(i)
        Else
            GetStrHex = Hex(i)
        End If        
    End Function
    
    Sub SetColor2(x,y,z)
        SetColor x,y,z
        x = x + 1
        z = z - 1
        If z <> 0 Then window.setTimeout _
                "SetColor2 " & x & "," & y & "," & z,5, "vbscript"        
    End Sub
    
</script> 
<body>
    
</body> 
</html>

Можно, конечно, и от зеленого, но на мой взгляд лучше от синего, т.к. черные буквы на красном по-моему не очень, лучше белые, а они лучше на более темных цветах.

7 (изменено: dab00, 2011-09-04 18:27:22)

Re: HTA: Free RAM monitor

Никому не понравился мой вариант трансформации цвета? Если лениво копипастить - можно скачать.
В архиве 2 варианта: с синего и зеленого на красный. Интересно же получилось .
В продолжение темы с подачи и, надеюсь, позволения уважаемого автора нарисовал HTML-приложение для мониторинга ресурсов системы: физической и виртуальной памяти, файла подкачки и загрузки процессора. С "игрой цветом", "поверх всех окон" и пр.
http://da440dil.narod.ru/resmon-images/resmon2.png http://da440dil.narod.ru/resmon-images/resmon3.png
Чисто для себя сделал. Поясню почему процессор добавил (все же с памяти началось).
У меня на рабочем ноуте 2 Гига оперативы и проц Селерон 1.8. Когда начал писать в Visual Studio 2010 проекты приложений баз данных на - ADO - Entity Framework - ASP - Silverlight и прочей мелкомягкой технологии, обратил внимание, что в процессе отладки ноуту становится плохо. Сначала думал на оперативу, файл подкачки увеличил, а потом просек, что оперативы используется чуть больше гига, а грузится процессор. Может у кого подобная проблема будет, этой приладой можно просечь .
Что касается кода, хочу указать на принципиальные отличия от кода автора:
- в большинстве отказался от функции Round, т.к. по-моему Int работает быстрее
- полностью отказался от метода Instances_, т.к. в коде ни к чему все свойства вызываемых объектов, кроме того  в WQL можно использовать полусинхронные запросы, что также увеличивает производительность
Для вывода окна поверх всех написал, как обычно, простенькую библиотеку, содержащую всего две API-функции:

Option Explicit
'API-функция получения дескриптора окна
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
        (ByVal lpszClassName As String, ByVal lpszWindow As String) As Long
'API-функция установки позиции окна
Private Declare Function SetWindowPos Lib "user32" _
        (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, _
        ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

'получаем дескриптор
Public Function GetHandle(ByVal strCaption As String) As Long
    GetHandle = FindWindow(vbNullString, strCaption)
End Function

'устанавливаем окно поверх всех
Public Sub SetTop(ByVal strCaption As String)
   SetWindowPos FindWindow(vbNullString, strCaption), -1, 0, 0, 0, 0, 3
End Sub

Кстати, на счет библиотеки. В этот раз я кажется решил проблему возможных косяков при повторной регистрации. По-моему лучше разрегистрировать библиотеку при выгрузке приложения. Возразите, может ошибаюсь.
А вот исходник HTA:

<html>
<head>
  <title>ResMon</title>
  <HTA:APPLICATION 
    ID = "ResMon"
    APPLICATIONNAME="ResMon"    
    SINGLEINSTANCE="yes"
    MAXIMIZEBUTTON = "no"
    SCROLL="no"
    ShowInTaskbar ="no"
    BORDER="none"
    SELECTION="no"
    Version = "1.0">
    </HTA:APPLICATION>
</head>
<style type="text/css">
    html, body{
        margin:1px;
        text-align: center;   
        font:bold 12 sans-serif;   
        border-style: outset;
        color: #ffffff;    
    }
    #header{
        background-color: #800000;
    }
 </style>
<script language="VBScript">
    Option Explicit
    Const strHash = "#"
    Const strHeader = "Объем свободных ресурсов"
    Const strDll = "WinPos.dll"
    '--- запросы
    Const strOSQ = "Select FreePhysicalMemory, FreeVirtualMemory, TotalVirtualMemorySize From Win32_OperatingSystem"
    Const strPMQ = "Select Capacity From Win32_PhysicalMemory"
    Const strPFUQ = "Select AllocatedBaseSize, CurrentUsage From Win32_PageFileUsage"
    Const strPQ = "Select LoadPercentage From Win32_Processor"
    Const intPSF = 48 'флаг полусинхронности
    '-------
    Dim objItem    
    Dim intTotal, intFreePart, intFreePartV, intFreePartP, intProcRate, intFreePartProc
    Dim intOSInfoArr(2), intOSInfo
    Dim intPFUInfoArr(1), intPFUInfo
    Dim i, intRet
    
    Dim objWMI, wshShell    
    Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
    Set wshShell = CreateObject("WScript.Shell")    
    
    Sub Window_OnLoad()
        Dim objSetTop
        window.resizeTo 245,80
        window.moveTo screen.availWidth-255, screen.availHeight-90
        'пытаемся зарегистрировать библиотеку
        intRet = RegLib(True)
        If intRet Then 
            'создаем экземпляр класса из либы = strDll
            Set objSetTop = CreateObject("WinPos.WPClass")        
            'делаем окно поверх всех окон
            objSetTop.SetTop document.title            
            'удаляем ссылку
            Set objSetTop = Nothing
        Else
            wshShell.PopUp "Не удалось зарегистрировать библиотеку " & strDll,1,"Ошибка регистрации",48
        End If
        header.Innertext = strHeader
        window.setTimeout "UpdateInfo", 1, "vbscript"    
    End Sub
        
    Sub Window_OnUnload()
        RegLib(False)
        Set wshShell = Nothing
        Set objWMI = Nothing
    End Sub
    
    Sub UpdateInfo()
        'информация из Win32_OperatingSystem: свободная физическая память, 
        'свободная виртуальная память, полный объем виртуальной памяти
        intOSInfo = GetOSInfo()
        intTotal = GetTotalMemorySize() 'полный объем физической памяти
        intPFUInfo = GetPFUInfo() 'информация о файле подкачки
        intProcRate = GetProcRate() 'процент свободного времени процессоров
        
        'процент свободной памяти в масштабе изменения RGB
        intFreePart = Round(intOSInfo(0)/intTotal*255) 'физической
        intFreePartV = Round(intOSInfo(1)/intOSInfo(2)*255) 'виртуальной
        intFreePartP = intPFUInfo(0)/intPFUInfo(1)*255 'подкачки
        intFreePartProc = intProcRate*2.55 'процессоры
        
        'выводим количество памяти
        fpRAM.Innertext = intOSInfo(0)     
        tpRAM.Innertext = intTotal
        fvRAM.Innertext = intOSInfo(1)
        tvRAM.Innertext = intOSInfo(2)
        fswap.Innertext = intPFUInfo(0)
        tswap.Innertext = intPFUInfo(1)
        procrate.Innertext = intProcRate
        
        'выставляем цвет окна: "#" + R + G + B, вариант от синего к красному
        window.document.getElementById("pRAM").style.backgroundColor = strHash & _
                GetStrHex(255-intFreePart) & GetStrHex(0) & GetStrHex(intFreePart)
        'вариант от зеленого к красному, прочие варианты - по аналогии
        window.document.getElementById("vRAM").style.backgroundColor = strHash & _
                GetStrHex(255-intFreePartV) & GetStrHex(intFreePartV) & GetStrHex(0)
        'снова от синего - подкачка
        window.document.getElementById("swap").style.backgroundColor = strHash & _
                GetStrHex(255-intFreePartP) & GetStrHex(0) & GetStrHex(intFreePartP)
        'снова от зеленого - процессор
        'MsgBox intProcRate & vbCrLf & strHash & _
        '        GetStrHex(255-intFreePartProc) & GetStrHex(intFreePartProc) & GetStrHex(0)
        window.document.getElementById("proc").style.backgroundColor = strHash & _
                GetStrHex(255-intFreePartProc) & GetStrHex(intFreePartProc) & GetStrHex(0)
        window.SetTimeout "UpdateInfo()", 1000, "vbscript"
    End Sub        
    
    Function GetOSInfo()
        Dim colOS
        Set colOS = objWMI.ExecQuery(strOSQ,,intPSF)
        For Each objItem In colOS
            With objItem
                intOSInfoArr(0) = Int(.FreePhysicalMemory/1024)
                intOSInfoArr(1) = Int(.FreeVirtualMemory/1024)
                intOSInfoArr(2) = Round(.TotalVirtualMemorySize/1024)            
            End With
        Next
        Set colOS = Nothing
        GetOSInfo = intOSInfoArr
    End Function
    
    'получаем объем физической памяти
    Function GetTotalMemorySize()
        Dim colPM
        Set colPM = objWMI.ExecQuery(strPMQ,,intPSF)
        For Each objItem In colPM
            GetTotalMemorySize = GetTotalMemorySize + Int(objItem.Capacity/1024/1024)
        Next
        Set colPM = Nothing
    End Function
    
    'получаем объем файла подкачки
    Function GetPFUInfo()
        Dim colPFL
        Set colPFL = objWMI.ExecQuery(strPFUQ,,intPSF)
        For Each objItem In colPFL
            With objItem
                'свободно = объем - использовано
                intPFUInfoArr(0) = .AllocatedBaseSize - .CurrentUsage 
                intPFUInfoArr(1) = .AllocatedBaseSize 'объем                
            End With
        Next
        Set colPFL = Nothing
        GetPFUInfo = intPFUInfoArr
    End Function
    
    'получаем процент загрузки процессоров
    Function GetProcRate()
        Dim colP
        Set colP = objWMI.ExecQuery(strPQ,,intPSF)
        i = 0
        For Each objItem In colP
            i = i + 1
            GetProcRate = GetProcRate + objItem.LoadPercentage            
        Next
        'вычисляем среднее арифметическое на случай, если процессоров несколько
        GetProcRate = 100-(GetProcRate/i)
        Set colP = Nothing
    End Function
    
    'переводим число из RGB в Hex для HTML
    Function GetStrHex(i)
        If i < 16 Then
            GetStrHex = "0" & Hex(i)
        Else
            GetStrHex = Hex(i)
        End If        
    End Function
    
    'регистрация библиотеки, True - регистрируем, False - разрегистрируем
    Function RegLib(bWha)
        Dim strWha
        If bWha Then 
            strWha = "regsvr32.exe /i /s "
        Else
            strWha = "regsvr32.exe u/ /i /s "
        End If
        
        intRet = wshShell.Run(strWha & strDll )
        
        If intRet = 0 Then 'если удалось зарегистрировать - True
            RegLib = True
        Else
            RegLib = False
        End If    
    End Function
    
</script> 
<body>
    <div id="header"></div>
    <div id="pRAM">
        Физическая память:&nbsp <span id="fpRAM"></span>&nbsp из&nbsp <span id="tpRAM"></span>&nbsp MB
    </div>
    <div id="vRAM">
        Виртуальная память:&nbsp <span id="fvRAM"></span>&nbsp из&nbsp <span id="tvRAM"></span>&nbsp MB
    </div>
    <div id="swap">
        Файл подкачки:&nbsp <span id="fswap"></span>&nbsp из&nbsp <span id="tswap"></span>&nbsp MB
    </div>
    <div id="proc">
        Процессоры:&nbsp <span id="procrate"></span>&nbsp из 100%
    </div>
</body> 
</html>

Ваши комменты .

8

Re: HTA: Free RAM monitor

dab00 пишет:

Кстати, на счет библиотеки. В этот раз я кажется решил проблему возможных косяков при повторной регистрации. По-моему лучше разрегистрировать библиотеку при выгрузке приложения. Возразите, может ошибаюсь.

Регистрацию лучше вовсе оставлять на откуп пользователю. Моё мнение.

9

Re: HTA: Free RAM monitor

alexii пишет:

Регистрацию лучше вовсе оставлять на откуп пользователю. Моё мнение.

Конечно так удобнее. Для разработчика .
Поясню про возникавшие проблемы регистрации (надеюсь решил вопрос).
Например, сегодня пишем код в каталоге 1, там же компилируем либу. Регистрируем, все работает.
Завтра пишем код в каталоге 2, регистрируем либу из каталоге 2 - все работает, т.к. есть либа в каталоге 1, а путь к либе прописан в реестре.
Послезавтра удаляем каталог 1 - код из каталога 2 не работает.
Так вот, на сколько я понял, чтобы все работало, что называется, portable - чтобы не копировать библиотеку куда-нибудь в системный каталог, откуда она уже никуда не пропадет, необходимо при завершении работы приложения разрегистрировать либу. Пробовал таким образом - полет нормальный .

10

Re: HTA: Free RAM monitor

dab00: да действительно, синий является самым "холодным" нежели зелёный.  Красивый переход реализован в 6-м посте.

У меня скрипт не работает: строка 87 рушит весь код.

intFreePartP = intPFUInfo(0)/intPFUInfo(1)*255 'подкачки

Закомментировав оную, начинает работать.

11 (изменено: dab00, 2011-09-05 16:54:24)

Re: HTA: Free RAM monitor

Аскет пишет:

У меня скрипт не работает: строка 87 рушит весь код.

intFreePartP = intPFUInfo(0)/intPFUInfo(1)*255 'подкачки

На вскидку могу предположить только деление на ноль - если у Вас AllocatedBaseSize - размер файла подкачки = 0.
Наверное нужно проверку добавить. А у Вас машинка какой системы ?
Вариант получше, совсем из головы вылетело - On Error Resume Next

12

Re: HTA: Free RAM monitor

Аскет пишет:

У меня скрипт не работает: строка 87 рушит весь код.

По ходу я поймал косяк - забыл округлить intFreePartP - процент свободного файла подкачки. Да и процент использования процессоров тоже округлить не помешало бы.

intFreePartP = Int(intPFUInfo(0)/intPFUInfo(1)*255) 'подкачки
intFreePartProc = Int(intProcRate*2.55) 'процессоры

Думаю это поможет. Я тоже поймал такую же ошибку в один прекрасный момент. У меня все решилось округлением.
Спасибо за тест

13 (изменено: dab00, 2011-09-05 21:25:21)

Re: HTA: Free RAM monitor

Исправил ошибку с округлением значения переменной.
Заинтересовала тема обработки событий окна - onmouseover, onkeydown и пр. - на VBS - у автора реализовано на JS.
Следующая реинкарнация кода:

<html>
<head>
  <title>ResMon</title>
  <HTA:APPLICATION 
    ID = "ResMon"
    APPLICATIONNAME="ResMon"    
    SINGLEINSTANCE="yes"
    MAXIMIZEBUTTON = "no"
    SCROLL="no"
    ShowInTaskbar ="no"
    BORDER="none"
    SELECTION="no"
    Version = "1.0">
    </HTA:APPLICATION>
</head>
<style type="text/css">
    html, body{
        margin:1px;
        text-align: center;   
        font:bold 12 sans-serif;   
        border-style: outset;
        color: #ffffff;
    }    
    #menu{        
        background-color: #800000;    
    }
    #closebtn{
        position: absolute; /* Абсолютное позиционирование */
        top: 1px; /* Положение от верхнего края */
        right: 1px; /* Положение от правого края */            
    }
    /* Цвета по умолчанию */
    #pRAM,#swap{
        background-color: #0000ff;
    }
    #vRAM,#proc{
        background-color: #00ff00;
    }
    
 </style>
<script language="VBScript">
    Option Explicit
    Const strHash = "#"
    Const strHeader = "Объем свободных ресурсов"    
    Const strDll = "WinPos.dll"
    '--- запросы
    Const strOSQ = "Select FreePhysicalMemory, FreeVirtualMemory, TotalVirtualMemorySize From Win32_OperatingSystem"
    Const strPMQ = "Select Capacity From Win32_PhysicalMemory"
    Const strPFUQ = "Select AllocatedBaseSize, CurrentUsage From Win32_PageFileUsage"
    Const strPQ = "Select LoadPercentage From Win32_Processor"
    Const intPSF = 48 'флаг полусинхронности
    '-------
    Dim objItem    
    Dim intTotal, intFreePart, intFreePartV, intFreePartP, intProcRate, intFreePartProc
    Dim intOSInfoArr(2), intOSInfo
    Dim intPFUInfoArr(1), intPFUInfo
    Dim i, intRet
    
    Dim objWMI, wshShell    
    Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
    Set wshShell = CreateObject("WScript.Shell")    
    
    Sub Window_OnLoad()
        Dim objSetTop
        window.resizeTo 245,80
        window.moveTo screen.availWidth-255, screen.availHeight-90
        
        'устанавливаем обработку событий
        SetUpEventHandler()    
        
        'пытаемся зарегистрировать библиотеку
        intRet = RegLib(True)
        If intRet Then 
            'создаем экземпляр класса из либы = strDll
            Set objSetTop = CreateObject("WinPos.WPClass")        
            'делаем окно поверх всех окон
            objSetTop.SetTop document.title            
            'удаляем ссылку
            Set objSetTop = Nothing
        Else
            wshShell.PopUp "Не удалось зарегистрировать библиотеку " & strDll,1,"Ошибка регистрации",48
        End If
        'заголовок приложения
        header.Innertext = strHeader
        window.setTimeout "UpdateInfo", 1, "vbscript"    
    End Sub
    
    '***************** Обработка событий окна приложения *****************
    
    Sub SetUpEventHandler()
        Dim ClosebtnOnclick, MouseOverClose, OnKeydownEvent
        Set ClosebtnOnclick = GetRef("OnClickCloseSub")
        closebtn.attachEvent "onclick", ClosebtnOnclick
        Set MouseOverClose = GetRef("MouseOverCloseSub")
        closebtn.attachEvent "onmouseover", MouseOverClose
        Set OnKeydownEvent = GetRef("MoveWindow")
        document.attachEvent "onkeydown", OnKeydownEvent    
    End Sub
    
    Sub OnClickCloseSub
        'window.close
        Window_OnUnload
    End Sub
    
    Sub MouseOverCloseSub
        closebtn.Style.Cursor = "hand"
    End Sub
    
    Sub MoveWindow()
        Dim z
        'ловим нажатие на Ctrl
        If window.event.ctrlKey Then
            'двигаем окно
            If window.event.keyCode=37 Then
                z = window.screenTop
                window.moveTo window.screenLeft-10,z
            ElseIf window.event.keyCode=39 Then
                z = window.screenTop
                window.moveTo window.screenLeft+10,z
            ElseIf window.event.keyCode=38 Then
                z = window.screenLeft
                window.moveTo z,window.screenTop-10
            ElseIf window.event.keyCode=40 Then
                z = window.screenLeft
                window.moveTo z,window.screenTop+10
            End If
        End If
    End Sub
    
    '***********************************************************************
        
    Sub Window_OnUnload()
        intRet = RegLib(False)
        Set wshShell = Nothing
        Set objWMI = Nothing
        window.close
    End Sub
    
    Sub UpdateInfo()
        'информация из Win32_OperatingSystem: свободная физическая память, 
        'свободная виртуальная память, полный объем виртуальной памяти
        intOSInfo = GetOSInfo()
        intTotal = GetTotalMemorySize() 'полный объем физической памяти
        intPFUInfo = GetPFUInfo() 'информация о файле подкачки
        intProcRate = GetProcRate() 'процент свободного времени процессоров
         
        'процент свободной памяти в масштабе изменения RGB
        intFreePart = Round(intOSInfo(0)/intTotal*255) 'физической
        intFreePartV = Round(intOSInfo(1)/intOSInfo(2)*255) 'виртуальной
        intFreePartP = Int(intPFUInfo(0)/intPFUInfo(1)*255) 'подкачки
        intFreePartProc = Int(intProcRate*2.55) 'процессоры
        
        'выводим количество памяти
        fpRAM.Innertext = intOSInfo(0)     
        tpRAM.Innertext = intTotal
        fvRAM.Innertext = intOSInfo(1)
        tvRAM.Innertext = intOSInfo(2)
        fswap.Innertext = intPFUInfo(0)
        tswap.Innertext = intPFUInfo(1)
        procrate.Innertext = intProcRate
        
        'выставляем цвет окна: "#" + R + G + B, вариант от синего к красному
        window.document.getElementById("pRAM").style.backgroundColor = strHash & _
                GetStrHex(255-intFreePart) & GetStrHex(0) & GetStrHex(intFreePart)
        'вариант от зеленого к красному, прочие варианты - по аналогии
        window.document.getElementById("vRAM").style.backgroundColor = strHash & _
                GetStrHex(255-intFreePartV) & GetStrHex(intFreePartV) & GetStrHex(0)
        'снова от синего - подкачка                
        window.document.getElementById("swap").style.backgroundColor = strHash & _
                GetStrHex(255-intFreePartP) & GetStrHex(0) & GetStrHex(intFreePartP)
        'снова от зеленого - процессор        
        window.document.getElementById("proc").style.backgroundColor = strHash & _
                GetStrHex(255-intFreePartProc) & GetStrHex(intFreePartProc) & GetStrHex(0)
        window.SetTimeout "UpdateInfo()", 1000, "vbscript"
    End Sub
        
    'получаем объем свободной памяти
    Function GetOSInfo()
        Dim colOS
        Set colOS = objWMI.ExecQuery(strOSQ,,intPSF)
        For Each objItem In colOS
            With objItem
                intOSInfoArr(0) = Int(.FreePhysicalMemory/1024)
                intOSInfoArr(1) = Int(.FreeVirtualMemory/1024)
                intOSInfoArr(2) = Round(.TotalVirtualMemorySize/1024)            
            End With
        Next        
        Set colOS = Nothing
        GetOSInfo = intOSInfoArr
    End Function
    
    'получаем объем физической памяти
    Function GetTotalMemorySize()
        Dim colPM
        Set colPM = objWMI.ExecQuery(strPMQ,,intPSF)
        For Each objItem In colPM
            GetTotalMemorySize = GetTotalMemorySize + Int(objItem.Capacity/1024/1024)
        Next
        Set colPM = Nothing
    End Function
    
    'получаем объем файла подкачки
    Function GetPFUInfo()
        Dim colPFL
        Set colPFL = objWMI.ExecQuery(strPFUQ,,intPSF)
        For Each objItem In colPFL
            With objItem
                'свободно = объем - использовано
                intPFUInfoArr(0) = .AllocatedBaseSize - .CurrentUsage 
                intPFUInfoArr(1) = .AllocatedBaseSize 'объем                
            End With
        Next
        Set colPFL = Nothing
        GetPFUInfo = intPFUInfoArr
    End Function
    
    'получаем процент загрузки процессоров
    Function GetProcRate()
        Dim colP
        Set colP = objWMI.ExecQuery(strPQ,,intPSF)
        i = 0
        For Each objItem In colP
            i = i + 1
            GetProcRate = GetProcRate + objItem.LoadPercentage            
        Next
        'вычисляем среднее арифметическое на случай, если процессоров несколько
        GetProcRate = 100-(GetProcRate/i)
        Set colP = Nothing
    End Function
    
    'переводим число из RGB в Hex для HTML
    Function GetStrHex(i)
        If i < 16 Then
            GetStrHex = "0" & Hex(i)
        Else
            GetStrHex = Hex(i)
        End If        
    End Function
    
    'регистрация библиотеки, True - регистрируем, False - разрегистрируем
    Function RegLib(bWha)
        Dim strWha
        If bWha Then 
            strWha = "regsvr32.exe /i /s "
        Else
            strWha = "regsvr32.exe u/ /i /s "
        End If
        'MsgBox "qwe"
        intRet = wshShell.Run(strWha & strDll )
        
        If intRet = 0 Then 'если удалось зарегистрировать - True
            RegLib = True
        Else
            RegLib = False
        End If    
    End Function
    
</script> 
<body>    
    <div id="menu">
        <span id="header"></span><span id="closebtn">X</span>
    </div>
    <div id="pRAM">
        Физическая память:&nbsp <span id="fpRAM"></span>&nbsp из&nbsp <span id="tpRAM"></span>&nbsp MB        
    </div>
    <div id="vRAM">
        Виртуальная память:&nbsp <span id="fvRAM"></span>&nbsp из&nbsp <span id="tvRAM"></span>&nbsp MB
    </div>
    <div id="swap">
        Файл подкачки:&nbsp <span id="fswap"></span>&nbsp из&nbsp <span id="tswap"></span>&nbsp MB
    </div>
    <div id="proc">
        Процессоры:&nbsp <span id="procrate"></span>&nbsp из 100%
    </div>
</body> 
</html>

Добавил крестик для завершения работы приложения. При наведении мыши на крестик изменяется курсор.
Кроме того Ctrl+стрелки перемещают окно по экрану. Приятные мелочи .
Не знаю как запустить процесс мониторинга в отдельном потоке, чтобы не подтормаживали манипуляции с окном.
Если ловить события через __InstanceCreationEvent - бесконечный цикл, тоже все висит.
Как-нибудь расставить приоритеты, чтобы код для манипуляций с интерфейсом был "круче", чем прочий.
Может снова через API как-нибудь можно сообразить?
Надеюсь кому-нибудь это интересно, а то похоже, что я тут сам с собой

14

Re: HTA: Free RAM monitor

dab00 пишет:

Не знаю как запустить процесс мониторинга в отдельном потоке, чтобы не подтормаживали манипуляции с окном.

Изнутри — никак. На время обработки события окно не перерисовывается.

15 (изменено: dab00, 2011-09-07 21:39:08)

Re: HTA: Free RAM monitor

alexii пишет:

Изнутри — никак. На время обработки события окно не перерисовывается.

Попробовал следующим образом. Добавил Public булеву переменную, которая служит флагом того, что приложение занято манипуляциями с окном. Рекурсивная процедура мониторинга начинается с проверки заначения этой переменной и в случае манипуляций с окном процедура завершается. В свою очередь процедуры манипуляций с окном в завершение изменяют значение переменной-флага и запускают процедуру мониторинга.
Алгоритм довольно простой и по идее должен работать как часы.

<html>
<head>
  <title>ResMon</title>
  <HTA:APPLICATION 
    ID = "ResMon"
    APPLICATIONNAME="ResMon"    
    SINGLEINSTANCE="yes"
    MAXIMIZEBUTTON = "no"
    SCROLL="no"
    ShowInTaskbar ="no"
    BORDER="none"
    SELECTION="no"
    Version = "1.0">
    </HTA:APPLICATION>
</head>
<style type="text/css">
    html, body{
        margin:1px;
        text-align: center;   
        font:bold 12 sans-serif;   
        border-style: outset;
        color: #ffffff;
    }    
    #menu{        
        background-color: #800000;    
    }
    #closebtn{
        position: absolute; /* Абсолютное позиционирование */
        top: 1px; /* Положение от верхнего края */
        right: 1px; /* Положение от правого края */            
    }
    /* Цвета по умолчанию */
    #pRAM,#swap{
        background-color: #0000ff;
    }
    #vRAM,#proc{
        background-color: #00ff00;
    }
    
 </style>
<script language="VBScript">
    Option Explicit
    Const strHash = "#"
    Const strHeader = "Объем свободных ресурсов"    
    Const strDll = "WinPos.dll"
    '--- запросы
    Const strOSQ = "Select FreePhysicalMemory, FreeVirtualMemory, TotalVirtualMemorySize From Win32_OperatingSystem"
    Const strPMQ = "Select Capacity From Win32_PhysicalMemory"
    Const strPFUQ = "Select AllocatedBaseSize, CurrentUsage From Win32_PageFileUsage"
    Const strPQ = "Select LoadPercentage From Win32_Processor"
    Const intPSF = 48 'флаг полусинхронности
    '-------
    Dim objItem    
    Dim intTotal, intFreePart, intFreePartV, intFreePartP, intProcRate, intFreePartProc
    Dim intOSInfoArr(2), intOSInfo
    Dim intPFUInfoArr(1), intPFUInfo
    Dim i, intRet
    
    Dim x0, y0 'координаты
    
    Dim bIsBusy 'флаг - приложение занято манипуляциями с окном
    bIsBusy = False 'по умолчанию
    
    Dim objWMI, wshShell    
    Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
    Set wshShell = CreateObject("WScript.Shell")    
    
    Sub Window_OnLoad()
        Dim objSetTop
        window.resizeTo 245,80
        window.moveTo screen.availWidth-255, screen.availHeight-90
        
        'устанавливаем обработку событий
        SetUpEventHandler()    
        
        'пытаемся зарегистрировать библиотеку
        intRet = RegLib(True)
        If intRet Then 
            'создаем экземпляр класса из либы = strDll
            Set objSetTop = CreateObject("WinPos.WPClass")        
            'делаем окно поверх всех окон
            objSetTop.SetTop document.title            
            'удаляем ссылку
            Set objSetTop = Nothing
        Else
            wshShell.PopUp "Не удалось зарегистрировать библиотеку " & strDll,1,"Ошибка регистрации",48
        End If
        'заголовок приложения
        header.Innertext = strHeader
        window.setTimeout "UpdateInfo", 1, "vbscript"    
    End Sub
    
    '***************** Обработка событий окна приложения *****************
    
    Sub SetUpEventHandler()
        Dim ClosebtnOnclick, MouseOverClose, MouseOutClose, OnKeydownEvent, OnKeyupEvent
        Dim EHMouseDown,EHMouseMove,EHMouseUp
        
        'закрываем окно
        Set ClosebtnOnclick = GetRef("OnClickCloseSub")
        closebtn.attachEvent "onclick", ClosebtnOnclick
        Set MouseOverClose = GetRef("MouseOverCloseSub")
        closebtn.attachEvent "onmouseover", MouseOverClose
        Set MouseOutClose = GetRef("MouseOutCloseSub")
        closebtn.attachEvent "onmouseout", MouseOutClose
        
        'тащим окно кнопками
        Set OnKeydownEvent = GetRef("MoveWindow")
        document.attachEvent "onkeydown", OnKeydownEvent
        Set OnKeyupEvent = GetRef("ReleaseUpdate")
        document.attachEvent "onkeyup", OnKeyupEvent
        
        'тащим окно мышью
        Set EHMouseDown = GetRef("MouseDownEvent")
        Set EHMouseMove = GetRef("MouseMoveEvent")
        Set EHMouseUp = GetRef("MouseUpEvent")
        document.attachEvent "onmousedown", EHMouseDown
        document.attachEvent "onmousemove", EHMouseMove
        document.attachEvent "onmouseup", EHMouseUp            
    End Sub
    
    '----- Мыши -----    
    Function MouseDownEvent()
        '1 - левая кнопка, 4 - средняя, 2 - правая
        If window.event.button = 2 Then
            'ставим флаг - приложение занято манипуляциями с окном
            bIsBusy = True 
            x0=window.event.x
            y0=window.event.y            
        End If
    End Function
    
    Sub MouseUpEvent()
        If window.event.button = 2 Then
            'ставим флаг - приложение завершило манипуляциями с окном
            bIsBusy = False 
            'на случай быстрых кликов запустим мониторинг с задержкой в 1 секунду
            window.SetTimeout "UpdateInfo()", 1000, "vbscript"            
        End If
    End Sub
                
    Function MouseMoveEvent()
        If window.event.button = 2 Then 'если нажата правая кнопка                    
            window.moveBy window.event.x-x0, window.event.y-y0
        End If
    End Function    
    '-----------------    
    
    '----- Закрыть -----
    Sub OnClickCloseSub()        
        Window_OnUnload
    End Sub
    
    Sub MouseOverCloseSub()
        closebtn.Style.Cursor = "hand"
        closebtn.style.backgroundColor = "#ff8c00"        
    End Sub
    
    Sub MouseOutCloseSub()
        closebtn.style.backgroundColor = "#800000"
    End Sub
    '--------------------
    
    '----- Кнопки -----    
    'если нажата стрелка - True
    Function IsArrowBtn(IntCode)
        IsArrowBtn = False
        For i = 37 To 40
            If i = IntCode Then
                IsArrowBtn = True
                Exit For
            End If
        Next
    End Function
    
    'двигаем окно
    Sub MoveWindow()
        Dim z        
        'ловим нажатие на Ctrl
        If window.event.ctrlKey Then
            'если нажата стрелка - выставляем флаг
            If IsArrowBtn(window.event.keyCode) Then bIsBusy = True
            'двигаем окно
            If window.event.keyCode=37 Then                
                z = window.screenTop
                window.moveTo window.screenLeft-10,z
            ElseIf window.event.keyCode=39 Then                
                z = window.screenTop
                window.moveTo window.screenLeft+10,z
            ElseIf window.event.keyCode=38 Then                
                z = window.screenLeft
                window.moveTo z,window.screenTop-10
            ElseIf window.event.keyCode=40 Then                
                z = window.screenLeft
                window.moveTo z,window.screenTop+10
            End If        
        End If        
    End Sub
    
    'продолжаем мониторинг
    Sub ReleaseUpdate()
        If window.event.ctrlKey Then
            'если нажата стрелка
            If IsArrowBtn(window.event.keyCode) Then 
                bIsBusy = False 'выставляем флаг
                'на случай возобновления движения 
                'запустим мониторинг с задержкой в 1 секунду
                window.SetTimeout "UpdateInfo()", 1000, "vbscript"            
            End If                
        End If
    End Sub
    '-------------------
    
    '***********************************************************************
        
    Sub Window_OnUnload()
        intRet = RegLib(False)
        Set wshShell = Nothing
        Set objWMI = Nothing
        window.close
    End Sub
    
    Sub UpdateInfo()
        'если приложение занято манипуляциями с окном - 
        'завершаем процесс мониторинга
        If bIsBusy Then Exit Sub
        'информация из Win32_OperatingSystem: свободная физическая память, 
        'свободная виртуальная память, полный объем виртуальной памяти
        intOSInfo = GetOSInfo()
        intTotal = GetTotalMemorySize() 'полный объем физической памяти
        intPFUInfo = GetPFUInfo() 'информация о файле подкачки
        intProcRate = GetProcRate() 'процент свободного времени процессоров
         
        'процент свободных ресурсов в масштабе изменения RGB
        intFreePart = Int(intOSInfo(0)/intTotal*255) 'физической
        intFreePartV = Int(intOSInfo(1)/intOSInfo(2)*255) 'виртуальной
        intFreePartP = Int(intPFUInfo(0)/intPFUInfo(1)*255) 'подкачки
        intFreePartProc = Int(intProcRate*2.55) 'процессоры
        
        'выводим количество ресурсов
        fpRAM.Innertext = intOSInfo(0)     
        tpRAM.Innertext = intTotal
        fvRAM.Innertext = intOSInfo(1)
        tvRAM.Innertext = intOSInfo(2)
        fswap.Innertext = intPFUInfo(0)
        tswap.Innertext = intPFUInfo(1)
        procrate.Innertext = intProcRate
        
        'выставляем цвет окна: "#" + R + G + B, вариант от синего к красному
        pRAM.style.backgroundColor = strHash & _
                GetStrHex(255-intFreePart) & GetStrHex(0) & GetStrHex(intFreePart)
        'вариант от зеленого к красному, прочие варианты - по аналогии
        vRAM.style.backgroundColor = strHash & _
                GetStrHex(255-intFreePartV) & GetStrHex(intFreePartV) & GetStrHex(0)
        'снова от синего - подкачка                
        swap.style.backgroundColor = strHash & _
                GetStrHex(255-intFreePartP) & GetStrHex(0) & GetStrHex(intFreePartP)
        'снова от зеленого - процессор        
        proc.style.backgroundColor = strHash & _
                GetStrHex(255-intFreePartProc) & GetStrHex(intFreePartProc) & GetStrHex(0)
        'курим 1 секунду и вызываем сами себя
        window.SetTimeout "UpdateInfo()", 1000, "vbscript"
    End Sub
        
    'получаем объем свободной памяти
    Function GetOSInfo()
        Dim colOS
        Set colOS = objWMI.ExecQuery(strOSQ,,intPSF)
        For Each objItem In colOS
            With objItem
                intOSInfoArr(0) = Int(.FreePhysicalMemory/1024)
                intOSInfoArr(1) = Int(.FreeVirtualMemory/1024)
                intOSInfoArr(2) = Int(.TotalVirtualMemorySize/1024)            
            End With
        Next        
        Set colOS = Nothing
        GetOSInfo = intOSInfoArr
    End Function
    
    'получаем объем физической памяти
    Function GetTotalMemorySize()
        Dim colPM
        Set colPM = objWMI.ExecQuery(strPMQ,,intPSF)
        For Each objItem In colPM
            GetTotalMemorySize = GetTotalMemorySize + Int(objItem.Capacity/1024/1024)
        Next
        Set colPM = Nothing
    End Function
    
    'получаем объем файла подкачки
    Function GetPFUInfo()
        Dim colPFL
        Set colPFL = objWMI.ExecQuery(strPFUQ,,intPSF)
        For Each objItem In colPFL
            With objItem
                'свободно = объем - использовано
                intPFUInfoArr(0) = .AllocatedBaseSize - .CurrentUsage 
                intPFUInfoArr(1) = .AllocatedBaseSize 'объем                
            End With
        Next
        Set colPFL = Nothing
        GetPFUInfo = intPFUInfoArr
    End Function
    
    'получаем процент загрузки процессоров
    Function GetProcRate()
        Dim colP
        Set colP = objWMI.ExecQuery(strPQ,,intPSF)
        i = 0
        For Each objItem In colP
            i = i + 1
            GetProcRate = GetProcRate + objItem.LoadPercentage            
        Next
        'вычисляем среднее арифметическое на случай, если процессоров несколько
        GetProcRate = 100-(GetProcRate/i)
        Set colP = Nothing
    End Function
    
    'переводим число из RGB в Hex для HTML
    Function GetStrHex(i)
        If i < 16 Then
            GetStrHex = "0" & Hex(i)
        Else
            GetStrHex = Hex(i)
        End If        
    End Function
    
    'регистрация библиотеки, True - регистрируем, False - разрегистрируем
    Function RegLib(bWha)
        Dim strWha
        If bWha Then 
            strWha = "regsvr32.exe /i /s "
        Else
            strWha = "regsvr32.exe u/ /i /s "
        End If        
        intRet = wshShell.Run(strWha & strDll )
        
        If intRet = 0 Then 'если удалось зарегистрировать - True
            RegLib = True
        Else
            RegLib = False
        End If    
    End Function
    
</script> 
<body>    
    <div id="menu">
        <span id="header"></span><span id="closebtn">X</span>
    </div>
    <div id="pRAM">
        Физическая память:&nbsp <span id="fpRAM"></span>&nbsp из&nbsp <span id="tpRAM"></span>&nbsp MB        
    </div>
    <div id="vRAM">
        Виртуальная память:&nbsp <span id="fvRAM"></span>&nbsp из&nbsp <span id="tvRAM"></span>&nbsp MB
    </div>
    <div id="swap">
        Файл подкачки:&nbsp <span id="fswap"></span>&nbsp из&nbsp <span id="tswap"></span>&nbsp MB
    </div>
    <div id="proc">
        Процессоры:&nbsp <span id="procrate"></span>&nbsp из 100%
    </div>
</body> 
</html>

Специально для тестирования алгоритма добавил альтернативный вариант перемещения окна - правой кнопкой мыши - тоже у автора поста подсмотрел, правда в другом посте - про мониторинг траффика, и переделал на VBS.
Итог: при желании можно "ушатать" оба варианта.
При перемещении окна мышью иногда вылетает курсор и следовательно не срабатывает событие onmouseup, которое должно запускать процесс мониторинга, в результате данные в окне не обновляются, для возобновления приходится еще раз щелкать мышью по окну.
При перемещении кнопками... я так и не понял. При забеге окна на небольшие расстояния все работает как надо. Но при желании можно уронить. Пробовал изменять задержку запуска процедуры мониторинга после завершения манипуляций с окном - не помогло.
Не могу понять..., должно же работать...
Время будет - посмотрите, уважаемые может появятся мысли какие по этому вопросу.