Войти

Показать полную графическую версию : [решено] Вывод ErrorLogs системы в GUICtrlListView с расшифровкой кодов в отдельном окне формы


saavaage
21-08-2010, 17:04
Собственно, проблема:
получить вывод в окно формы логов ошибочных событий системы и, затем, используя полученные в списке GUICtrlListView коды ошибок, получить их расшифровку в отдельном окне GUICtrlEdit.

Последовательность действий: 1. получаем в cmd список ErrorLogs (команда CSCRIPT %SYSTEMROOT%\system32\EVENTQUERY.vbs /v /fo TABLE /NH), 2. выводим полученный список ErrorLogs в GUICtrlListView, 3. выделяем любую строку списка в GUICtrlListView, 4. получаем в окне GUICtrlEdit информацию по данной ошибке (используя команду net helpmsg <код ошибки>).

Тема является продолжением http://forum.oszone.net/thread-183492.html

последний код (спасибо madmasles):

#include <Constants.au3>
#include <Encoding.au3>
#include <GUIConstantsEx.au3>
#include <GUIListview.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)

Global $hForm1, $hButton1, $hInput, $ListView, $hListView, $aErrorsNew, $nMsg
Dim $aToList = __ErrorLog()

$hForm1 = GUICreate("Form1", 620, 445, -1, -1)
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
$hButton1 = GUICtrlCreateButton("Обновить", 16, 120, 65, 57)
$hInput = GUICtrlCreateEdit('', 95, 10, 400, 34, BitOR($ES_READONLY, $ES_MULTILINE))
$ListView = GUICtrlCreateListView('Список событий с ошибками', 95, 60, 400, 320, -1, $LVS_EX_GRIDLINES)
GUICtrlSetState(-1, $GUI_FOCUS)
$hListView = GUICtrlGetHandle($ListView)
_GUICtrlListView_SetColumnWidth($hListView, 0, 2000)
GUICtrlSetTip(-1, "Выделите мышкой строку," & @CRLF & "чтобы получить подсказку.")
If $aToList <> 0 Then
_GUICtrlListView_AddColumn($hListView, '')
For $i = 1 To UBound($aToList) - 1
_GUICtrlListView_AddItem($hListView, $aToList[$i])
Next
_GUICtrlListView_SetItemSelected($hListView, 0)
EndIf

GUISetState(@SW_SHOW)

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $hButton1
GUICtrlSetData($hInput, '')
$aErrorsNew = __ErrorLog()
If $aErrorsNew <> 0 Then
_GUICtrlListView_DeleteAllItems($hListView)
For $i = 1 To UBound($aErrorsNew) - 1
_GUICtrlListView_AddItem($hListView, $aErrorsNew[$i])
Next
_GUICtrlListView_SetItemSelected($hListView, 0)
EndIf
GUICtrlSetState($hButton1, $GUI_ENABLE)
GUICtrlSetState($ListView, $GUI_FOCUS)
EndSwitch
WEnd

