URLLogin = https://example.com/?a=login
Login =
Pass =
Debug = ; указать имя секции для обработки ошибок, иначе должно быть пусто
CountProc = 4 ; кол-во браузеров
MinRange = 1 ; от
MaxRange = 55 ; до
Add = 0 ; Add = 1 то прибавлять, если 0 то отнимать
ErrorTime := 30000 ; Период в мс с момента последнего сообщения от скрипта, через который он считается нерабочим
CheckTime := 2000 ; Период в мс обновления инфо
#SingleInstance Force
#NoEnv
SetBatchLines -1
ListLines Off
DetectHiddenWindows, On
SetWorkingDir, %A_ScriptDir%
ThisPID := DllCall("GetCurrentProcessId")
Menu, Tray, UseErrorLevel
Menu, Tray, Click, 1
Menu, Tray, NoStandard
Menu, Tray, Add, Min/Max, MinMax
Menu, Tray, Default, Min/Max
Menu, Tray, Disable, Min/Max
Try Menu, Tray, Icon, Shell32.dll, 239
Menu, Tray, Add, ExitApp
Global oIE, CurrentURL, ThisPID, oAll := [], oCLV, HLV, IniSection, IEMode, StartTime
, ErrorCount := 0, ErrorRest := 0, CountLink := 0, CheckTime, ErrorTime, FullComplete
OnExit, ExitApp
Gui, IE:+ReSize -DPIScale +HWNDhGui
Gui, IE:Add, Edit, w830 r1 vURLGui
Gui, IE:Add, Button, x+6 yp w44 gButtonGo, Go
Gui, IE:Add, ActiveX, xm w880 h640 voIE HWNDhoIE, Shell.Explorer
oIE.Silent := 1, IEMode := 1
ComObjError(false)
ComObjConnect(oIE, WB_events)
Gui, IE:Show
oIE.Navigate(CurrentURL := URLLogin)
IEBusy()
MsgBox, 4160, Url parser, Ввести логин
oIE.document.querySelector("#username").value := Login
oIE.document.querySelector("#password").value := Pass
oIE.document.querySelector("input[class='home-btn form-submit']").click()
Sleep 444
IEBusy()
MsgBox, 4132, Url parser, Начать работу?
IfMsgBox No
GoTo ExitApp2
IEMode := 0
oIE.Stop(), oIE.Close(), oIE.Quit()
oIE := "", DllCall("DestroyWindow", "Ptr", hoIE)
Gui, IE:Destroy
Gui, -DPIScale +HWNDhGui
Gui, Add, Text, xm ym w630 r1 vTextInfo cBlue
Gui, Add, Text, wp y+20 r1 vTextProgress cGreen
; 1 2 3 4 5 6
Gui, Add, ListView, r20 wp hwndHLV Grid, № |Диапазон|Количество|Выполнено|Осталось|Прогресс| |
Gui, Font, s12
Gui, Add, Text, Border xp y+10 vButtonView gButtonView, % " Показать окно "
Gui, Add, Text, Border x+30 gManualCheck vManualCheck, % " Проверить "
Gui, Add, Text, Border x+60 gCloseScript vCloseScript, % " Закрыть "
Gui, Show, , Url parser
oCLV := New LV_Colors(HLV)
StartTime := A_TickCount
FormatTime, IniSection, , yyyy_MM_dd_HH_mm_ss
FormatTime, StrTime, , HH:mm:ss d - MMMM
If Debug
{
IniRead, str, Log.ini, %Debug%, All
Add := StrSplit(str, "|")[3]
IniRead, Section, Log.ini, %Debug%
IniWrite("Debug|Debug|" Add "|Debug|" Debug, "All")
CountProc := 0
Loop, Parse, Section, `n
{
If A_Index = 1
Continue
Index := A_Index - 1, Field := A_LoopField, ++CountProc
Gui, Add, Edit, Hidden +ReadOnly w0 h0 HwndhControl, 0|%A_TickCount% ; gEvent Hidden w0 h0 w111, 0
Min := StrSplit(Field, "|")[2]
Max := StrSplit(Field, "|")[3]
Cmp := StrSplit(Field, "=")[2]
If Add
Min := Min + Cmp
Else
Max := Max - Cmp
Count := Max - Min + 1
CountLink += Count
LV_Add(Index, Index, Min " - " Max, Count, 0, Count, "0`%")
Run, "Url parser child.ahk" "%Index%" "%Min%" "%Max%" "%Add%" "%ThisPID%" "%hControl%", , Hide, PID
oAll[Index] := {PID:PID,Index:Index,Min:Min,Max:Max,Time:A_TickCount
,Count:Count,Item:0,hControl:hControl,IniKey:Index "|" Min "|" Max "|"}
IniWrite(0, oAll[Index].IniKey)
WinWait, % "ahk_pid " PID, , 5
Sleep 111
; MsgBox, 4160, Url parser, % Field "`n" Min "`n" Max "`n" Cmp "`n" Count
}
GuiControl, , TextInfo, % "Запущено в: " StrTime " \\ DEBUG MODE!!!"
. " \\ Запущено в " CountProc " скриптах. \\ " (Add ? "Плюсовать" : "Минусовать")
GuiControl, , TextProgress, % "Всего адресов: " CountLink " \\ Выполнено: " 0
. " \\ Прогресс: " 0 "`% \\ Всего ошибок: " 0
}
Else
{
CountLink := MaxRange - MinRange + 1
step := CountLink // CountProc
rest := CountLink - (step * CountProc)
prevmax := MinRange
GuiControl, , TextInfo, % "Запущено в: " StrTime " \\ Диапазон: " MinRange " - " MaxRange
. " \\ Запущено в " CountProc " скриптах. \\ " (Add ? "Плюсовать" : "Минусовать")
GuiControl, , TextProgress, % "Всего адресов: " CountLink " \\ Выполнено: " 0
. " \\ Прогресс: " 0 "`% \\ Всего ошибок: " 0
; 1 2 3 4 5
IniWrite(MinRange "|" MaxRange "|" Add "|" CountLink "|" CountProc, "All")
Loop % CountProc
{
Gui, Add, Edit, Hidden +ReadOnly w0 h0 HwndhControl, 0|%A_TickCount% ; gEvent Hidden w0 h0 w111, 0
Min := prevmax
Max := prevmax + step + (!!rest) - 1
prevmax := Max + 1
(rest && (--rest))
Count := Max - Min + 1
LV_Add(A_Index, A_Index, Min " - " Max, Count, 0, Count, "0`%")
Run, "Url parser child.ahk" "%A_Index%" "%Min%" "%Max%" "%Add%" "%ThisPID%" "%hControl%", , Hide, PID
oAll[A_Index] := {PID:PID,Index:A_Index,Min:Min,Max:Max,Time:A_TickCount
,Count:Count,Item:0,hControl:hControl,IniKey:A_Index "|" Min "|" Max "|"}
IniWrite(0, oAll[A_Index].IniKey)
WinWait, % "ahk_pid " PID, , 5
Sleep 111
}
}
Loop % LV_GetCount("Col")
LV_ModifyCol(A_Index, "AutoHdr")
SetTimer, Check, -500
Return
^+Delete::
MsgBox, 4404, Url parser, Точно закрыть все скрипты?
IfMsgBox No
Return
CloseAllChild()
Return
ManualCheck:
SetTimer, Check, -1
GuiControl, +Redraw, %HLV%
Return
Check() {
GuiControl, Disable, ManualCheck
For Index, arr in oAll.Clone() {
If (arr.Complete || arr.Error)
Continue
GuiControlGet, Text, , % arr.hControl
oP := StrSplit(Text, "|")
for k, v in ["Item","Time"]
%v% := oP[k]
If (Item + 0 = "") && !oAll[Index].Item
oAll[Index].Item := (Item := 0)
Else If (Item + 0 = "")
Item := oAll[Index].Item
If (Time + 0 != "")
arr.Time := Time
Else
Time := arr.Time
If (Item = arr.Count) {
oCLV.Row(Index, 0x34CC06, 0xFFFFFF)
oAll[Index].Complete := 1
IniDelete(arr.IniKey)
}
Else If !WinExist("ahk_pid " arr.PID) || ((A_TickCount - Time) > ErrorTime) {
++ErrorCount, ErrorRest += arr.Count - Item
oCLV.Row(Index, 0xEA5E2C, 0xFFFFFF)
oAll[Index].Error := 1
Process, Close, % arr.PID
}
If LV__ModifyCell(Index, 4, Item) && !oAll[Index].Complete
IniWrite(Item, arr.IniKey)
LV__ModifyCell(Index, 5, arr.Count - Item)
LV__ModifyCell(Index, 6, Percent(arr.Count, Item) "`%")
}
Loop % LV_GetCount() + (AllLinkCheck := 0)
{
LV_GetText(Text, A_Index, 4)
AllLinkCheck += Text
}
GuiControl, +Redraw, %HLV%
SetTimer, Redraw, -333
GuiControl, , TextProgress, % "Всего адресов: " CountLink " \\ Выполнено: " AllLinkCheck
. " \\ Прогресс: " Percent(CountLink, AllLinkCheck) "`% \\ Всего ошибок: " ErrorCount " \\ Невыполнено: " ErrorRest
GuiControl, Enable, ManualCheck
If ((AllLinkCheck + ErrorRest) = CountLink) && (FullComplete := 1)
MsgBox, 4160, Url parser, % "Работа завершена!" (ErrorCount ? "`n`nЕсть ошибки!!!" : "") "`n`nВыполнено за: " FormatTime(A_TickCount - StartTime)
Else
SetTimer, Check, -%CheckTime%
}
Redraw:
DllCall("RedrawWindow", "Ptr", HLV, "Uint", 0, "Uint", 0, "Uint", 0x1|0x4)
Return
Event(CtrlHwnd) {
; GuiControlGet, Text,, %CtrlHwnd%
Return 1
}
LV__ModifyCell(Row, Col, Text) {
LV_GetText(GetText, Row, Col)
If (GetText != Text)
LV_ModifyCell(Row, Col, Text), bool := 1
Return bool
}
Percent(whole, part) {
Return Round(100 / (whole / part), 1)
}
ButtonView() {
Loop % LV_GetCount("S") + (sRow := 0)
{
sRow := LV_GetNext(sRow)
LV_GetText(Text, sRow, 1)
WinShow, % "AHK_pid" oAll[Text].PID " ahk_class AutoHotkeyGUI"
}
}
CloseScript() {
MsgBox, 4404, Url parser, Точно закрыть все выделенные скрипты?
IfMsgBox No
Return
Loop % LV_GetCount("S") + (sRow := 0)
{
sRow := LV_GetNext(sRow)
LV_GetText(Text, sRow, 1)
Process, Close, % oAll[Text].PID
}
}
CloseAllChild() {
Query := "SELECT * FROM Win32_Process WHERE Caption = 'AutoHotkey.exe' AND ProcessId != " DllCall("GetCurrentProcessId")
For Proc In ComObjGet("winmgmts:").ExecQuery(Query)
{
RegExMatch(Proc.CommandLine, "Si).*""(?<Name>.*)\.ahk""", _)
If _Name = %A_ScriptDir%\Url parser child
Proc.Terminate()
}
}
IniRead(Key, Error := " ") {
IniRead, Value, Log.ini, %IniSection%, %Key%, %Error%
Return Value
}
IniWrite(Value, Key) {
IniWrite, %Value%, Log.ini, %IniSection%, %Key%
Return Value
}
IniDelete(Key) {
IniDelete, Log.ini, %IniSection%, %Key%
Return Value
}
FormatTime(Time) {
Local Rest, Hours, Min, Sec, MSec
If Time < 0
Return "00:00:00"
Rest := Mod(Time, 3600000)
Hours := Format("{:02d}", Time // 3600000)
Min := Format("{:02d}", Rest // 60000)
Sec := Format("{:02d}", Mod(Rest, 60000) // 1000)
; MSec := Format("{:03d}", Mod(Rest, 1000))
Return Hours ":" Min ":" Sec
}
IEGuiSize:
If A_EventInfo = 1
GoTo GuiClose
If IEMode
WinMove, ahk_id %hoIE%, , 0, 30, A_GuiWidth, A_GuiHeight-31
Return
MinMax:
Gui, % (IEMode ? "IE:" : "") "Show", % !DllCall("IsWindowVisible", "Ptr", hGui) ? "" : "Hide"
Return
ButtonGo:
Gui, IE:Submit, NoHide
oIE.Navigate(URLGui)
Return
GuiClose:
GuiEscape:
Gui, % (IEMode ? "IE:" : "") "Hide"
Return
ExitApp:
MsgBox, 4404, Url parser, Точно закрыть?
IfMsgBox No
Return
ExitApp2:
Try oIE.Quit(), oIE := ""
OnExit
Gui, IE:Destroy
Gui, Destroy
CloseAllChild()
ExitApp
IEBusy() {
While !(oIE.readyState=4 && oIE.document.readyState="complete" && !oIE.busy)
Sleep, 50
}
class WB_events
{
NavigateComplete2(IE, NewURL)
{
GuiControl, IE:, URLGui, % oIE.LocationURL ; Update the URL edit control.
; GuiControl,, URLGui, % NewURL ; Update the URL edit control.
}
BeforeNavigate2(pDsip, url, flags, TargetFrameName, PostData, headers, cancel)
{
; If (CurrentURL != url)
; cancel[] := true ; NumPut(-1, ComObjValue(cancel), "Short")
}
}
FixIE(param) {
Static Key := "Software\Microsoft\Internet Explorer\MAIN"
. "\FeatureControl\FEATURE_BROWSER_EMULATION", _ := FixIE(0)
If A_IsCompiled
ExeName := A_ScriptName
Else
SplitPath, A_AhkPath, ExeName
RegRead, value, HKCU, %Key%, %ExeName%
If (value != param)
RegWrite, REG_DWORD, HKCU, %Key%, %ExeName%, %param%
}
IESoundsOff() {
Static Key := "Software\Microsoft\Internet Explorer\Main", _ := IESoundsOff()
RegRead, Value, HKCU, %Key%, Play_Background_Sounds
If Value != no
RegWrite, REG_SZ, HKCU, %Key%, Play_Background_Sounds, no ; no || yes
}
#If IEMode && WinActive("ahk_id " hGui)
^vk43:: oIE.document.selection.createRange().execCommand("COPY") ; Ctrl + C
^vk56:: oIE.document.selection.createRange().execCommand("PASTE") ; Ctrl + V
Enter:: rng := oIE.document.selection.createRange(), rng.text := "`n", rng.select()
Del:: rng := oIE.document.selection.createRange()
, (rng.text = "" && rng.moveEnd("character", 1))
, rng.execCommand("DELETE")
^vk41:: oIE.document.execCommand("SELECTALL") ; Ctrl + A
^vk58:: oIE.document.selection.createRange().execCommand("CUT") ; Ctrl + X
^vk59:: oIE.document.execCommand("REDO") ; Ctrl + Y
^vk5A:: oIE.document.execCommand("UNDO") ; Ctrl + Z
F5:: oIE.document.execCommand("Refresh")
#If
LV_ModifyCell(Row, Col, Text) {
If (Row > LV_GetCount())
LV_Insert(Row, "Col" Col, Text)
Else
LV_Modify(Row, "Col" Col, Text)
}
; ======================================================================================================================
; Namespace: LV_Colors
; Function: Individual row and cell coloring for AHK ListView controls.
; Tested with: AHK 1.1.23.05 (A32/U32/U64)
; Tested on: Win 10 (x64)
; Changelog:
; 1.1.04.01/2016-05-03/just me - added change to remove the focus rectangle from focused rows
; 1.1.04.00/2016-05-03/just me - added SelectionColors method
; 1.1.03.00/2015-04-11/just me - bugfix for StaticMode
; 1.1.02.00/2015-04-07/just me - bugfixes for StaticMode, NoSort, and NoSizing
; 1.1.01.00/2015-03-31/just me - removed option OnMessage from __New(), restructured code
; 1.1.00.00/2015-03-27/just me - added AlternateRows and AlternateCols, revised code.
; 1.0.00.00/2015-03-23/just me - new version using new AHK 1.1.20+ features
; 0.5.00.00/2014-08-13/just me - changed 'static mode' handling
; 0.4.01.00/2013-12-30/just me - minor bug fix
; 0.4.00.00/2013-12-30/just me - added static mode
; 0.3.00.00/2013-06-15/just me - added "Critical, 100" to avoid drawing issues
; 0.2.00.00/2013-01-12/just me - bugfixes and minor changes
; 0.1.00.00/2012-10-27/just me - initial release
; ======================================================================================================================
; CLASS LV_Colors
;
; The class provides six public methods to set individual colors for rows and/or cells, to clear all colors, to
; prevent/allow sorting and rezising of columns dynamically, and to deactivate/activate the message handler for
; WM_NOTIFY messages (see below).
;
; The message handler for WM_NOTIFY messages will be activated for the specified ListView whenever a new instance is
; created. If you want to temporarily disable coloring call MyInstance.OnMessage(False). This must be done also before
; you try to destroy the instance. To enable it again, call MyInstance.OnMessage().
;
; To avoid the loss of Gui events and messages the message handler might need to be set 'critical'. This can be
; achieved by setting the instance property 'Critical' ti the required value (e.g. MyInstance.Critical := 100).
; New instances default to 'Critical, Off'. Though sometimes needed, ListViews or the whole Gui may become
; unresponsive under certain circumstances if Critical is set and the ListView has a g-label.
; ======================================================================================================================
Class LV_Colors {
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; META FUNCTIONS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ===================================================================================================================
; __New() Create a new LV_Colors instance for the given ListView
; Parameters: HWND - ListView's HWND.
; Optional ------------------------------------------------------------------------------------------
; StaticMode - Static color assignment, i.e. the colors will be assigned permanently to the row
; contents rather than to the row number.
; Values: True/False
; Default: False
; NoSort - Prevent sorting by click on a header item.
; Values: True/False
; Default: True
; NoSizing - Prevent resizing of columns.
; Values: True/False
; Default: True
; ===================================================================================================================
__New(HWND, StaticMode := False, NoSort := True, NoSizing := True) {
If (This.Base.Base.__Class) ; do not instantiate instances
Return False
If This.Attached[HWND] ; HWND is already attached
Return False
If !DllCall("IsWindow", "Ptr", HWND) ; invalid HWND
Return False
VarSetCapacity(Class, 512, 0)
DllCall("GetClassName", "Ptr", HWND, "Str", Class, "Int", 256)
If (Class <> "SysListView32") ; HWND doesn't belong to a ListView
Return False
; ----------------------------------------------------------------------------------------------------------------
; Set LVS_EX_DOUBLEBUFFER (0x010000) style to avoid drawing issues.
SendMessage, 0x1036, 0x010000, 0x010000, , % "ahk_id " . HWND ; LVM_SETEXTENDEDLISTVIEWSTYLE
; Get the default colors
SendMessage, 0x1025, 0, 0, , % "ahk_id " . HWND ; LVM_GETTEXTBKCOLOR
This.BkClr := ErrorLevel
SendMessage, 0x1023, 0, 0, , % "ahk_id " . HWND ; LVM_GETTEXTCOLOR
This.TxClr := ErrorLevel
; Get the header control
SendMessage, 0x101F, 0, 0, , % "ahk_id " . HWND ; LVM_GETHEADER
This.Header := ErrorLevel
; Set other properties
This.HWND := HWND
This.IsStatic := !!StaticMode
This.AltCols := False
This.AltRows := False
This.NoSort(!!NoSort)
This.NoSizing(!!NoSizing)
This.OnMessage()
This.Critical := "Off"
This.Attached[HWND] := True
}
; ===================================================================================================================
__Delete() {
This.Attached.Remove(HWND, "")
This.OnMessage(False)
WinSet, Redraw, , % "ahk_id " . This.HWND
}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PUBLIC METHODS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ===================================================================================================================
; Clear() Clears all row and cell colors.
; Parameters: AltRows - Reset alternate row coloring (True / False)
; Default: False
; AltCols - Reset alternate column coloring (True / False)
; Default: False
; Return Value: Always True.
; ===================================================================================================================
Clear(AltRows := False, AltCols := False) {
If (AltCols)
This.AltCols := False
If (AltRows)
This.AltRows := False
This.Remove("Rows")
This.Remove("Cells")
Return True
}
; ===================================================================================================================
; AlternateRows() Sets background and/or text color for even row numbers.
; Parameters: BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
AlternateRows(BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
This.AltRows := False
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["ARB"] := (BkBGR <> "") ? BkBGR : This.BkClr
This["ART"] := (TxBGR <> "") ? TxBGR : This.TxClr
This.AltRows := True
Return True
}
; ===================================================================================================================
; AlternateCols() Sets background and/or text color for even column numbers.
; Parameters: BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
AlternateCols(BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
This.AltCols := False
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["ACB"] := (BkBGR <> "") ? BkBGR : This.BkClr
This["ACT"] := (TxBGR <> "") ? TxBGR : This.TxClr
This.AltCols := True
Return True
}
; ===================================================================================================================
; SelectionColors() Sets background and/or text color for selected rows.
; Parameters: BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default selected background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default selected text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
SelectionColors(BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
This.SelColors := False
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["SELB"] := BkBGR
This["SELT"] := TxBGR
This.SelColors := True
Return True
}
; ===================================================================================================================
; Row() Sets background and/or text color for the specified row.
; Parameters: Row - Row number
; Optional ------------------------------------------------------------------------------------------
; BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> default text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
Row(Row, BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
If This.IsStatic
Row := This.MapIndexToID(Row)
This["Rows"].Remove(Row, "")
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
This["Rows", Row, "B"] := (BkBGR <> "") ? BkBGR : This.BkClr
This["Rows", Row, "T"] := (TxBGR <> "") ? TxBGR : This.TxClr
Return True
}
; ===================================================================================================================
; Cell() Sets background and/or text color for the specified cell.
; Parameters: Row - Row number
; Col - Column number
; Optional ------------------------------------------------------------------------------------------
; BkColor - Background color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> row's background color
; TxColor - Text color as RGB color integer (e.g. 0xFF0000 = red) or HTML color name.
; Default: Empty -> row's text color
; Return Value: True on success, otherwise false.
; ===================================================================================================================
Cell(Row, Col, BkColor := "", TxColor := "") {
If !(This.HWND)
Return False
If This.IsStatic
Row := This.MapIndexToID(Row)
This["Cells", Row].Remove(Col, "")
If (BkColor = "") && (TxColor = "")
Return True
BkBGR := This.BGR(BkColor)
TxBGR := This.BGR(TxColor)
If (BkBGR = "") && (TxBGR = "")
Return False
If (BkBGR <> "")
This["Cells", Row, Col, "B"] := BkBGR
If (TxBGR <> "")
This["Cells", Row, Col, "T"] := TxBGR
Return True
}
; ===================================================================================================================
; NoSort() Prevents/allows sorting by click on a header item for this ListView.
; Parameters: Apply - True/False
; Default: True
; Return Value: True on success, otherwise false.
; ===================================================================================================================
NoSort(Apply := True) {
If !(This.HWND)
Return False
If (Apply)
This.SortColumns := False
Else
This.SortColumns := True
Return True
}
; ===================================================================================================================
; NoSizing() Prevents/allows resizing of columns for this ListView.
; Parameters: Apply - True/False
; Default: True
; Return Value: True on success, otherwise false.
; ===================================================================================================================
NoSizing(Apply := True) {
Static OSVersion := DllCall("GetVersion", "UChar")
If !(This.Header)
Return False
If (Apply) {
If (OSVersion > 5)
Control, Style, +0x0800, , % "ahk_id " . This.Header ; HDS_NOSIZING = 0x0800
This.ResizeColumns := False
}
Else {
If (OSVersion > 5)
Control, Style, -0x0800, , % "ahk_id " . This.Header ; HDS_NOSIZING
This.ResizeColumns := True
}
Return True
}
; ===================================================================================================================
; OnMessage() Adds/removes a message handler for WM_NOTIFY messages for this ListView.
; Parameters: Apply - True/False
; Default: True
; Return Value: Always True
; ===================================================================================================================
OnMessage(Apply := True) {
If (Apply) && !This.HasKey("OnMessageFunc") {
This.OnMessageFunc := ObjBindMethod(This, "On_WM_Notify")
OnMessage(0x004E, This.OnMessageFunc) ; add the WM_NOTIFY message handler
}
Else If !(Apply) && This.HasKey("OnMessageFunc") {
OnMessage(0x004E, This.OnMessageFunc, 0) ; remove the WM_NOTIFY message handler
This.OnMessageFunc := ""
This.Remove("OnMessageFunc")
}
WinSet, Redraw, , % "ahk_id " . This.HWND
Return True
}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE PROPERTIES +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Static Attached := {}
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PRIVATE METHODS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
On_WM_NOTIFY(W, L, M, H) {
; Notifications: NM_CUSTOMDRAW = -12, LVN_COLUMNCLICK = -108, HDN_BEGINTRACKA = -306, HDN_BEGINTRACKW = -326
Critical, % This.Critical
If ((HCTL := NumGet(L + 0, 0, "UPtr")) = This.HWND) || (HCTL = This.Header) {
Code := NumGet(L + (A_PtrSize * 2), 0, "Int")
If (Code = -12)
Return This.NM_CUSTOMDRAW(This.HWND, L)
If !This.SortColumns && (Code = -108)
Return 0
If !This.ResizeColumns && ((Code = -306) || (Code = -326))
Return True
}
}
; -------------------------------------------------------------------------------------------------------------------
NM_CUSTOMDRAW(H, L) {
; Return values: 0x00 (CDRF_DODEFAULT), 0x20 (CDRF_NOTIFYITEMDRAW / CDRF_NOTIFYSUBITEMDRAW)
Static SizeNMHDR := A_PtrSize * 3 ; Size of NMHDR structure
Static SizeNCD := SizeNMHDR + 16 + (A_PtrSize * 5) ; Size of NMCUSTOMDRAW structure
Static OffItem := SizeNMHDR + 16 + (A_PtrSize * 2) ; Offset of dwItemSpec (NMCUSTOMDRAW)
Static OffItemState := OffItem + A_PtrSize ; Offset of uItemState (NMCUSTOMDRAW)
Static OffCT := SizeNCD ; Offset of clrText (NMLVCUSTOMDRAW)
Static OffCB := OffCT + 4 ; Offset of clrTextBk (NMLVCUSTOMDRAW)
Static OffSubItem := OffCB + 4 ; Offset of iSubItem (NMLVCUSTOMDRAW)
; ----------------------------------------------------------------------------------------------------------------
DrawStage := NumGet(L + SizeNMHDR, 0, "UInt")
, Row := NumGet(L + OffItem, "UPtr") + 1
, Col := NumGet(L + OffSubItem, "Int") + 1
, Item := Row - 1
If This.IsStatic
Row := This.MapIndexToID(Row)
; CDDS_SUBITEMPREPAINT = 0x030001 --------------------------------------------------------------------------------
If (DrawStage = 0x030001) {
UseAltCol := !(Col & 1) && (This.AltCols)
, ColColors := This["Cells", Row, Col]
, ColB := (ColColors.B <> "") ? ColColors.B : UseAltCol ? This.ACB : This.RowB
, ColT := (ColColors.T <> "") ? ColColors.T : UseAltCol ? This.ACT : This.RowT
, NumPut(ColT, L + OffCT, "UInt"), NumPut(ColB, L + OffCB, "UInt")
Return (!This.AltCols && !This.HasKey(Row) && (Col > This["Cells", Row].MaxIndex())) ? 0x00 : 0x20
}
; CDDS_ITEMPREPAINT = 0x010001 -----------------------------------------------------------------------------------
If (DrawStage = 0x010001) {
; LVM_GETITEMSTATE = 0x102C, LVIS_SELECTED = 0x0002
If (This.SelColors) && DllCall("SendMessage", "Ptr", H, "UInt", 0x102C, "Ptr", Item, "Ptr", 0x0002, "UInt") {
; Remove the CDIS_SELECTED (0x0001) and CDIS_FOCUS (0x0010) states from uItemState and set the colors.
NumPut(NumGet(L + OffItemState, "UInt") & ~0x0011, L + OffItemState, "UInt")
If (This.SELB <> "")
NumPut(This.SELB, L + OffCB, "UInt")
If (This.SELT <> "")
NumPut(This.SELT, L + OffCT, "UInt")
Return 0x02 ; CDRF_NEWFONT
}
UseAltRow := (Item & 1) && (This.AltRows)
, RowColors := This["Rows", Row]
, This.RowB := RowColors ? RowColors.B : UseAltRow ? This.ARB : This.BkClr
, This.RowT := RowColors ? RowColors.T : UseAltRow ? This.ART : This.TxClr
If (This.AltCols || This["Cells"].HasKey(Row))
Return 0x20
NumPut(This.RowT, L + OffCT, "UInt"), NumPut(This.RowB, L + OffCB, "UInt")
Return 0x00
}
; CDDS_PREPAINT = 0x000001 ---------------------------------------------------------------------------------------
Return (DrawStage = 0x000001) ? 0x20 : 0x00
}
; -------------------------------------------------------------------------------------------------------------------
MapIndexToID(Row) { ; provides the unique internal ID of the given row number
SendMessage, 0x10B4, % (Row - 1), 0, , % "ahk_id " . This.HWND ; LVM_MAPINDEXTOID
Return ErrorLevel
}
; -------------------------------------------------------------------------------------------------------------------
BGR(Color, Default := "") { ; converts colors to BGR
Static Integer := "Integer" ; v2
; HTML Colors (BGR)
Static HTML := {AQUA: 0xFFFF00, BLACK: 0x000000, BLUE: 0xFF0000, FUCHSIA: 0xFF00FF, GRAY: 0x808080, GREEN: 0x008000
, LIME: 0x00FF00, MAROON: 0x000080, NAVY: 0x800000, OLIVE: 0x008080, PURPLE: 0x800080, RED: 0x0000FF
, SILVER: 0xC0C0C0, TEAL: 0x808000, WHITE: 0xFFFFFF, YELLOW: 0x00FFFF}
If Color Is Integer
Return ((Color >> 16) & 0xFF) | (Color & 0x00FF00) | ((Color & 0xFF) << 16)
Return (HTML.HasKey(Color) ? HTML[color] : Default)
}
}