Что нового

Избавиться от квадрата с плюсом при перетаскивании строки (ListView & WM_Notify)

saavaage

Знающий
Сообщения
171
Репутация
17
Есть скрипт:
Код:
#include <ButtonConstants.au3>
#include <Constants.au3>
#include <EditConstants.au3>
#include <Encoding.au3>
#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <TreeViewConstants.au3>
#include <ListViewConstants.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>


; EventLogs
Global $hMain_GUI, $nErrorRenew_Button, $hInput, $hInputAll, $ListViewEv, $hListViewEv, $aErrorsNew, $PicError;, $EventErrors


Opt("GUIOnEventMode", 1)




$hMain_GUI = GUICreate("", 619, 442, 189, 122)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")

$Tab1 = GUICtrlCreateTab(8, 16, 601, 377)

;;;; EventLogs ;;;;
Dim $aToList = __ErrorLog()
$EventErrors = GUICtrlCreateTabItem("EventLogs")
$nErrorRenew_Button = GUICtrlCreateButton("Обновить", 440, 400, 85, 33, 0)
GUICtrlSetTip(-1, "Обновить текущее состояние вкладки")
GUICtrlSetOnEvent($nErrorRenew_Button, "_ErrorRenew_Button")

GUICtrlCreateGroup("Расшифровка кода ошибки", 16, 65, 585, 63)
$hInput = GUICtrlCreateEdit('', 24, 80, 570, 39, BitOR($ES_READONLY, $ES_MULTILINE, $WS_VSCROLL))
$ListViewEv = GUICtrlCreateListView('Список Errors логов системы', 16, 133, 585, 169, -1, $LVS_EX_GRIDLINES)
GUICtrlSetState(-1, $GUI_FOCUS)
GUICtrlCreateGroup("Полное описание выделенной ошибки", 16, 305, 585, 82)
$hInputAll = GUICtrlCreateEdit('', 24, 320, 570, 59, BitOR($ES_READONLY, $ES_MULTILINE, $WS_VSCROLL))

GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')

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

GUICtrlCreateTabItem("")

GUISetState()

While 1
    Sleep(100)
WEnd


Func CLOSEClicked()
  Exit
EndFunc


;; ErrorsLog Section ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Func PCCenter_Button()
ShellExecute('eventvwr.exe')
EndFunc

Func OnlineCenter_Button()
ShellExecute('http://www.support.microsoft.com/gp/errormessage/ru')
EndFunc

Func Eventid_Button()
ShellExecute('http://www.eventid.net')
EndFunc

Func _ErrorRenew_Button()
	        GUICtrlSetState($nErrorRenew_Button, $GUI_DISABLE)
			_GUICtrlListView_DeleteAllItems($hListViewEv)
			GUICtrlSetData($hInput, '')
            GUICtrlSetData($hInputAll, '')
            $aErrorsNew = __ErrorLog()
            If $aErrorsNew <>0 Then
                For $i = 1 To UBound($aErrorsNew) - 1
				_GUICtrlListView_AddItem($hListViewEv, $aErrorsNew[$i])
                Next
                _GUICtrlListView_SetItemSelected($hListViewEv, 0)
			EndIf
            sleep(1000)
			GUICtrlSetState($nErrorRenew_Button, $GUI_ENABLE)
            GUICtrlSetState($ListViewEv, $GUI_FOCUS)
EndFunc

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 $hListViewEv
            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

Func __ErrorLog()
    GUICtrlSetState($nErrorRenew_Button, $GUI_DISABLE)
    Local $sLog = '', $hError, $aErrorsTemp, $i
    Dim $aErrors[1]
    $hError = Run('CSCRIPT.exe ' & @SystemDir & '\eventquery.vbs /v /fi "Type eq ERROR" /fo TABLE /r 20 /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 _ErrorHelp($Index)
    Local $iNumberError, $hHelp, $sLog = ''
    GUICtrlSetState($hListViewEv, $GUI_DISABLE)
	$sItemText = _GUICtrlListView_GetItemText($hListViewEv, $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($hListViewEv, $GUI_ENABLE)
EndFunc   ;==>_ErrorHelp

Все работает нормально, но есть один нюанс - если юзер нечаянно пытается перетянуть строку, возникает квадаратик с плюсом, который в определенных условиях становится непрозрачным (темным квадратом) и остается на экране до обновления.
Можно ли каким-нибудь образом вообще избавиться от этого значка?

PS Доп. библиотеку Encoding.au3 см. в аттаче
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
"+", это иконка в ресурсах скомпилированного файла по номером 169. Я ее просто заменяю на пустую иконку 16x16x32bpp.
 
Автор
S

saavaage

Знающий
Сообщения
171
Репутация
17
мда, проще некуда. Сейчас попробую...


Добавлено:
Сообщение автоматически объединено:

Yashied, пустышку просто записать под тем же номером?


Добавлено:
Сообщение автоматически объединено:

попробовал, одно и тоже, только окошко стало в виде пустышки... Т.е. там теперь выводится изображение, общее для всех неизвестных приложений... Вообще устранить это окно, я так понимаю, нельзя?


Добавлено:
Сообщение автоматически объединено:

Кажется понял о чем Вы... Сейчас возьму редактор ArtIcon и попробую в внем...



Добавлено:
Сообщение автоматически объединено:

Все получилось! Спасибо за совет!
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Можно еще так:

Код:
#Include <GUIConstantsEx.au3>
#Include <GUIListView.au3>
#Include <ListViewConstants.au3>
#Include <WindowsConstants.au3>

GUICreate('MyGUI', 300, 300)
$ListView = GUICtrlCreateListView('Column', 10, 10, 280, 280)
GUICtrlCreateListViewItem('Item', -1)
GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)

	Local $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    Local $ID = DllStructGetData($tNMHDR, 'Code')

    Switch $wParam
        Case $ListView
            Switch $ID
				Case $LVN_BEGINDRAG
					Return 0
			EndSwitch
	EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
 
Автор
S

saavaage

Знающий
Сообщения
171
Репутация
17
что-то подобное я и хотел. Спасибо. Не подскажете, где можно посмотреть help по $WM_NOTIFY. В частности, по таким условиям, как $LVN_BEGINDRAG, $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

только более жестче что ли. Не подскажете, насколько эти строки нужны?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
saavaage сказал(а):
Не подскажете, где можно посмотреть help по $WM_NOTIFY. В частности, по таким условиям, как $LVN_BEGINDRAG, $LVN_ITEMCHANGED и т.д.?

http://msdn.microsoft.com/en-us/library/ff485962%28VS.85%29.aspx

saavaage сказал(а):
...скрипт работает и без срок:
Код:
If (BitAND(DllStructGetData($tNMITEMACTIVATE, 'Changed'), $LVIF_STATE)) And _
                            (BitAND(DllStructGetData($tNMITEMACTIVATE, 'NewState'), $LVIS_SELECTED)) _
                            And (Not BitAND(DllStructGetData($tNMITEMACTIVATE, 'OldState'), $LVIS_FOCUSED)) Then

только более жестче что ли. Не подскажете, насколько эти строки нужны?

Проверяет, что элемент действительно выделен (не клик по пустому месту) и отсекает повторные клики на одном и том же элементе. Без этого, функция _ErrorHelp() будет вызываться при любом клике в ListView, что не есть хорошо.
 
Автор
S

saavaage

Знающий
Сообщения
171
Репутация
17
На всякий случай выкладываю правильный код функции WM_NOTIFY:

Код:
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 $hListViewEv
            Switch $ID
                Case $LVN_BEGINDRAG
                    Return 0
                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


Тема решена.
 
Верх