Func __ErrorLog()
GUICtrlSetState($hButton1, $GUI_DISABLE)
Local $sLog = '', $j = 0, $hError, $aErrorsTemp, $i
Dim $aErrors[1]
$hError = Run('CSCRIPT.exe ' & @SystemDir & '\eventquery.vbs /v /fi "Type eq ERROR" /fo TABLE /NH', '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hError)
If @error Then ExitLoop
Sleep(10)
WEnd
If Not $sLog Then Return 0
$aErrorsTemp = StringSplit(_Encoding_866To1251($sLog), @LF)
If Not IsArray($aErrorsTemp) Then Return 0
For $i = 1 To $aErrorsTemp[0]
If StringInStr($aErrorsTemp[$i], "ошибка") Then
ReDim $aErrors[UBound($aErrors) + 1]
$j += 1
$aErrors[$j] = StringStripWS(StringStripCR($aErrorsTemp[$i]), 7)
EndIf
Next
$aErrors[0] = UBound($aErrors) - 1
If UBound($aErrors) < 2 Then Return 0
Return $aErrors
EndFunc ;==>__ErrorLog

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
Local $tNMITEMACTIVATE = DllStructCreate($tagNMITEMACTIVATE, $lParam)
Local $hFrom = DllStructGetData($tNMITEMACTIVATE, 'hWndFrom')
Local $Index = DllStructGetData($tNMITEMACTIVATE, 'Index')
Local $ID = DllStructGetData($tNMITEMACTIVATE, 'Code')

Switch $hFrom
Case $hListView
Switch $ID
Case $LVN_ITEMCHANGED
If (BitAND(DllStructGetData($tNMITEMACTIVATE, 'Changed'), $LVIF_STATE)) And _
(BitAND(DllStructGetData($tNMITEMACTIVATE, 'NewState'), $LVIS_SELECTED)) _
And (Not BitAND(DllStructGetData($tNMITEMACTIVATE, 'OldState'), $LVIS_FOCUSED)) Then
_ErrorHelp($Index)
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY

Func _ErrorHelp($Index)
Local $iNumberError, $hHelp, $sLog = ''
GUICtrlSetState($hButton1, $GUI_DISABLE)
GUICtrlSetState($hListView, $GUI_DISABLE)
$iNumberError = StringRegExpReplace(_GUICtrlListView_GetItemText($hListView, $Index), "(?s).*?ошибка (.*?)\s+?.*", '\1')
$hHelp = Run('net helpmsg ' & $iNumberError, '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hHelp)
If @error Then ExitLoop
Sleep(10)
WEnd
$sLog = StringStripWS(StringStripCR(_Encoding_866To1251($sLog)), 7)
GUICtrlSetData($hInput, 'Ошибка № ' & $iNumberError & ' - ' & $sLog)
GUICtrlSetState($hButton1, $GUI_ENABLE)
GUICtrlSetState($hListView, $GUI_ENABLE)
EndFunc ;==>_ErrorHelp

Собственно, незакрытый вопрос по этому коду:
обнаружено ограничение на длину строки (кол-во выводимых символов) в GUICtrlListView - "не отображается полная строка с описанием ошибки (обрывается на 300 с чем-то знаков)"- (пост http://forum.oszone.net/post-1478325-12.html)

madmasles
21-08-2010, 17:21
saavaage,
обрывается на 300 с чем-то знаков
Не нашел я решения этого вопроса. Как вариант, как Вы предлагали, делить строку на части и распределять их по разным столбцам.

Creat0R
21-08-2010, 17:37
обнаружено ограничение на длину строки »
Уже давно (http://msdn.microsoft.com/en-us/library/bb774760(VS.85).aspx).
Строка обрезается (260 символов), однако Item содержит полную строку как она была передана, и её можно извлечь.

Я бы делал так:

For (http://www.autoitscript.com/autoit3/docs/keywords.htm#For) $i = 1 To (http://www.autoitscript.com/autoit3/docs/keywords.htm#To) UBound (http://www.autoitscript.com/autoit3/docs/functions/UBound.htm)($aToList) - 1
If (http://www.autoitscript.com/autoit3/docs/keywords.htm#If) StringLen (http://www.autoitscript.com/autoit3/docs/functions/StringLen.htm)($aToList[$i]) >= 260 Then (http://www.autoitscript.com/autoit3/docs/keywords.htm#Then)
$aToList[$i] = StringLeft (http://www.autoitscript.com/autoit3/docs/functions/StringLeft.htm)($aToList[$i], 256) & "..."
EndIf (http://www.autoitscript.com/autoit3/docs/keywords.htm#EndIf)
_GUICtrlListView_AddItem (http://dundats.mvps.org/help/html/libfunctions/_guictrllistview_additem.htm)($hListView, $aToList[$i])
Next (http://www.autoitscript.com/autoit3/docs/keywords.htm#Next)

если конечно потом эту строку не нужно извлекать.

saavaage
21-08-2010, 17:45
madmasles, тоже "ходил" на оф. форум и, насколько понял, это ограничение связано с системными делами XP.

saavaage
21-08-2010, 18:01
Creat0R, у меня особой разницы не получилось... В первом случае - просто обрыв строки, во-втором - обрыв + добавляется "..." (что, в принципе логично, исходя из кода).

madmasles, Creat0R, а возможно ли ее извлечь по принципу расшифровки ошибки по коду, т.е. создать еще одно GUICtrlEdit и тупо выводить туда строку, которую выделяешь в GUICtrlListView, только полностью.

Суть - будет 3 окна:
1. список GUICtrlListView,
2. GUICtrlEdit1 с расшифровкой кода выделенной строки GUICtrlListView,
3. GUICtrlEdit2 с полным выводом выделенной строки из GUICtrlListView.

saavaage
21-08-2010, 18:53
Вот, что, собственно, у меня вышло:
#include <Constants.au3>
#include <Encoding.au3>
#include <GUIConstantsEx.au3>
#include <GUIListview.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Global $Form1, $Button1, $hInput, $hInputAll, $hListView, $aErrorsNew
Dim $aToList = __ErrorLog()

$Form1 = GUICreate("Form1", 620, 445, -1, -1)
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
$Button1 = GUICtrlCreateButton("Обновить", 16, 120, 65, 57)
GUICtrlSetState(-1, $GUI_FOCUS)
$hInput = GUICtrlCreateEdit('', 95, 10, 400, 34, BitOR($ES_READONLY, $ES_MULTILINE))
$hInputAll = GUICtrlCreateEdit('', 95, 370, 400, 64, BitOR($ES_READONLY, $ES_MULTILINE, $WS_VSCROLL))
$hListView = GUICtrlCreateListView('Список событий с ошибками', 95, 60, 400, 300, -1, $LVS_EX_GRIDLINES)
_GUICtrlListView_SetColumnWidth($hListView, 0, 2500)
GUICtrlSetTip(-1, "Выделите левой или правой кнопкой мышки" & @CRLF & "строку, чтобы получить подсказку.")
If $aToList <> 0 Then
_GUICtrlListView_AddColumn($hListView, $aToList[0], 2500)
For $i = 1 To UBound($aToList) - 1
GUICtrlCreateListViewItem($aToList[$i], $hListView)
Next
EndIf

GUISetState(@SW_SHOW)

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
GUICtrlSetData($hInput, '')
_GUICtrlListView_DeleteAllItems($hListView)
$aErrorsNew = __ErrorLog()
If $aErrorsNew <> 0 Then
_GUICtrlListView_BeginUpdate($hListView)
For $i = 1 To UBound($aErrorsNew) - 1
GUICtrlCreateListViewItem($aErrorsNew[$i], $hListView)
Next
_GUICtrlListView_EndUpdate($hListView)
EndIf
GUICtrlSetState($Button1, $GUI_ENABLE)
EndSwitch
WEnd

Func __ErrorLog()
GUICtrlSetState($Button1, $GUI_DISABLE)
Local $sLog = '', $j = 0, $hError, $aErrorsTemp, $i = 0
Dim $aErrors[1]
$hError = Run('CSCRIPT.exe ' & @SystemDir & '\eventquery.vbs /v /fi "Type eq ERROR" /fo TABLE /NH', '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hError)
If @error Then ExitLoop
Sleep(100)
WEnd
If Not $sLog Then Return 0
$aErrorsTemp = StringSplit(_Encoding_866To1251($sLog), @LF)
If Not IsArray($aErrorsTemp) Then Return 0
For $i = 1 To $aErrorsTemp[0]
If StringInStr($aErrorsTemp[$i], "ошибка") Then
ReDim $aErrors[UBound($aErrors) + 1]
$j += 1
$aErrors[$j] = StringStripWS(StringStripCR($aErrorsTemp[$i]), 7)
EndIf
Next
If UBound($aErrors) < 2 Then Return 0
Return $aErrors
EndFunc ;==>__ErrorLog

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iCode, $tNMHDR, $hWndListView, $tInfo, $iIndex, $sLog = '', $hHelp

$hWndListView = $hListView
If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hWndListView
Switch $iCode
Case $NM_CLICK
$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndex = DllStructGetData($tInfo, "Index")
If $iIndex < 0 Then Return $GUI_RUNDEFMSG
$hFullString =_GUICtrlListView_GetItemText($hListView, $iIndex)
$iNumberError = StringRegExpReplace(_GUICtrlListView_GetItemText($hListView, $iIndex), "(?s).*?ошибка (.*?)\s+?.*", '\1')
$hHelp = Run('net helpmsg ' & $iNumberError, '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hHelp)
If @error Then ExitLoop
Sleep(10)
WEnd
$sLog = StringStripWS(StringStripCR(_Encoding_866To1251($sLog)), 7)
GUICtrlSetData($hInput, 'Ошибка № ' & $iNumberError & ' - ' & $sLog)
GUICtrlSetData($hInputAll, $hFullString)
Case $NM_RCLICK
$tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
$iIndex = DllStructGetData($tInfo, "Index")
If $iIndex <> -1 Then
GUICtrlSetData($hInput, _GUICtrlListView_GetItemText($hListView, $iIndex))
$iIndex_Item = $iIndex
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY

Аналогично с кодом в шапке:

#include <Constants.au3>
#include <Encoding.au3>
#include <GUIConstantsEx.au3>
#include <GUIListview.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)

Global $hForm1, $hButton1, $hInput, $ListView, $hListView, $aErrorsNew, $nMsg, $hInputAll
Dim $aToList = __ErrorLog()

$hForm1 = GUICreate("Form1", 620, 445, -1, -1)
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
$hButton1 = GUICtrlCreateButton("Обновить", 16, 120, 65, 57)
$hInput = GUICtrlCreateEdit('', 95, 10, 500, 34, BitOR($ES_READONLY, $ES_MULTILINE))
$hInputAll = GUICtrlCreateEdit('', 95, 370, 500, 64, BitOR($ES_READONLY, $ES_MULTILINE, $WS_VSCROLL))
$ListView = GUICtrlCreateListView('Список событий с ошибками', 95, 60, 500, 300, -1, $LVS_EX_GRIDLINES)
GUICtrlSetState(-1, $GUI_FOCUS)
$hListView = GUICtrlGetHandle($ListView)
_GUICtrlListView_SetColumnWidth($hListView, 0, 2000)
GUICtrlSetTip(-1, "Выделите мышкой строку," & @CRLF & "чтобы получить подсказку.")
If $aToList <> 0 Then
_GUICtrlListView_AddColumn($hListView, '')
For $i = 1 To UBound($aToList) - 1
_GUICtrlListView_AddItem($hListView, $aToList[$i])
Next
_GUICtrlListView_SetItemSelected($hListView, 0)
EndIf

GUISetState(@SW_SHOW)

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $hButton1
GUICtrlSetData($hInput, '')
GUICtrlSetData($hInputAll, '')
$aErrorsNew = __ErrorLog()
If $aErrorsNew <> 0 Then
_GUICtrlListView_DeleteAllItems($hListView)
For $i = 1 To UBound($aErrorsNew) - 1
_GUICtrlListView_AddItem($hListView, $aErrorsNew[$i])
Next
_GUICtrlListView_SetItemSelected($hListView, 0)
EndIf
GUICtrlSetState($hButton1, $GUI_ENABLE)
GUICtrlSetState($ListView, $GUI_FOCUS)
EndSwitch
WEnd

Func __ErrorLog()
GUICtrlSetState($hButton1, $GUI_DISABLE)
Local $sLog = '', $j = 0, $hError, $aErrorsTemp, $i
Dim $aErrors[1]
$hError = Run('CSCRIPT.exe ' & @SystemDir & '\eventquery.vbs /v /fi "Type eq ERROR" /fo TABLE /NH', '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hError)
If @error Then ExitLoop
Sleep(10)
WEnd
If Not $sLog Then Return 0
$aErrorsTemp = StringSplit(_Encoding_866To1251($sLog), @LF)
If Not IsArray($aErrorsTemp) Then Return 0
For $i = 1 To $aErrorsTemp[0]
If StringInStr($aErrorsTemp[$i], "ошибка") Then
ReDim $aErrors[UBound($aErrors) + 1]
$j += 1
$aErrors[$j] = StringStripWS(StringStripCR($aErrorsTemp[$i]), 7)
EndIf
Next
$aErrors[0] = UBound($aErrors) - 1
If UBound($aErrors) < 2 Then Return 0
Return $aErrors
EndFunc ;==>__ErrorLog

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
Local $tNMITEMACTIVATE = DllStructCreate($tagNMITEMACTIVATE, $lParam)
Local $hFrom = DllStructGetData($tNMITEMACTIVATE, 'hWndFrom')
Local $Index = DllStructGetData($tNMITEMACTIVATE, 'Index')
Local $ID = DllStructGetData($tNMITEMACTIVATE, 'Code')

Switch $hFrom
Case $hListView
Switch $ID
Case $LVN_ITEMCHANGED
If (BitAND(DllStructGetData($tNMITEMACTIVATE, 'Changed'), $LVIF_STATE)) And _
(BitAND(DllStructGetData($tNMITEMACTIVATE, 'NewState'), $LVIS_SELECTED)) _
And (Not BitAND(DllStructGetData($tNMITEMACTIVATE, 'OldState'), $LVIS_FOCUSED)) Then
_ErrorHelp($Index)
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY

Func _ErrorHelp($Index)
Local $iNumberError, $hHelp, $sLog = '', $hFullString
GUICtrlSetState($hButton1, $GUI_DISABLE)
GUICtrlSetState($hListView, $GUI_DISABLE)
$hFullString =_GUICtrlListView_GetItemText($hListView, $Index)
$iNumberError = StringRegExpReplace(_GUICtrlListView_GetItemText($hListView, $Index), "(?s).*?ошибка (.*?)\s+?.*", '\1')
$hHelp = Run('net helpmsg ' & $iNumberError, '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hHelp)
If @error Then ExitLoop
Sleep(10)
WEnd
$sLog = StringStripWS(StringStripCR(_Encoding_866To1251($sLog)), 7)
GUICtrlSetData($hInput, 'Ошибка № ' & $iNumberError & ' - ' & $sLog)
GUICtrlSetData($hInputAll, $hFullString)
GUICtrlSetState($hButton1, $GUI_ENABLE)
GUICtrlSetState($hListView, $GUI_ENABLE)
EndFunc ;==>_ErrorHelp

Кстати, есть вопрос по последнему коду: почему-то, при клике на строке в окне GUICtrlCreateListView, происходит ее выделение, а при попытке кликнуть по другой строке не происходит выделение последней. Система кликов-выделений срабатывает через клик.

Creat0R
21-08-2010, 19:43
возможно ли ее извлечь »
Я же написал:
Строка обрезается (260 символов), однако Item содержит полную строку как она была передана, и её можно извлечь»

Пытался проделать тоже с кодом в шапке - потерпел фиаско. Может поможете? »
Вот, немного поправил код для ускорения:
#include <Encoding.au3>
#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListview.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

;Opt('MustDeclareVars', 1)

Global $hForm1, $hButton1, $hInput, $ListView, $hListView, $aErrorsNew, $nMsg
Dim $aToList = __ErrorLog()

$hForm1 = GUICreate("Form1", 620, 445, -1, -1)
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
$hButton1 = GUICtrlCreateButton("Обновить", 16, 120, 65, 57)
$hInput = GUICtrlCreateEdit('', 95, 10, 400, 34, BitOR($ES_READONLY, $ES_MULTILINE))
$hInputAll = GUICtrlCreateEdit('', 95, 385, 400, 55, BitOR($ES_READONLY, $ES_MULTILINE, $WS_VSCROLL))
$ListView = GUICtrlCreateListView('Список событий с ошибками', 95, 60, 400, 320, -1, $LVS_EX_GRIDLINES)
GUICtrlSetState(-1, $GUI_FOCUS)
$hListView = GUICtrlGetHandle($ListView)
_GUICtrlListView_SetColumnWidth($hListView, 0, 2000)
GUICtrlSetTip(-1, "Выделите мышкой строку," & @CRLF & "чтобы получить подсказку.")

If $aToList <> 0 Then
_GUICtrlListView_AddColumn($hListView, '')
For $i = 1 To UBound($aToList) - 1
_GUICtrlListView_AddItem($hListView, $aToList[$i])
Next
_GUICtrlListView_SetItemSelected($hListView, 0)
EndIf

GUISetState(@SW_SHOW)

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $hButton1
GUICtrlSetData($hInput, '')
GUICtrlSetData($hInputAll, '')
$aErrorsNew = __ErrorLog()
If $aErrorsNew <> 0 Then
_GUICtrlListView_DeleteAllItems($hListView)
For $i = 1 To UBound($aErrorsNew) - 1
_GUICtrlListView_AddItem($hListView, $aErrorsNew[$i])
Next
_GUICtrlListView_SetItemSelected($hListView, 0)
EndIf
GUICtrlSetState($hButton1, $GUI_ENABLE)
GUICtrlSetState($ListView, $GUI_FOCUS)
EndSwitch
WEnd

Func __ErrorLog()
GUICtrlSetState($hButton1, $GUI_DISABLE)
Local $sLog = '', $hError, $aErrorsTemp, $i
Dim $aErrors[1]
$hError = Run('CSCRIPT.exe ' & @SystemDir & '\eventquery.vbs /v /fi "Type eq ERROR" /fo TABLE /NH', '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hError)
If @error Then ExitLoop
;Sleep(10)
WEnd
If Not $sLog Then Return 0
$aErrorsTemp = StringSplit(_Encoding_866To1251($sLog), @LF)
If Not IsArray($aErrorsTemp) Then Return 0
Dim $aErrors[$aErrorsTemp[0]]
For $i = 1 To $aErrorsTemp[0]
If StringInStr($aErrorsTemp[$i], "ошибка") Then
$aErrors[0] += 1
$aErrors[$aErrors[0]] = StringStripWS(StringStripCR($aErrorsTemp[$i]), 7)
EndIf
Next
If $aErrors[0] < 1 Then Return 0
ReDim $aErrors[$aErrors[0]+1]
Return $aErrors
EndFunc ;==>__ErrorLog

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
Local $tNMITEMACTIVATE = DllStructCreate($tagNMITEMACTIVATE, $lParam)
Local $hFrom = DllStructGetData($tNMITEMACTIVATE, 'hWndFrom')
Local $Index = DllStructGetData($tNMITEMACTIVATE, 'Index')
Local $ID = DllStructGetData($tNMITEMACTIVATE, 'Code')

Switch $hFrom
Case $hListView
Switch $ID
Case $LVN_ITEMCHANGED
If (BitAND(DllStructGetData($tNMITEMACTIVATE, 'Changed'), $LVIF_STATE)) And _
(BitAND(DllStructGetData($tNMITEMACTIVATE, 'NewState'), $LVIS_SELECTED)) _
And (Not BitAND(DllStructGetData($tNMITEMACTIVATE, 'OldState'), $LVIS_FOCUSED)) Then
_ErrorHelp($Index)
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY

Func _ErrorHelp($Index)
Local $iNumberError, $hHelp, $sLog = ''
GUICtrlSetState($hButton1, $GUI_DISABLE)
GUICtrlSetState($hListView, $GUI_DISABLE)
$sItemText = _GUICtrlListView_GetItemText($hListView, $Index)
$iNumberError = StringRegExpReplace($sItemText, "(?s).*?ошибка (.*?)\s+?.*", '\1')
$hHelp = Run('net helpmsg ' & $iNumberError, '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hHelp)
If @error Then ExitLoop
;Sleep(10)
WEnd
$sLog = StringStripWS(StringStripCR(_Encoding_866To1251($sLog)), 7)
GUICtrlSetData($hInput, 'Ошибка № ' & $iNumberError & ' - ' & $sLog)
GUICtrlSetData($hInputAll, $sItemText)
GUICtrlSetState($hButton1, $GUI_ENABLE)
GUICtrlSetState($hListView, $GUI_ENABLE)
EndFunc ;==>_ErrorHelp

при клике на строке в окне GUICtrlCreateListView, происходит ее выделение, а при попытке кликнуть по другой строке не происходит выделение последней. »
Очень странный аргумент. Какой другой, и почему должна выделяться последняя строка?

saavaage
21-08-2010, 19:51
Creat0R, я имел ввиду последняя - та, по которой кликнул в последний раз! :-) Понял - просто было подвисание, которое вы убрали. Спасибо.

madmasles
21-08-2010, 20:09
saavaage,
Вот что у меня получилось с полным отображением строк. Строки делятся на части и вставляются в разные колонки одной строки:#include <Constants.au3>
#include <Encoding.au3>
#include <GUIConstantsEx.au3>
#include <GUIListview.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Opt('MustDeclareVars', 1)

Global $hForm1, $hButton1, $hInput, $ListView, $hListView, $aErrorsNew, $nMsg, $iX
Dim $aToList = __ErrorLog()

$hForm1 = GUICreate("Form1", 620, 445, -1, -1)
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
$hButton1 = GUICtrlCreateButton("Обновить", 16, 120, 65, 57)
$hInput = GUICtrlCreateEdit('', 95, 10, 400, 34, BitOR($ES_READONLY, $ES_MULTILINE))
$ListView = GUICtrlCreateListView('', 95, 60, 400, 320, -1, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
GUICtrlSetState(-1, $GUI_FOCUS)
$hListView = GUICtrlGetHandle($ListView)
GUICtrlSetTip(-1, "Выделите мышкой строку," & @CRLF & "чтобы получить подсказку.")
If $aToList <> 0 Then
_GUICtrlListView_AddColumn($hListView, 'Список событий с ошибками', 50)
_GUICtrlListView_AddColumn($hListView, '')
For $i = 1 To UBound($aToList) - 1
_GUICtrlListView_AddItem($hListView, $aToList[$i][0])
_GUICtrlListView_AddSubItem($hListView, $i - 1, $aToList[$i][1], 1)
Next
_GUICtrlListView_SetColumnWidth($hListView, 0, $LVSCW_AUTOSIZE)
_GUICtrlListView_SetColumnWidth($hListView, 1, $LVSCW_AUTOSIZE)
_GUICtrlListView_SetItemSelected($hListView, 0)
EndIf

GUISetState(@SW_SHOW)

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $hButton1
GUICtrlSetState($hButton1, $GUI_DISABLE)
GUICtrlSetData($hInput, '')
$aErrorsNew = __ErrorLog()
If $aErrorsNew <> 0 Then
_GUICtrlListView_DeleteAllItems($hListView)
For $i = 1 To UBound($aErrorsNew) - 1
_GUICtrlListView_AddItem($hListView, $aToList[$i][0])
_GUICtrlListView_AddSubItem($hListView, $i - 1, $aToList[$i][1], 1)
Next
_GUICtrlListView_SetColumnWidth($hListView, 0, $LVSCW_AUTOSIZE)
_GUICtrlListView_SetColumnWidth($hListView, 1, $LVSCW_AUTOSIZE)
_GUICtrlListView_SetItemSelected($hListView, 0)
SoundPlay(@WindowsDir & '\Media\tada.wav');звук будет только, если точно обновились.
EndIf
GUICtrlSetState($hButton1, $GUI_ENABLE)
GUICtrlSetState($ListView, $GUI_FOCUS)
EndSwitch
WEnd

Func __ErrorLog()
Local $sLog = '', $j = 0, $hError, $aErrorsTemp, $i, $sError, $sError_0, $sError_1, $sError_Temp
Dim $aErrors[1][2]
$hError = Run('CSCRIPT.exe ' & @SystemDir & '\eventquery.vbs /v /fi "Type eq ERROR" /fo TABLE /NH', '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hError)
If @error Then ExitLoop
Sleep(10)
WEnd
If Not $sLog Then Return 0
$aErrorsTemp = StringSplit(_Encoding_866To1251($sLog), @LF)
If Not IsArray($aErrorsTemp) Then Return 0
For $i = 1 To $aErrorsTemp[0]
If StringInStr($aErrorsTemp[$i], "ошибка") Then
ReDim $aErrors[UBound($aErrors) + 1][2]
$j += 1
$sError = StringStripWS(StringStripCR($aErrorsTemp[$i]), 7)
If StringLen($sError) > 260 Then
$sError_0 = StringLeft($sError, 240)
$sError_Temp = StringTrimLeft($sError, 240)
$sError_Temp = StringLeft($sError_Temp, StringInStr($sError_Temp, ' '))
$sError_0 &= $sError_Temp
$sError_1 = StringTrimLeft($sError, StringLen($sError_0))
$aErrors[$j][0] = $sError_0
$aErrors[$j][1] = $sError_1
Else
$aErrors[$j][0] = $sError
$aErrors[$j][1] = ''
EndIf
EndIf
Next
$aErrors[0][0] = UBound($aErrors) - 1
If UBound($aErrors) < 2 Then Return 0
Return $aErrors
EndFunc ;==>__ErrorLog

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
Local $tNMITEMACTIVATE = DllStructCreate($tagNMITEMACTIVATE, $lParam)
Local $hFrom = DllStructGetData($tNMITEMACTIVATE, 'hWndFrom')
Local $Index = DllStructGetData($tNMITEMACTIVATE, 'Index')
Local $ID = DllStructGetData($tNMITEMACTIVATE, 'Code')

Switch $hFrom
Case $hListView
Switch $ID
Case $LVN_ITEMCHANGED
If (BitAND(DllStructGetData($tNMITEMACTIVATE, 'Changed'), $LVIF_STATE)) And _
(BitAND(DllStructGetData($tNMITEMACTIVATE, 'NewState'), $LVIS_SELECTED)) _
And (Not BitAND(DllStructGetData($tNMITEMACTIVATE, 'OldState'), $LVIS_FOCUSED)) Then
_ErrorHelp($Index)
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY

Func _ErrorHelp($Index)
Local $iNumberError, $hHelp, $sLog = ''
GUICtrlSetState($hButton1, $GUI_DISABLE)
GUICtrlSetState($hListView, $GUI_DISABLE)
$iNumberError = StringRegExpReplace(_GUICtrlListView_GetItemText($hListView, $Index), "(?s).*?ошибка (.*?)\s+?.*", '\1')
$hHelp = Run('net helpmsg ' & $iNumberError, '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hHelp)
If @error Then ExitLoop
Sleep(10)
WEnd
$sLog = StringStripWS(StringStripCR(_Encoding_866To1251($sLog)), 7)
If Not $sLog Then $sLog = 'не удается найти текст сообщения с номером ' & $iNumberError & _
' в файле сообщений NETMSG.'
GUICtrlSetData($hInput, 'Ошибка № ' & $iNumberError & ' - ' & $sLog)
GUICtrlSetState($hButton1, $GUI_ENABLE)
GUICtrlSetState($hListView, $GUI_ENABLE)
DllCall('user32.dll', 'long', 'SendMessage', 'hwnd', $hForm1, 'int', 0x0111, 'int', 0x7103, 'int', 0)
EndFunc ;==>_ErrorHelp

saavaage
21-08-2010, 20:21
madmasles, работает! Но, имхо, лучше для восприятия информации, вариант - с выводом полной информации в GuiCtrlEdit. Легче считывать инфу.
Посмотрите, кстати, что предложил Creat0R для ускорения скрипта (пост №7). Раньше у меня было небольшое подвисание (иногда клик по строке происходил через раз), теперь все гут.

madmasles, Creat0R, Спасибо за Помощь!

Тема решена!

saavaage
22-08-2010, 22:59
Убрал, имхо, за ненадобностью строки из скрипта (пост 7):

GUICtrlSetTip(-1, "Выделите мышкой строку," & @CRLF & "чтобы получить подсказку.")

и в Func _ErrorHelp($Index):
в начале:
GUICtrlSetState($hButton1, $GUI_DISABLE)
GUICtrlSetState($hListView, $GUI_DISABLE)
в конце:
GUICtrlSetState($hButton1, $GUI_ENABLE)
GUICtrlSetState($hListView, $GUI_ENABLE)

Окончательный код:
#include <Encoding.au3>
#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListview.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>


Global $hForm1, $hButton1, $hInput, $ListView, $hListView, $aErrorsNew, $nMsg
Dim $aToList = __ErrorLog()

$hForm1 = GUICreate("Form1", 620, 445, -1, -1)
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
$hButton1 = GUICtrlCreateButton("Обновить", 16, 120, 65, 57)
$hInput = GUICtrlCreateEdit('', 95, 10, 400, 34, BitOR($ES_READONLY, $ES_MULTILINE))
$hInputAll = GUICtrlCreateEdit('', 95, 385, 400, 55, BitOR($ES_READONLY, $ES_MULTILINE, $WS_VSCROLL))
$ListView = GUICtrlCreateListView('Список событий с ошибками', 95, 60, 400, 320, -1, $LVS_EX_GRIDLINES)
GUICtrlSetState(-1, $GUI_FOCUS)
$hListView = GUICtrlGetHandle($ListView)
_GUICtrlListView_SetColumnWidth($hListView, 0, 2000)
;GUICtrlSetTip(-1, "Выделите мышкой строку," & @CRLF & "чтобы получить подсказку.")
If $aToList <> 0 Then
_GUICtrlListView_AddColumn($hListView, '')
For $i = 1 To UBound($aToList) - 1
_GUICtrlListView_AddItem($hListView, $aToList[$i])
Next
_GUICtrlListView_SetItemSelected($hListView, 0)
EndIf

GUISetState(@SW_SHOW)

While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $hButton1
GUICtrlSetData($hInput, '')
GUICtrlSetData($hInputAll, '')
$aErrorsNew = __ErrorLog()
If $aErrorsNew <> 0 Then
_GUICtrlListView_DeleteAllItems($hListView)
For $i = 1 To UBound($aErrorsNew) - 1
_GUICtrlListView_AddItem($hListView, $aErrorsNew[$i])
Next
_GUICtrlListView_SetItemSelected($hListView, 0)
EndIf
GUICtrlSetState($hButton1, $GUI_ENABLE)
GUICtrlSetState($ListView, $GUI_FOCUS)
EndSwitch
WEnd

Func __ErrorLog()
GUICtrlSetState($hButton1, $GUI_DISABLE)
Local $sLog = '', $hError, $aErrorsTemp, $i
Dim $aErrors[1]
$hError = Run('CSCRIPT.exe ' & @SystemDir & '\eventquery.vbs /v /fi "Type eq ERROR" /fo TABLE /NH', '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hError)
If @error Then ExitLoop
;Sleep(10)
WEnd
If Not $sLog Then Return 0
$aErrorsTemp = StringSplit(_Encoding_866To1251($sLog), @LF)
If Not IsArray($aErrorsTemp) Then Return 0
Dim $aErrors[$aErrorsTemp[0]]
For $i = 1 To $aErrorsTemp[0]
If StringInStr($aErrorsTemp[$i], "ошибка") Then
$aErrors[0] += 1
$aErrors[$aErrors[0]] = StringStripWS(StringStripCR($aErrorsTemp[$i]), 7)
EndIf
Next
If $aErrors[0] < 1 Then Return 0
ReDim $aErrors[$aErrors[0]+1]
Return $aErrors
EndFunc ;==>__ErrorLog

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
Local $tNMITEMACTIVATE = DllStructCreate($tagNMITEMACTIVATE, $lParam)
Local $hFrom = DllStructGetData($tNMITEMACTIVATE, 'hWndFrom')
Local $Index = DllStructGetData($tNMITEMACTIVATE, 'Index')
Local $ID = DllStructGetData($tNMITEMACTIVATE, 'Code')

Switch $hFrom
Case $hListView
Switch $ID
Case $LVN_ITEMCHANGED
If (BitAND(DllStructGetData($tNMITEMACTIVATE, 'Changed'), $LVIF_STATE)) And _
(BitAND(DllStructGetData($tNMITEMACTIVATE, 'NewState'), $LVIS_SELECTED)) _
And (Not BitAND(DllStructGetData($tNMITEMACTIVATE, 'OldState'), $LVIS_FOCUSED)) Then
_ErrorHelp($Index)
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY

Func _ErrorHelp($Index)
Local $iNumberError, $hHelp, $sLog = ''
;GUICtrlSetState($hButton1, $GUI_DISABLE)
;GUICtrlSetState($hListView, $GUI_DISABLE)
$sItemText = _GUICtrlListView_GetItemText($hListView, $Index)
$iNumberError = StringRegExpReplace($sItemText, "(?s).*?ошибка (.*?)\s+?.*", '\1')
$hHelp = Run('net helpmsg ' & $iNumberError, '', @SW_HIDE, $STDOUT_CHILD)
While 1
$sLog &= StdoutRead($hHelp)
If @error Then ExitLoop
;Sleep(10)
WEnd
$sLog = StringStripWS(StringStripCR(_Encoding_866To1251($sLog)), 7)
GUICtrlSetData($hInput, 'Ошибка № ' & $iNumberError & ' - ' & $sLog)
GUICtrlSetData($hInputAll, $sItemText)
;GUICtrlSetState($hButton1, $GUI_ENABLE)
;GUICtrlSetState($hListView, $GUI_ENABLE)
EndFunc ;==>_ErrorHelp




© OSzone.net 2001-2012